[msvc] Update csproj files
[mono.git] / eglib / src / gspawn.c
index f55d5042123f1d00d1d2e8e61859049637086d1f..01639be101fb1d18e57f6dc74b94c7630bf30aed 100644 (file)
 #include <unistd.h>
 #endif
 
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
 #include <sys/wait.h>
 #endif
 
+#ifdef HAVE_SYS_RESOURCE_H
+#  include <sys/resource.h>
+#endif
+
 #ifdef G_OS_WIN32
 #include <io.h>
 #include <winsock2.h>
 #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)
 
-#if defined(__APPLE__) && !defined (__arm__)
+#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)
 {
@@ -185,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,
@@ -194,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;
@@ -229,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 */
@@ -290,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];
@@ -359,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);
                        }
 
@@ -390,7 +455,7 @@ g_spawn_async_with_pipes (const gchar *working_directory,
                        }
 
                        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);
                        }
 
@@ -406,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) {