From ba26f296f9ddc694fc42683132bc328dffd777ec Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 7 Dec 2007 22:08:59 +0100 Subject: Windows: Implement start_command(). On Windows, we have spawnv() variants to run a child process instead of fork()/exec(). In order to attach pipe ends to stdin, stdout, and stderr, we have to use this idiom: save1 = dup(1); dup2(pipe[1], 1); spawnv(); dup2(save1, 1); close(pipe[1]); assuming that the descriptors created by pipe() are not inheritable. Signed-off-by: Johannes Sixt --- compat/mingw.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ compat/mingw.h | 8 ++++++++ 2 files changed, 70 insertions(+) (limited to 'compat') diff --git a/compat/mingw.c b/compat/mingw.c index 31a9b9e25..7f89a6cb8 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -315,6 +315,68 @@ void mingw_execvp(const char *cmd, char *const *argv) free_path_split(path); } +char **copy_environ() +{ + char **env; + int i = 0; + while (environ[i]) + i++; + env = xmalloc((i+1)*sizeof(*env)); + for (i = 0; environ[i]; i++) + env[i] = xstrdup(environ[i]); + env[i] = NULL; + return env; +} + +void free_environ(char **env) +{ + int i; + for (i = 0; env[i]; i++) + free(env[i]); + free(env); +} + +static int lookup_env(char **env, const char *name, size_t nmln) +{ + int i; + + for (i = 0; env[i]; i++) { + if (0 == strncmp(env[i], name, nmln) + && '=' == env[i][nmln]) + /* matches */ + return i; + } + return -1; +} + +/* + * If name contains '=', then sets the variable, otherwise it unsets it + */ +char **env_setenv(char **env, const char *name) +{ + char *eq = strchrnul(name, '='); + int i = lookup_env(env, name, eq-name); + + if (i < 0) { + if (*eq) { + for (i = 0; env[i]; i++) + ; + env = xrealloc(env, (i+2)*sizeof(*env)); + env[i] = xstrdup(name); + env[i+1] = NULL; + } + } + else { + free(env[i]); + if (*eq) + env[i] = xstrdup(name); + else + for (; env[i]; i++) + env[i] = env[i+1]; + } + return env; +} + #undef rename int mingw_rename(const char *pold, const char *pnew) { diff --git a/compat/mingw.h b/compat/mingw.h index 0ce9c96f9..0879894c6 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -165,3 +165,11 @@ sig_handler_t mingw_signal(int sig, sig_handler_t handler); #define is_dir_sep(c) ((c) == '/' || (c) == '\\') #define PATH_SEP ';' #define PRIuMAX "I64u" + +/* + * helpers + */ + +char **copy_environ(void); +void free_environ(char **env); +char **env_setenv(char **env, const char *name); -- cgit v1.2.1