X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=eglib%2Fsrc%2Fgspawn.c;h=01639be101fb1d18e57f6dc74b94c7630bf30aed;hb=bcefc710782c9e95d3e9bcad58d4bcf1a944150d;hp=8a0c03d0977a2731900a06bc78ac8b5cc64a0eec;hpb=bd0d82edd83a46371125a2cf63c399446df8a472;p=mono.git diff --git a/eglib/src/gspawn.c b/eglib/src/gspawn.c index 8a0c03d0977..01639be101f 100644 --- a/eglib/src/gspawn.c +++ b/eglib/src/gspawn.c @@ -35,10 +35,16 @@ #include #ifdef HAVE_UNISTD_H +#ifndef __USE_GNU #define __USE_GNU +#endif #include #endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif + #ifdef HAVE_SYS_TIME_H #include #endif @@ -47,6 +53,10 @@ #include #endif +#ifdef HAVE_SYS_RESOURCE_H +# include +#endif + #ifdef G_OS_WIN32 #include #include @@ -64,19 +74,25 @@ #define NO_INTR(var,cmd) do { (var) = (cmd); } while ((var) == -1 && errno == EINTR) #define CLOSE_PIPE(p) do { close (p [0]); close (p [1]); } while (0) -#ifdef __APPLE__ +#if defined(__APPLE__) +#if defined (TARGET_OSX) /* Apple defines this in crt_externs.h but doesn't provide that header for * arm-apple-darwin9. We'll manually define the symbol on Apple as it does * in fact exist on all implementations (so far) */ -gchar ***_NSGetEnviron(); +gchar ***_NSGetEnviron(void); #define environ (*_NSGetEnviron()) +#else +static char *mono_environ[1] = { NULL }; +#define environ mono_environ +#endif /* defined (TARGET_OSX) */ #elif defined(_MSC_VER) /* MS defines this in stdlib.h */ #else extern char **environ; #endif +#ifndef G_OS_WIN32 static int safe_read (int fd, gchar *buffer, gint count, GError **error) { @@ -183,6 +199,51 @@ create_pipe (int *fds, GError **error) } return TRUE; } +#endif /* G_OS_WIN32 */ + +static int +write_all (int fd, const void *vbuf, size_t n) +{ + const char *buf = (const char *) vbuf; + size_t nwritten = 0; + int w; + + do { + do { + w = write (fd, buf + nwritten, n - nwritten); + } while (w == -1 && errno == EINTR); + + if (w == -1) + return -1; + + nwritten += w; + } while (nwritten < n); + + return nwritten; +} + +#ifndef G_OS_WIN32 +int +eg_getdtablesize (void) +{ +#ifdef HAVE_GETRLIMIT + struct rlimit limit; + int res; + + res = getrlimit (RLIMIT_NOFILE, &limit); + g_assert (res == 0); + return limit.rlim_cur; +#else + return getdtablesize (); +#endif +} +#else +int +eg_getdtablesize (void) +{ + g_error ("Should not be called"); +} +#endif gboolean g_spawn_command_line_sync (const gchar *command_line, @@ -192,6 +253,9 @@ g_spawn_command_line_sync (const gchar *command_line, GError **error) { #ifdef G_OS_WIN32 +#elif !defined (HAVE_FORK) || !defined (HAVE_EXECV) + fprintf (stderr, "g_spawn_command_line_sync not supported on this platform\n"); + return FALSE; #else pid_t pid; gchar **argv; @@ -227,7 +291,7 @@ g_spawn_command_line_sync (const gchar *command_line, close (stderr_pipe [0]); dup2 (stderr_pipe [1], STDERR_FILENO); } - for (i = getdtablesize () - 1; i >= 3; i--) + for (i = eg_getdtablesize () - 1; i >= 3; i--) close (i); /* G_SPAWN_SEARCH_PATH is always enabled for g_spawn_command_line_sync */ @@ -288,6 +352,9 @@ g_spawn_async_with_pipes (const gchar *working_directory, GError **error) { #ifdef G_OS_WIN32 +#elif !defined (HAVE_FORK) || !defined (HAVE_EXECVE) + fprintf (stderr, "g_spawn_async_with_pipes is not supported on this platform\n"); + return FALSE; #else pid_t pid; int info_pipe [2]; @@ -357,12 +424,12 @@ g_spawn_async_with_pipes (const gchar *working_directory, if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) { pid = getpid (); - NO_INTR (unused, write (info_pipe [1], &pid, sizeof (pid_t))); + NO_INTR (unused, write_all (info_pipe [1], &pid, sizeof (pid_t))); } if (working_directory && chdir (working_directory) == -1) { int err = errno; - NO_INTR (unused, write (info_pipe [1], &err, sizeof (int))); + NO_INTR (unused, write_all (info_pipe [1], &err, sizeof (int))); exit (0); } @@ -381,14 +448,14 @@ g_spawn_async_with_pipes (const gchar *working_directory, } if (standard_input) { - dup2 (in_pipe [0], STDERR_FILENO); + dup2 (in_pipe [0], STDIN_FILENO); } else if ((flags & G_SPAWN_CHILD_INHERITS_STDIN) == 0) { fd = open ("/dev/null", O_RDONLY); - dup2 (fd, STDERR_FILENO); + dup2 (fd, STDIN_FILENO); } if ((flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN) != 0) { - for (i = getdtablesize () - 1; i >= 3; i--) + for (i = eg_getdtablesize () - 1; i >= 3; i--) close (i); } @@ -404,13 +471,13 @@ g_spawn_async_with_pipes (const gchar *working_directory, arg0 = g_find_program_in_path (argv [0]); if (arg0 == NULL) { int err = ENOENT; - write (info_pipe [1], &err, sizeof (int)); + write_all (info_pipe [1], &err, sizeof (int)); exit (0); } } execve (arg0, actual_args, envp); - write (info_pipe [1], &errno, sizeof (int)); + write_all (info_pipe [1], &errno, sizeof (int)); exit (0); } } else if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) {