pid_t
GNUNET_OS_start_process (const char *filename, ...)
{
+ va_list ap;
+
+#ifndef MINGW
pid_t ret;
char **argv;
- va_list ap;
int argc;
ret = fork ();
execvp (filename, argv);
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
exit (1);
+#else
+ char *arg;
+ unsigned int cmdlen;
+ char *cmd, *idx;
+ STARTUPINFO start;
+ PROCESS_INFORMATION proc;
+
+ cmdlen = 0;
+ va_start (ap, filename);
+ while (NULL != (arg = va_arg (ap, char *)))
+ cmdlen = cmdlen + strlen (arg) + 3;
+ va_end (ap);
+
+ cmd = idx = GNUNET_malloc (sizeof(char) * cmdlen);
+ va_start (ap, filename);
+ while (NULL != (arg = va_arg (ap, char *)))
+ idx += sprintf (idx, "\"%s\" ", arg);
+ va_end (ap);
+
+ memset (&start, 0, sizeof(start));
+ start.cb = sizeof(start);
+
+ if (!CreateProcess (filename, cmd, NULL, NULL, FALSE, DETACHED_PROCESS, NULL,
+ NULL, &start, &proc))
+ {
+ SetErrnoFromWinError (GetLastError ());
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+ return -1;
+ }
+ CloseHandle (proc.hProcess);
+ CloseHandle (proc.hThread);
+
+ GNUNET_free(cmd);
+
+ return proc.dwProcessId;
+#endif
}
pid_t
GNUNET_OS_start_process_v (const char *filename, char *const argv[])
{
+#ifndef MINGW
pid_t ret;
ret = fork ();
execvp (filename, argv);
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
exit (1);
+#else
+ char **arg;
+ unsigned int cmdlen;
+ char *cmd, *idx;
+ STARTUPINFO start;
+ PROCESS_INFORMATION proc;
+
+ cmdlen = 0;
+ arg = argv;
+ while (*arg)
+ {
+ cmdlen = cmdlen + strlen (*arg) + 3;
+ arg++;
+ }
+
+ cmd = idx = GNUNET_malloc (sizeof(char) * cmdlen);
+ arg = argv;
+ while (*arg)
+ {
+ idx += sprintf (idx, "\"%s\" ", *arg);
+ arg++;
+ }
+
+ memset (&start, 0, sizeof(start));
+ start.cb = sizeof(start);
+
+ if (!CreateProcess (filename, cmd, NULL, NULL, FALSE, DETACHED_PROCESS, NULL,
+ NULL, &start, &proc))
+ {
+ SetErrnoFromWinError (GetLastError ());
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+ return -1;
+ }
+ CloseHandle (proc.hProcess);
+ CloseHandle (proc.hThread);
+
+ GNUNET_free(cmd);
+
+ return proc.dwProcessId;
+#endif
}
+/**
+ * Retrieve the status of a process
+ * @param proc process ID
+ * @param type status type
+ * @param code return code/signal number
+ * @return GNUNET_OK on success, GNUNET_NO if the process is still running, GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_OS_process_status (pid_t proc, enum GNUNET_OS_ProcessStatusType *type,
+ unsigned long *code)
+{
+#ifndef MINGW
+ int status;
+ int ret;
+ GNUNET_assert (0 != proc);
+ ret = waitpid (proc, &status, WNOHANG);
+ if (0 == ret)
+ {
+ *type = GNUNET_OS_PROCESS_RUNNING;
+ *code = 0;
+ return GNUNET_NO;
+ }
+ if (proc != ret)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
+ return GNUNET_SYSERR;
+ }
+ if (WIFEXITED (status))
+ {
+ *type = GNUNET_OS_PROCESS_EXITED;
+ *code = WEXITSTATUS (status);
+ }
+ else if (WIFSIGNALED (status))
+ {
+ *type = GNUNET_OS_PROCESS_SIGNALED;
+ *code = WTERMSIG (status);
+ }
+ else if (WIFSTOPPED (status))
+ {
+ *type = GNUNET_OS_PROCESS_SIGNALED;
+ *code = WSTOPSIG (status);
+ }
+ else if (WIFCONTINUED (status))
+ {
+ *type = GNUNET_OS_PROCESS_RUNNING;
+ *code = 0;
+ }
+ else
+ {
+ *type = GNUNET_OS_PROCESS_UNKNOWN;
+ *code = 0;
+ }
+#else
+ HANDLE h;
+ DWORD c;
+
+ h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, proc);
+ if (INVALID_HANDLE_VALUE == h)
+ {
+ SetErrnoFromWinError (GetLastError ());
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "OpenProcess");
+ return GNUNET_SYSERR;
+ }
+
+ c = GetExitCodeProcess (proc, &c);
+ if (STILL_ACTIVE == c)
+ {
+ *type = GNUNET_OS_PROCESS_RUNNING;
+ *code = 0;
+ CloseHandle (h);
+ return GNUNET_NO;
+ }
+ *type = GNUNET_OS_PROCESS_EXITED;
+ *code = c;
+ CloseHandle (h);
+#endif
+
+ return GNUNET_OK;
+}
+/**
+ * Wait for a process
+ * @param proc process ID to wait for
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_OS_process_wait (pid_t proc)
+{
+#ifndef MINGW
+ if (proc != waitpid (proc, NULL, 0))
+ return GNUNET_SYSERR;
+
+ return GNUNET_OK;
+#else
+ HANDLE h;
+ DWORD c;
+ int ret;
+ h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, proc);
+ if (INVALID_HANDLE_VALUE == h)
+ {
+ SetErrnoFromWinError (GetLastError ());
+ return GNUNET_SYSERR;
+ }
+
+ if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE))
+ {
+ SetErrnoFromWinError (GetLastError ());
+ ret = GNUNET_SYSERR;
+ }
+ else
+ ret = GNUNET_OK;
+
+ CloseHandle (h);
+
+ return ret;
+#endif
+}
/* end of os_priority.c */