* child_info.h (child_info_spawn::__stdin): New element.

(child_info_spawn::__stdin): Ditto.
(CURR_CHILD_INFO_MAGIC): Regenerate.
* dcrt0.cc (check_sanity_and_sync): Minor cleanup.
(child_info_spawn::handle_spawn): Handle new __std* elements by calling
move_fd.
* dtable.cc (dtable::move_fd): Define new function.
* dtable.h (dtable::move_fd): Declare new function.
* fhandler.h (fhandler_pipe::popen_pid): Declare new element.
* fhandler.h (fhandler_pipe::get_popen_pid): Define new function.
* fhandler.h (fhandler_pipe::set_popen_pid): Ditto.
* pipe.cc (fhandler_pipe::fhandler_pipe): Zero popen_pid.
(fhandler_pipe::dup): Ditto.
* spawn.cc (handle): Change second argument to bool.
(spawn_guts): Accept __stdin/__stdout arguments and set them appropriately in
child_info structure and in STARTUPINFO structure.
* syscalls.cc (popen): New cygwin-specific implementation using spawn.
(pclose): Ditto.
* winsup.h (spawn_guts): Accommodate new arguments for spawn_guts.
* fhandler.cc (fhandler_base::set_no_inheritance): Make second arg a bool.
* fhandler.h (fhandler_base::set_no_inheritance): Ditto for declaration.
* child_info.h (child_info::msv_count): Rename from the now-inappropriate
"zero".
(child_info_spawn::filler): Add filler to work around Vista bug.
(child_info_fork::filler): Ditto.
* dcrt0.cc (get_cygwin_startup_info): Remove "zero" check since it is now
always filled out.
* fork.cc (frok::parent): Move ch.zero manipulation to constructor.
* spawn.cc (spawn_guts): Ditto.  Remove _ch wrapper.
* sigproc.cc (child_info::child_info): Initialize starter[].
* shared.cc (shared_info::heap_slop_size): Remove noisy system_printfs.
* shared_info.h (CURR_SHARED_MAGIC): Regenerate.
This commit is contained in:
Christopher Faylor
2006-12-11 18:55:29 +00:00
parent e79c01f84e
commit c16548b2a2
15 changed files with 251 additions and 121 deletions

View File

@@ -40,6 +40,7 @@ details. */
#include <limits.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/wait.h>
#include <winnls.h>
#include <wininet.h>
#include <winioctl.h>
@@ -3242,3 +3243,109 @@ funlockfile (FILE *file)
{
_funlockfile (file);
}
extern "C" FILE *
popen (const char *command, const char *type)
{
int fds[2];
if (pipe (fds) < 0)
return NULL;
int fd, other_fd, __stdin, __stdout, stdwhat;
if (type[1] != '\0')
{
set_errno (EINVAL);
return NULL;
}
if (*type == 'r')
{
__stdin = -1;
stdwhat = 1;
other_fd = __stdout = fds[1];
fd = fds[0];
}
else if (*type == 'w')
{
__stdout = -1;
stdwhat = 0;
other_fd = __stdin = fds[0];
fd = fds[1];
}
else
{
set_errno (EINVAL);
return NULL;
}
FILE *fp = fdopen (fd, type);
fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
if (!fp)
goto err;
pid_t pid;
const char *argv[4];
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = command;
argv[3] = NULL;
{
lock_process now;
int state = fcntl (stdwhat, F_GETFD, 0);
fcntl (stdwhat, F_SETFD, state | FD_CLOEXEC);
pid = spawn_guts ("/bin/sh", argv, cur_environ (), _P_NOWAIT,
__stdin, __stdout);
fcntl (stdwhat, F_SETFD, state);
}
if (pid < 0)
goto err;
close (other_fd);
fhandler_pipe *fh = (fhandler_pipe *) cygheap->fdtab[fd];
fh->set_popen_pid (pid);
return fp;
err:
int save_errno = get_errno ();
close (fds[0]);
close (fds[1]);
set_errno (save_errno);
return NULL;
}
int
pclose (FILE *fp)
{
fhandler_pipe *fh = (fhandler_pipe *) cygheap->fdtab[fileno(fp)];
if (fh->get_device () != FH_PIPEW && fh->get_device () != FH_PIPER)
{
set_errno (EBADF);
return -1;
}
int pid = fh->get_popen_pid ();
if (!pid)
{
set_errno (ECHILD);
return -1;
}
if (fclose (fp))
return -1;
int status;
while (1)
if (waitpid (pid, &status, 0) == pid)
break;
else if (get_errno () == EINTR)
continue;
else
return -1;
return status;
}