#include <glib.h>
#ifdef HAVE_UNISTD_H
+#ifndef __USE_GNU
#define __USE_GNU
+#endif
#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)
-#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)
{
}
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,
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;
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 */
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];
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);
}
}
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);
}
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) {