- SetErrnoFromWinError (lRet);
- LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "plibc_conv_to_win_path",
- non_const_filename);
- GNUNET_free (non_const_filename);
- GNUNET_free (pathbuf);
- return NULL;
- }
- GNUNET_free (non_const_filename);
- non_const_filename = GNUNET_strdup (win_path);
- /* Check that this is the full path. If it isn't, search. */
- /* FIXME: convert it to wchar_t and use SearchPathW?
- * Remember: arguments to _start_process() are technically in UTF-8...
- */
- if (non_const_filename[1] == ':')
- snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename);
- else if (!SearchPathA
- (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char),
- path, NULL))
- {
- SetErrnoFromWinError (GetLastError ());
- LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "SearchPath",
- non_const_filename);
- GNUNET_free (non_const_filename);
- GNUNET_free (pathbuf);
- return NULL;
- }
- GNUNET_free (pathbuf);
- GNUNET_free (non_const_filename);
-
- cmdlen = 0;
- argc = 0;
- while (NULL != (arg = argv[argc++]))
- {
- if (cmdlen == 0)
- cmdlen = cmdlen + strlen (path) + 4;
- else
- cmdlen = cmdlen + strlen (arg) + 4;
- }
- arg_count = argc;
-
- cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1));
- argc = 0;
- while (NULL != (arg = argv[argc++]))
- {
- /* This is to escape trailing slash */
- char arg_lastchar = arg[strlen (arg) - 1];
- if (idx == cmd)
- idx += sprintf (idx, "\"%s%s\"%s", path,
- arg_lastchar == '\\' ? "\\" : "", argc + 1 == arg_count ? "" : " ");
- else
- idx += sprintf (idx, "\"%s%s\"%s", arg,
- arg_lastchar == '\\' ? "\\" : "", argc + 1 == arg_count ? "" : " ");
- }
-
- memset (&start, 0, sizeof (start));
- start.cb = sizeof (start);
-
- if ((pipe_stdin != NULL) || (pipe_stdout != NULL))
- start.dwFlags |= STARTF_USESTDHANDLES;
-
- if (pipe_stdin != NULL)
- {
- GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
- (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
- &stdin_handle, sizeof (HANDLE));
- start.hStdInput = stdin_handle;
- }
-
- if (pipe_stdout != NULL)
- {
- GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
- (pipe_stdout,
- GNUNET_DISK_PIPE_END_WRITE),
- &stdout_handle, sizeof (HANDLE));
- start.hStdOutput = stdout_handle;
- }
- if (GNUNET_YES == pipe_control)
- {
- control_pipe =
- npipe_create (&childpipename, GNUNET_DISK_OPEN_WRITE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
- if (control_pipe == NULL)
- {
- GNUNET_free (cmd);
- GNUNET_free (path);
- return NULL;
- }
- }
- else
- control_pipe = NULL;
- if (NULL != childpipename)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n",
- childpipename);
- GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE);
- GNUNET_asprintf (&our_env[1], "%s", childpipename);
- our_env[2] = NULL;
- }
- else
- {
- our_env[0] = NULL;
- }
- env_block = CreateCustomEnvTable (our_env);
- GNUNET_free_non_null (our_env[0]);
- GNUNET_free_non_null (our_env[1]);
-
- wpath_len = 0;
- if (NULL == (wpath = u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len)))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", path, errno);
- GNUNET_free (env_block);
- GNUNET_free (cmd);
- return NULL;
- }
-
- wcmd_len = 0;
- if (NULL == (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len)))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", cmd, errno);
- GNUNET_free (env_block);
- GNUNET_free (cmd);
- free (wpath);
- return NULL;
- }
-
- if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE,
- DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc))
- {
- SetErrnoFromWinError (GetLastError ());
- LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path);
- GNUNET_free (env_block);
- GNUNET_free (cmd);
- free (wpath);
- free (wcmd);
- return NULL;
- }
-
- GNUNET_free (env_block);
-
- gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
- gnunet_proc->pid = proc.dwProcessId;
- gnunet_proc->handle = proc.hProcess;
- gnunet_proc->control_pipe = control_pipe;
-
- CreateThread (NULL, 64000, &child_wait_thread, (void *) gnunet_proc, 0, NULL);
-
- ResumeThread (proc.hThread);
- CloseHandle (proc.hThread);
-
- GNUNET_free (cmd);
- free (wpath);
- free (wcmd);
- return gnunet_proc;
-#endif
-}
-
-
-/**
- * Start a process.
- *
- * @param pipe_control should a pipe be used to send signals to the child?
- * @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 (int pipe_control,
- 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_control,
- pipe_stdin,
- pipe_stdout,
- filename,
- argv);
- GNUNET_free (argv);
- return ret;
-}
-
-
-
-/**
- * Start a process.
- *
- * @param pipe_control should a pipe be used to send signals to the child?
- * @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 ... 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 (int pipe_control,
- struct GNUNET_DISK_PipeHandle *pipe_stdin,
- struct GNUNET_DISK_PipeHandle *pipe_stdout,
- const char *filename, ...)
-{
- struct GNUNET_OS_Process *ret;
- va_list ap;
-
- va_start (ap, filename);
- ret = GNUNET_OS_start_process_va (pipe_control, pipe_stdin, pipe_stdout, filename, ap);
- va_end (ap);
- return ret;
-}
-
-
-/**
- * Start a process.
- *
- * @param pipe_control should a pipe be used to send signals to the child?
- * @param lsocks array of listen sockets to dup systemd-style (or NULL);
- * must be NULL on platforms where dup is not supported
- * @param filename name of the binary
- * @param argv NULL-terminated list of arguments to the process
- * @return process ID of the new process, -1 on error
- */
-struct GNUNET_OS_Process *
-GNUNET_OS_start_process_v (int pipe_control,
- const SOCKTYPE *lsocks,
- const char *filename,
- char *const argv[])
-{
-#ifndef MINGW
- pid_t ret;
- char lpid[16];
- char fds[16];
- struct GNUNET_OS_Process *gnunet_proc = NULL;
- char *childpipename = NULL;
- int i;
- int j;
- int k;
- int tgt;
- int flags;
- int *lscp;
- unsigned int ls;
-
- if ( (GNUNET_YES == pipe_control) &&
- (GNUNET_OK != npipe_setup (&childpipename)) )
- return NULL;
- lscp = NULL;
- ls = 0;
- if (lsocks != NULL)
- {
- i = 0;
- while (-1 != (k = lsocks[i++]))
- GNUNET_array_append (lscp, ls, k);
- GNUNET_array_append (lscp, ls, -1);
- }
- ret = fork ();
- if (-1 == ret)
- {
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
- GNUNET_free_non_null (childpipename);
- GNUNET_array_grow (lscp, ls, 0);
- return NULL;
- }
- if (0 != ret)
- {
- gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
- gnunet_proc->pid = ret;
- gnunet_proc->childpipename = childpipename;
- GNUNET_array_grow (lscp, ls, 0);
- return gnunet_proc;