#include "gnunet_common.h"
#include "gnunet_os_lib.h"
#include "gnunet_scheduler_lib.h"
+#include "gnunet_strings_lib.h"
#include "disk.h"
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
* @param proc pointer to process structure
*/
static DWORD_WINAPI
-ChildWaitThread (void *arg)
+child_wait_thread (void *arg)
{
struct GNUNET_OS_Process *proc = (struct GNUNET_OS_Process *) arg;
* @param pipe_stdin pipe to use to send input to child process (or NULL)
* @param pipe_stdout pipe to use to get output from child process (or NULL)
* @param filename name of the binary
- * @param va NULL-terminated list of arguments to the process
+ * @param argv NULL-terminated array of arguments to the process
* @return pointer to process structure of the new process, NULL on error
*/
struct GNUNET_OS_Process *
-GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
- struct GNUNET_DISK_PipeHandle *pipe_stdout,
- const char *filename, va_list va)
+GNUNET_OS_start_process_vap (struct GNUNET_DISK_PipeHandle *pipe_stdin,
+ struct GNUNET_DISK_PipeHandle *pipe_stdout,
+ const char *filename,
+ char *const argv[])
{
- va_list ap;
-
#if ENABLE_WINDOWS_WORKAROUNDS
char *childpipename = NULL;
struct GNUNET_DISK_FileHandle *control_pipe = NULL;
#ifndef MINGW
pid_t ret;
- char **argv;
- int argc;
int fd_stdout_write;
int fd_stdout_read;
int fd_stdin_read;
if (control_pipe == NULL)
return NULL;
#endif
-
- argc = 0;
- va_copy (ap, va);
- while (NULL != va_arg (ap, char *))
- argc++;
-
- va_end (ap);
- argv = GNUNET_malloc (sizeof (char *) * (argc + 1));
- argc = 0;
- va_copy (ap, va);
- while (NULL != (argv[argc] = va_arg (ap, char *)))
- argc++;
-
- va_end (ap);
if (pipe_stdout != NULL)
{
GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
gnunet_proc->control_pipe = control_pipe;
#endif
}
- GNUNET_free (argv);
#if ENABLE_WINDOWS_WORKAROUNDS
GNUNET_free (childpipename);
#endif
char *arg;
unsigned int cmdlen;
char *cmd, *idx;
- STARTUPINFO start;
+ STARTUPINFOW start;
PROCESS_INFORMATION proc;
-
+ int argc;
HANDLE stdin_handle;
HANDLE stdout_handle;
char *libdir;
char *ptr;
char *non_const_filename;
+ wchar_t wpath[MAX_PATH + 1], wcmd[32768];
/* Search in prefix dir (hopefully - the directory from which
* the current module was loaded), bindir and libdir, then in PATH
GNUNET_free (non_const_filename);
cmdlen = 0;
- va_copy (ap, va);
- while (NULL != (arg = va_arg (ap, char *)))
+ argc = 0;
+ while (NULL != (arg = argv[argc++]))
{
if (cmdlen == 0)
cmdlen = cmdlen + strlen (path) + 3;
else
cmdlen = cmdlen + strlen (arg) + 3;
}
- va_end (ap);
cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1));
- va_copy (ap, va);
- while (NULL != (arg = va_arg (ap, char *)))
+ argc = 0;
+ while (NULL != (arg = argv[argc++]))
{
if (idx == cmd)
idx += sprintf (idx, "\"%s\" ", path);
else
idx += sprintf (idx, "\"%s\" ", arg);
}
- va_end (ap);
memset (&start, 0, sizeof (start));
start.cb = sizeof (start);
GNUNET_free (our_env[0]);
GNUNET_free (our_env[1]);
- if (!CreateProcessA
- (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
+ if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath)
+ || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd)
+ || !CreateProcessW
+ (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
env_block, NULL, &start, &proc))
{
SetErrnoFromWinError (GetLastError ());
gnunet_proc->handle = proc.hProcess;
gnunet_proc->control_pipe = control_pipe;
- CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL);
+ CreateThread (NULL, 64000, &child_wait_thread, (void *) gnunet_proc, 0, NULL);
ResumeThread (proc.hThread);
CloseHandle (proc.hThread);
}
+/**
+ * Start a process.
+ *
+ * @param pipe_stdin pipe to use to send input to child process (or NULL)
+ * @param pipe_stdout pipe to use to get output from child process (or NULL)
+ * @param filename name of the binary
+ * @param va NULL-terminated list of arguments to the process
+ * @return pointer to process structure of the new process, NULL on error
+ */
+struct GNUNET_OS_Process *
+GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin,
+ struct GNUNET_DISK_PipeHandle *pipe_stdout,
+ const char *filename, va_list va)
+{
+ struct GNUNET_OS_Process *ret;
+ va_list ap;
+ char **argv;
+ int argc;
+
+ argc = 0;
+ va_copy (ap, va);
+ while (NULL != va_arg (ap, char *))
+ argc++;
+ va_end (ap);
+ argv = GNUNET_malloc (sizeof (char *) * (argc + 1));
+ argc = 0;
+ va_copy (ap, va);
+ while (NULL != (argv[argc] = va_arg (ap, char *)))
+ argc++;
+ va_end (ap);
+ ret = GNUNET_OS_start_process_vap (pipe_stdin,
+ pipe_stdout,
+ filename,
+ argv);
+ GNUNET_free (argv);
+ return ret;
+}
+
+
+
/**
* Start a process.
*
char **arg, **non_const_argv;
unsigned int cmdlen;
char *cmd, *idx;
- STARTUPINFO start;
+ STARTUPINFOW start;
PROCESS_INFORMATION proc;
int argcount = 0;
struct GNUNET_OS_Process *gnunet_proc = NULL;
const struct GNUNET_DISK_FileHandle *lsocks_write_fd;
HANDLE lsocks_read;
HANDLE lsocks_write;
+ wchar_t wpath[MAX_PATH + 1], wcmd[32768];
int fail;
GNUNET_free (path);
return NULL;
}
- if (lsocks != NULL)
+ if (lsocks != NULL && lsocks[0] != INVALID_SOCKET)
{
- lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
+ lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
if (lsocks_pipe == NULL)
{
GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE);
GNUNET_asprintf (&our_env[1], "%s", childpipename);
GNUNET_free (childpipename);
- if (lsocks == NULL)
+ if (lsocks == NULL || lsocks[0] == INVALID_SOCKET)
our_env[2] = NULL;
else
{
GNUNET_free_non_null (our_env[2]);
GNUNET_free_non_null (our_env[3]);
- if (!CreateProcessA
- (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
+ if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath)
+ || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd)
+ || !CreateProcessW
+ (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED,
env_block, NULL, &start, &proc))
{
SetErrnoFromWinError (GetLastError ());
gnunet_proc->handle = proc.hProcess;
gnunet_proc->control_pipe = control_pipe;
- CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL);
+ CreateThread (NULL, 64000, &child_wait_thread, (void *) gnunet_proc, 0, NULL);
ResumeThread (proc.hThread);
CloseHandle (proc.hThread);
GNUNET_free (cmd);
- if (lsocks == NULL)
+ if (lsocks == NULL || lsocks[0] == INVALID_SOCKET)
return gnunet_proc;
GNUNET_DISK_pipe_close_end (lsocks_pipe, GNUNET_DISK_PIPE_END_READ);
#ifndef MINGW
pid_t pid = proc->pid;
+ pid_t ret;
- if (pid != waitpid (pid, NULL, 0))
+ while ( (pid != (ret = waitpid (pid, NULL, 0))) &&
+ (EINTR == errno) ) ;
+ if (pid != ret)
+ {
+ LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid");
return GNUNET_SYSERR;
+ }
return GNUNET_OK;
#else
HANDLE h;
struct GNUNET_DISK_PipeHandle *opipe;
va_list ap;
- opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
+ opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
if (NULL == opipe)
return NULL;
va_start (ap, binary);