33#if defined (HAVE_CONFIG_H)
42#if defined (__WIN32__) && ! defined (__CYGWIN__)
45# define WIN32_LEAN_AND_MEAN 1
52# include <sys/types.h>
58#if defined (__WIN32__) && ! defined (__CYGWIN__)
61make_command_string (
const char *cmd,
char *
const *args)
69 cmd_len =
strlen (cmd) + 3;
75 cmd_len +=
strlen (*argp) + 3;
77 command = (
char *)
malloc (cmd_len);
80 sprintf (command,
"\"%s\"", cmd);
83 cmd_len =
strlen (cmd) + 2;
87 command[cmd_len++] =
' ';
88 command[cmd_len++] =
'"';
90 memcpy (command + cmd_len, *argp, arg_len);
92 command[cmd_len++] =
'"';
100octave_popen2 (
const char *cmd,
char *
const *args,
bool sync_mode,
101 int *fildes,
const char **errmsg)
108 PROCESS_INFORMATION pi;
111 HANDLE hProcess = GetCurrentProcess ();
112 HANDLE childRead, childWrite, parentRead, parentWrite;
115 ZeroMemory (&pi,
sizeof (pi));
116 ZeroMemory (&si,
sizeof (si));
119 if (! CreatePipe (&childRead, &parentWrite, 0, 0)
120 || ! DuplicateHandle (hProcess, childRead, hProcess, &childRead,
122 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
124 *errmsg =
"popen2: pipe creation failed";
128 if (! CreatePipe (&parentRead, &childWrite, 0, 0)
129 || ! DuplicateHandle (hProcess, childWrite, hProcess, &childWrite,
131 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
133 *errmsg =
"popen2: pipe creation failed";
139 pipeMode = PIPE_NOWAIT;
140 SetNamedPipeHandleState (parentRead, &pipeMode, 0, 0);
143 fildes[1] = _open_osfhandle ((intptr_t) parentRead, _O_RDONLY | _O_BINARY);
144 fildes[0] = _open_osfhandle ((intptr_t) parentWrite, _O_WRONLY | _O_BINARY);
146 si.dwFlags |= STARTF_USESTDHANDLES;
148 si.hStdInput = childRead;
149 si.hStdOutput = childWrite;
150 si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
152 command = make_command_string (cmd, args);
158 status = CreateProcessW (NULL, wcmd, NULL, NULL, TRUE, CREATE_NO_WINDOW,
159 NULL, NULL, &si, &pi);
165 *errmsg =
"popen2: process creation failed";
169 pid = pi.dwProcessId;
171 CloseHandle (childRead);
172 CloseHandle (childWrite);
174 CloseHandle (pi.hProcess);
175 CloseHandle (pi.hThread);
184 int *fildes,
const char **errmsg)
188 int child_stdin[2], child_stdout[2];
190 if (
pipe (child_stdin) < 0)
192 *errmsg = strerror (errno);
196 if (
pipe (child_stdout) < 0)
198 close (child_stdin[0]);
199 close (child_stdin[1]);
201 *errmsg = strerror (errno);
211 close (child_stdin[1]);
212 close (child_stdout[0]);
216 close (child_stdin[0]);
218 if (
dup2 (child_stdout[1], STDOUT_FILENO) >= 0)
220 close (child_stdout[1]);
222 if (
execvp (cmd, args) < 0)
223 perror (
"popen2 (child)");
226 perror (
"popen2 (child)");
229 perror (
"popen2 (child)");
237 close (child_stdin[0]);
238 close (child_stdout[1]);
240#if defined (F_SETFL) && defined (O_NONBLOCK)
241 if (! sync_mode &&
fcntl (child_stdout[0], F_SETFL, O_NONBLOCK) < 0)
243 *errmsg = strerror (errno);
249 fildes[0] = child_stdin[1];
250 fildes[1] = child_stdout[0];
257 *errmsg = strerror (errno);
T::size_type strlen(const typename T::value_type *str)
pid_t fork(std::string &msg)
int execvp(const std::string &file, const string_vector &argv)
int fcntl(int fd, int cmd, long arg)
int dup2(int old_fd, int new_fd)
pid_t octave_popen2(const char *cmd, char *const *args, bool sync_mode, int *fildes, const char **errmsg)
wchar_t * u8_to_wchar(const char *u8)