33#if defined (HAVE_CONFIG_H)
42#if defined (__WIN32__) && ! defined (__CYGWIN__)
45# define WIN32_LEAN_AND_MEAN 1
52# include <sys/types.h>
59#if defined (__WIN32__) && ! defined (__CYGWIN__)
62make_command_string (
const char *cmd,
char *
const *args)
70 cmd_len =
strlen (cmd) + 3;
76 cmd_len +=
strlen (*argp) + 3;
78 command = (
char *)
malloc (cmd_len);
81 sprintf (command,
"\"%s\"", cmd);
84 cmd_len =
strlen (cmd) + 2;
88 command[cmd_len++] =
' ';
89 command[cmd_len++] =
'"';
91 memcpy (command + cmd_len, *argp, arg_len);
93 command[cmd_len++] =
'"';
101octave_popen2 (
const char *cmd,
char *
const *args,
bool sync_mode,
102 int *fildes,
const char **errmsg)
109 PROCESS_INFORMATION pi;
112 HANDLE hProcess = GetCurrentProcess ();
113 HANDLE childRead, childWrite, parentRead, parentWrite;
116 ZeroMemory (&pi,
sizeof (pi));
117 ZeroMemory (&si,
sizeof (si));
120 if (! CreatePipe (&childRead, &parentWrite, 0, 0)
121 || ! DuplicateHandle (hProcess, childRead, hProcess, &childRead,
123 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
125 *errmsg =
"popen2: pipe creation failed";
129 if (! CreatePipe (&parentRead, &childWrite, 0, 0)
130 || ! DuplicateHandle (hProcess, childWrite, hProcess, &childWrite,
132 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
134 *errmsg =
"popen2: pipe creation failed";
140 pipeMode = PIPE_NOWAIT;
141 SetNamedPipeHandleState (parentRead, &pipeMode, 0, 0);
144 fildes[1] = _open_osfhandle ((intptr_t) parentRead, _O_RDONLY | _O_BINARY);
145 fildes[0] = _open_osfhandle ((intptr_t) parentWrite, _O_WRONLY | _O_BINARY);
147 si.dwFlags |= STARTF_USESTDHANDLES;
149 si.hStdInput = childRead;
150 si.hStdOutput = childWrite;
151 si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
153 command = make_command_string (cmd, args);
159 status = CreateProcessW (NULL, wcmd, NULL, NULL, TRUE, CREATE_NO_WINDOW,
160 NULL, NULL, &si, &pi);
166 *errmsg =
"popen2: process creation failed";
170 pid = pi.dwProcessId;
172 CloseHandle (childRead);
173 CloseHandle (childWrite);
175 CloseHandle (pi.hProcess);
176 CloseHandle (pi.hThread);
184#define OCTAVE_CHILD_FAILURE 129
188 int *fildes,
const char **errmsg)
192 int child_stdin[2], child_stdout[2];
194 if (
pipe (child_stdin) < 0)
196 *errmsg = strerror (errno);
200 if (
pipe (child_stdout) < 0)
202 close (child_stdin[0]);
203 close (child_stdin[1]);
205 *errmsg = strerror (errno);
215 close (child_stdin[1]);
216 close (child_stdout[0]);
220 close (child_stdin[0]);
222 if (
dup2 (child_stdout[1], STDOUT_FILENO) >= 0)
224 close (child_stdout[1]);
226 if (
execvp (cmd, args) < 0)
227 perror (
"error: popen2 (child)");
230 perror (
"error: popen2 (child)");
233 perror (
"error: popen2 (child)");
241 close (child_stdin[0]);
242 close (child_stdout[1]);
244#if defined (F_SETFL) && defined (O_NONBLOCK)
245 if (! sync_mode &&
fcntl (child_stdout[0], F_SETFL, O_NONBLOCK) < 0)
247 *errmsg = strerror (errno);
253 fildes[0] = child_stdin[1];
254 fildes[1] = child_stdout[0];
265 *errmsg = strerror (errno);
268 else if (tst_pid != 0)
271 if (WIFEXITED(wstatus)
274 *errmsg =
"popen2 (parent): failure in child process";
284 *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)
pid_t waitpid(pid_t pid, int *status, int options)
int fcntl(int fd, int cmd, long arg)
int dup2(int old_fd, int new_fd)
#define OCTAVE_CHILD_FAILURE
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)