* 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

@ -1,3 +1,41 @@
2006-12-11 Christopher Faylor <me@cgf.cx>
* 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.
2006-12-11 Corinna Vinschen <corinna@vinschen.de>
* fhandler.cc (rootdir): Fix typo in comment.
@ -78,7 +116,7 @@
2006-12-06 Corinna Vinschen <corinna@vinschen.de>
* termios.cc: Change include order to accomodate change to sys/ioctl.h.
* termios.cc: Change include order to accommodate change to sys/ioctl.h.
2006-12-06 Corinna Vinschen <corinna@vinschen.de>
@ -123,7 +161,7 @@
* fork.cc (frok::parent): Set ch.zero[0] to a sensible count value
if wincap.needs_count_in_si_lpres2 is set.
* spawn.cc (spawn_guts): Ditto. Add filler bytes after ch on stack
to accomodate needs_count_in_si_lpres2.
to accommodate needs_count_in_si_lpres2.
* wincap.h: Define needs_count_in_si_lpres2 throughout.
* wincap.cc: Ditto.
@ -153,7 +191,7 @@
* security.cc (create_token): Revert erroneous change to test
subauth_token for INVAILD_HANDLE_VALUE.
* syscalls.cc (seteuid32): Set create_token's subauth_token parameter
* syscalls.cc (seteuid32): Set create_token's subauth_token parameter
back to NULL.
2006-11-28 Corinna Vinschen <corinna@vinschen.de>
@ -175,7 +213,7 @@
* cyglsa.h: New header file.
* environ.cc: Disable subauth settings.
* grp.cc: Accomodate cygsidlist's count now being a method.
* grp.cc: Accommodate cygsidlist's count now being a method.
* sec_helper.cc (SECURITY_MANDATORY_INTEGRITY_AUTHORITY): Remove.
(mandatory_medium_integrity_sid): Remove.
(mandatory_high_integrity_sid): Remove.
@ -189,7 +227,7 @@
(cygsidlist::add): Move here from security.h. Add well_known parameter.
Set well_known_sid accordingly. Don't allow duplicate SIDs.
* security.cc: Include cyglsa.h and cygwin/version.h. Throughout
accomodate cygsidlist's count now being a method. Throughout drop
accommodate cygsidlist's count now being a method. Throughout drop
redundant "contains" tests.
(get_user_local_groups): Add local groups as well known SIDs.
(get_token_group_sidlist): Add well known groups as well known SIDs.
@ -201,11 +239,11 @@
(get_system_priv_list): Make static. Return size of TOKEN_PRIVILEGES
structure.
(get_priv_list): Ditto.
(create_token): Accomodate above changes. Drop misguided attempt to
(create_token): Accommodate above changes. Drop misguided attempt to
add MIC SIDs to created user token. Print returned token as hex value.
(subauth): Disable.
(lsaauth): New function implementing client side of LSA authentication.
* security.h (class cygsid): Add well_known_sid attribute. Accomodate
* security.h (class cygsid): Add well_known_sid attribute. Accommodate
throughout. Add *= operator to create a well known SID.
(class cygsidlist): Rename count to cnt. Make count a method.
(cygsidlist::add): Move to sec_helper.cc.
@ -351,7 +389,7 @@
(fhandler_dev_zero::mmap): Ditto.
* shared.cc (shared_info::heap_slop_size): New method.
(shared_info::heap_chunk_size): Don't use debug_printf at early stage.
* shared_info.h (SHARED_INFO_CB): Accomodate change to shared_info.
* shared_info.h (SHARED_INFO_CB): Accommodate change to shared_info.
(CURR_SHARED_MAGIC): Ditto.
(class shared_info): Add heap_slop member. Declare heap_slop_size.
* wincap.h: Define heapslop throughout.
@ -388,7 +426,7 @@
2006-10-23 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::rewinddir): Accomodate
* fhandler_disk_file.cc (fhandler_disk_file::rewinddir): Accommodate
buggy RestartScan behaviour of Windows 2000.
* wincap.h: Define has_buggy_restart_scan throughout.
* wincap.cc: Ditto.
@ -423,7 +461,7 @@
get_reg_security.
* security.h (cygpsid::operator PSID): Make method const, not the
result.
(class security_descriptor): Add type member. Accomodate throughout.
(class security_descriptor): Add type member. Accommodate throughout.
(security_descriptor::copy): New method.
(security_descriptor::operator PSECURITY_DESCRIPTOR *): New operator.
@ -513,7 +551,7 @@
opening with backup intent.
(fhandler_disk_file::readdir): Ditto when trying to retrieve file id
explicitely.
* security.cc (check_file_access): Replace pbuf with correctly
* security.cc (check_file_access): Replace pbuf with correctly
PPRIVILEGE_SET typed pset. Check explicitely for backup and/or restore
privileges when AccessCheck fails, to circumvent AccessCheck
shortcoming. Add comment to explain.
@ -653,13 +691,13 @@
* cygwin.din: Export posix_fadvise and posix_fallocate.
* fhandler.cc (fhandler_base::fadvise): New method.
(fhandler_base::ftruncate): Add allow_truncate parameter.
* fhandler.h (class fhandler_base): Add fadvise method. Accomodate
* fhandler.h (class fhandler_base): Add fadvise method. Accommodate
new parameter to ftruncate.
(class fhandler_pipe): Add fadvise and ftruncate methods.
(class fhandler_disk_file): Add fadvise method. Accomodate new
(class fhandler_disk_file): Add fadvise method. Accommodate new
parameter to ftruncate.
* fhandler_disk_file.cc (fhandler_disk_file::fadvise): New method.
(fhandler_disk_file::ftruncate): Accomodate new allow_truncate
(fhandler_disk_file::ftruncate): Accommodate new allow_truncate
parameter. Set EOF using NtSetInformationFile on NT.
* ntdll.h (struct _FILE_END_OF_FILE_INFORMATION): Define.
(NtSetInformationFile): Declare.
@ -667,7 +705,7 @@
(fhandler_pipe::ftruncate): Ditto.
* syscalls.cc (posix_fadvise): New function.
(posix_fallocate): Ditto.
(ftruncate64): Accomodate second parameter to fhandler's ftruncate
(ftruncate64): Accommodate second parameter to fhandler's ftruncate
method.
* include/fcntl.h: Add POSIX_FADV_* flags. Add declarations of
posix_fadvise and posix_fallocate.
@ -842,9 +880,9 @@
* cygtls.h: Drop socket related includes.
(struct _local_storage): Remove exitsock and exitsock_sin. Add
select_sockevt.
* cygtls.cc: Accomodate above change throughout.
* cygtls.cc: Accommodate above change throughout.
* fhandler.h (class fhandler_socket): Make wsock_evt public.
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Accomodate
* fhandler_socket.cc (fhandler_socket::fhandler_socket): Accommodate
reordering members.
(fhandler_socket::evaluate_events): Drop FD_CONNECT event as soon as
it gets read once. Never remove FD_WRITE event here.
@ -857,7 +895,7 @@
(fhandler_socket::send_internal): Drop FD_WRITE event from wsock_events
if the call to WSASendTo fails with WSAEWOULDBLOCK. Fix return value
condition.
* select.cc (struct socketinf): Change to accomodate using socket event
* select.cc (struct socketinf): Change to accommodate using socket event
handling.
(peek_socket): Use event handling for peeking socket.
(thread_socket): Ditto.
@ -885,14 +923,14 @@
(fhandler_socket::wait_for_events): Second half of former wait method.
Call evaluate_events and wait in a loop if socket is blocking.
(fhandler_socket::release_events): Rename from release.
(fhandler_socket::connect): Accomodate above name changes.
(fhandler_socket::connect): Accommodate above name changes.
(fhandler_socket::accept): Ditto.
(fhandler_socket::recv_internal): Ditto.
(fhandler_socket::send_internal): Ditto.
(fhandler_socket::close): Ditto.
(fhandler_socket::fcntl): Always set owner to given input value on
F_SETOWN. Handle F_GETOWN.
* net.cc (fdsock): Accomodate above name changes.
* net.cc (fdsock): Accommodate above name changes.
2006-07-20 Corinna Vinschen <corinna@vinschen.de>
@ -932,7 +970,7 @@
* mmap.cc (mmap_is_attached_or_noreserve_page): Rename
mmap_is_attached_or_noreserve. Add region length parameter.
Return enum above.
* exceptions.cc (_cygtls::handle_exceptions): Accomodate above.
* exceptions.cc (_cygtls::handle_exceptions): Accommodate above.
* fhandler.cc (fhandler_base::raw_read): Call above for NOACCESS
errors and retry on success to allow reads into untouched
MAP_NORESERVE buffers.
@ -1102,7 +1140,7 @@
* fhandler.h (class fhandler_socket): Add wsock_mtx, wsock_evt
and wsock_events members. Remove closed status flag, add listener
status flag. Accomodate new implementation of socket event handling
status flag. Accommodate new implementation of socket event handling
methods. Declare recv* and send* functions ssize_t as the POSIX
equivalents.
(fhandler_socket::recv_internal): Declare.
@ -1130,9 +1168,9 @@
mutex handle and event handle.
(fhandler_socket::dup): Duplicate wsock_mtx and wsock_evt. Fix
copy-paste error in debug output.
(fhandler_socket::connect): Accomodate new event handling.
(fhandler_socket::connect): Accommodate new event handling.
(fhandler_socket::listen): Set listener flag on successful listen.
(fhandler_socket::accept): Accomodate new event handling.
(fhandler_socket::accept): Accommodate new event handling.
(fhandler_socket::recv_internal): New inline method centralizing
common recv code.
(fhandler_socket::recvfrom): Call recv_internal now.
@ -1202,14 +1240,14 @@
* cygwin.din: Export in6addr_any, in6addr_loopback, freeaddrinfo,
gai_strerror, getaddrinfo, getnameinfo.
* fhandler_socket.cc: Include cygwin/in6.h.
(get_inet_addr): Accomodate AF_INET6 usage.
(get_inet_addr): Accommodate AF_INET6 usage.
(fhandler_socket::connect): Ditto.
(fhandler_socket::listen): Ditto.
(fhandler_socket::sendto): Ditto.
* net.cc: Include cygwin/in6.h.
(in6addr_any): Define.
(in6addr_loopback): Define.
(cygwin_socket): Accomodate AF_INET6 usage.
(cygwin_socket): Accommodate AF_INET6 usage.
(socketpair): Bind socketpairs only to loopback for security.
(inet_pton4): New static function.
(inet_pton6): Ditto.
@ -1263,7 +1301,7 @@
RegGetKeySecurity return value.
* security.h (get_logon_server): Remove default vaue from wserver
parameter. Add rediscovery parameter.
* uinfo.cc (cygheap_user::env_logsrv): Accomodate rediscovery parameter
* uinfo.cc (cygheap_user::env_logsrv): Accommodate rediscovery parameter
in call to get_logon_server.
2006-07-05 Christopher Faylor <cgf@timesys.com>
@ -1333,13 +1371,13 @@
NtQueryEaFile.
(write_ea): Rename from NTWriteEA and rewrite using NtSetEaFile.
* path.cc (get_symlink_ea): Make static. Add handle parameter to
accomodate new read_ea call.
(set_symlink_ea): Make static. Add handle parameter to accomodate new
accommodate new read_ea call.
(set_symlink_ea): Make static. Add handle parameter to accommodate new
write_ea call.
(symlink_worker): Call set_symlink_ea while file is still open.
(symlink_info::check): Call get_symlink_ea after file has been opened.
* security.cc (get_file_attribute): Accomodate new read_ea call.
(set_file_attribute): Accomodate new write_ea call.
* security.cc (get_file_attribute): Accommodate new read_ea call.
(set_file_attribute): Accommodate new write_ea call.
* security.h (read_ea): Change declaration accordingly.
(write_ea): Ditto.
@ -1884,9 +1922,9 @@
(path_conv::isgood_inode): Centralized function to recognize
a good inode number.
(fhandler_base::fstat_by_handle): Constify fvi_size and fai_size.
Accomodate argument change in fstat_helper.
Accommodate argument change in fstat_helper.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_helper): Accomodate argument change. Call
(fhandler_base::fstat_helper): Accommodate argument change. Call
path_conv::isgood_inode to recognize good inodes.
(fhandler_disk_file::opendir): Explain Samba weirdness here.
Call path_conv::fs_is_samba instead of path_conv::is_samba.

View File

@ -23,7 +23,6 @@ enum child_status
_CI_STRACED = 0x01,
_CI_ISCYGWIN = 0x02,
_CI_SAW_CTRL_C = 0x04
};
#define OPROC_MAGIC_MASK 0xff00ff00
@ -38,7 +37,7 @@ enum child_status
#define EXEC_MAGIC_SIZE sizeof(child_info)
/* Change this value if you get a message indicating that it is out-of-sync. */
#define CURR_CHILD_INFO_MAGIC 0x3a24db6aU
#define CURR_CHILD_INFO_MAGIC 0x3ebda16aU
/* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between
@ -46,7 +45,7 @@ enum child_status
class child_info
{
public:
DWORD zero[4]; // must be zeroed
DWORD msv_count; // zeroed on < W2K3, set to pseudo-count on Vista
DWORD cb; // size of this record
DWORD intro; // improbable string
unsigned long magic; // magic number unique to child_info
@ -85,6 +84,7 @@ public:
jmp_buf jmp; // where child will jump to
void *stacktop; // location of top of parent stack
void *stackbottom; // location of bottom of parent stack
char filler[4];
child_info_fork ();
void handle_fork () __attribute__ ((regparm (1)));;
bool handle_failure (DWORD) __attribute__ ((regparm (2)));
@ -109,6 +109,9 @@ class child_info_spawn: public child_info
{
public:
cygheap_exec_info *moreinfo;
int __stdin;
int __stdout;
char filler[4];
~child_info_spawn ()
{

View File

@ -425,9 +425,7 @@ check_sanity_and_sync (per_process *p)
/* struct without updating SIZEOF_PER_PROCESS [it makes them think twice */
/* about changing it]. */
if (sizeof (per_process) != SIZEOF_PER_PROCESS)
{
api_fatal ("per_process sanity check failed");
}
api_fatal ("per_process sanity check failed");
/* Make sure that the app and the dll are in sync. */
@ -590,48 +588,17 @@ child_info *
get_cygwin_startup_info ()
{
STARTUPINFO si;
DWORD zeros[sizeof (child_proc_info->zero)
/ sizeof (child_proc_info->zero[0])] = {0};
GetStartupInfo (&si);
child_info *res = (child_info *) si.lpReserved2;
/* It appears that when running under WOW64 on Vista 64, the first DWORD
value in the datastructure lpReserved2 is pointing to (zero[0] in
Cygwin), has to reflect the size of that datastructure as used in the
Microsoft C runtime (a count value, counting the number of elements in
two subsequent arrays, BYTE[count and HANDLE[count]), even though the C
runtime isn't used. Otherwise, if zero[0] is 0 or too small, the
datastructure gets overwritten.
This seems to be a bug in Vista's WOW64, which apparently copies the
lpReserved2 datastructure not using the cbReserved2 size information,
but using the information given in the first DWORD within lpReserved2
instead. 32 bit Windows and former WOW64 don't care if zero[0] is 0
or a sensible non-0 count value. However, it's not clear if a non-0
count doesn't result in trying to evaluate the content, so we do this
really only for Vista 64 for now.
exec/spawn as well as fork write an appropriate value into zero[0] now,
depending on the wincap.needs_count_in_si_lpres2 flag. The value is
sizeof (child_info_*) / 5 which results in a count which covers the
full datastructure, plus not more than 4 extra bytes. This is ok as
long as the child_info structure is cosily stored within a bigger
datastructure. */
if (wincap.needs_count_in_si_lpres2 ())
zeros[0] = si.cbReserved2 / 5;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !res
|| memcmp (res->zero, zeros, sizeof (res->zero)) != 0)
|| res->intro != PROC_MAGIC_GENERIC || res->magic != CHILD_INFO_MAGIC)
res = NULL;
else
{
if ((res->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
multiple_cygwin_problem ("proc intro", res->intro, 0);
else if (res->intro == PROC_MAGIC_GENERIC
&& res->magic != CHILD_INFO_MAGIC)
multiple_cygwin_problem ("proc magic", res->magic,
CHILD_INFO_MAGIC);
else if (res->cygheap != (void *) &_cygheap_start)
multiple_cygwin_problem ("cygheap base", (DWORD) res->cygheap,
(DWORD) &_cygheap_start);
@ -718,6 +685,11 @@ child_info_spawn::handle_spawn ()
envc = moreinfo->envc;
if (!dynamically_loaded)
cygheap->fdtab.fixup_after_exec ();
if (__stdin >= 0)
cygheap->fdtab.move_fd (__stdin, 0);
if (__stdout >= 0)
cygheap->fdtab.move_fd (__stdout, 1);
ready (true);
/* Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of

View File

@ -662,6 +662,14 @@ dtable::fixup_before_fork (DWORD target_proc_id)
unlock ();
}
void
dtable::move_fd (int from, int to)
{
// close (to); /* It is assumed that this is close-on-exec */
fds[to] = fds[from];
fds[from] = NULL;
}
void
dtable::fixup_before_exec (DWORD target_proc_id)
{

View File

@ -45,6 +45,7 @@ public:
bool need_fixup_before ()
{ return cnt_need_fixup_before > 0; }
void move_fd (int, int);
int vfork_child_dup ();
void vfork_parent_restore ();
void vfork_child_fixup ();

View File

@ -1534,19 +1534,23 @@ fhandler_dev_null::open (int flags, mode_t mode)
}
void
fhandler_base::set_no_inheritance (HANDLE &h, int not_inheriting)
fhandler_base::set_no_inheritance (HANDLE &h, bool not_inheriting)
{
HANDLE oh = h;
/* Note that we could use SetHandleInformation here but it is not available
on all platforms. Test cases seem to indicate that using DuplicateHandle
in this fashion does not actually close the original handle, which is
what we want. If this changes in the future, we may be forced to use
SetHandleInformation on newer OS's */
if (!DuplicateHandle (hMainProc, oh, hMainProc, &h, 0, !not_inheriting,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
debug_printf ("DuplicateHandle failed, %E");
if (oh != h)
VerifyHandle (h);
if (wincap.has_set_handle_information ())
{
if (!SetHandleInformation (h, HANDLE_FLAG_INHERIT, not_inheriting ? 0 : HANDLE_FLAG_INHERIT))
debug_printf ("SetHandleInformation failed, %E");
}
else
{
HANDLE oh = h;
if (!DuplicateHandle (hMainProc, oh, hMainProc, &h, 0, !not_inheriting,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
debug_printf ("DuplicateHandle failed, %E");
if (oh != h)
VerifyHandle (h);
}
#ifdef DEBUGGING_AND_FDS_PROTECTED
if (h)
setclexec (oh, h, not_inheriting);

View File

@ -167,7 +167,7 @@ class fhandler_base
void set_flags (int x, int supplied_bin = 0);
bool is_nonblocking ();
void set_nonblocking (int yes);
void set_nonblocking (int);
bool wbinary () const { return status.wbinset ? status.wbinary : 1; }
bool rbinary () const { return status.rbinset ? status.rbinary : 1; }
@ -249,15 +249,15 @@ class fhandler_base
virtual char *get_proc_fd_name (char *buf);
virtual void hclose (HANDLE h) {CloseHandle (h);}
virtual void set_no_inheritance (HANDLE &h, int not_inheriting);
virtual void set_no_inheritance (HANDLE &, bool);
/* fixup fd possibly non-inherited handles after fork */
bool fork_fixup (HANDLE parent, HANDLE &h, const char *name);
bool fork_fixup (HANDLE, HANDLE &, const char *);
virtual bool need_fixup_before () const {return false;}
int open_9x (int flags, mode_t mode = 0);
virtual int open (int flags, mode_t mode = 0);
int open_fs (int flags, mode_t mode = 0);
int open_9x (int, mode_t = 0);
virtual int open (int, mode_t = 0);
int open_fs (int, mode_t = 0);
virtual int close ();
int close_fs ();
virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
@ -520,8 +520,12 @@ protected:
HANDLE writepipe_exists;
DWORD orig_pid;
unsigned id;
private:
pid_t popen_pid;
public:
fhandler_pipe ();
void set_popen_pid (pid_t pid) {popen_pid = pid;}
pid_t get_popen_pid () const {return popen_pid;}
_off64_t lseek (_off64_t offset, int whence);
select_record *select_read (select_record *s);
select_record *select_write (select_record *s);

View File

@ -284,10 +284,6 @@ frok::parent (void *stack_here)
si.lpReserved2 = (LPBYTE) &ch;
si.cbReserved2 = sizeof (ch);
/* See comment in dcrt0.cc, function get_cygwin_startup_info. */
if (wincap.needs_count_in_si_lpres2 ())
ch.zero[0] = sizeof (ch) / 5;
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %p, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi);
bool locked = __malloc_lock ();

View File

@ -32,7 +32,7 @@ static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u";
fhandler_pipe::fhandler_pipe ()
: fhandler_base (), guard (NULL), broken_pipe (false), writepipe_exists (NULL),
orig_pid (0), id (0)
orig_pid (0), id (0), popen_pid (0)
{
need_fork_fixup (true);
}
@ -280,6 +280,7 @@ fhandler_pipe::dup (fhandler_base *child)
{
int res = -1;
fhandler_pipe *ftp = (fhandler_pipe *) child;
ftp->set_popen_pid (0);
ftp->guard = ftp->writepipe_exists = ftp->read_state = NULL;
if (get_handle () && fhandler_base::dup (child))

View File

@ -253,9 +253,6 @@ shared_info::heap_slop_size ()
heap_slop = 0;
else
heap_slop <<= 20;
#ifdef DEBUGGING
system_printf ("fixed heap slop is %p", heap_slop);
#endif
}
return heap_slop;
@ -287,9 +284,6 @@ shared_info::heap_chunk_size ()
heap_chunk <<= 20;
if (!heap_chunk)
heap_chunk = 384 * 1024 * 1024;
#ifdef DEBUGGING
system_printf ("fixed heap size is %u", heap_chunk);
#endif
}
return heap_chunk;

View File

@ -145,7 +145,7 @@ public:
#define SHARED_INFO_CB 19988
#define CURR_SHARED_MAGIC 0xb632a4cU
#define CURR_SHARED_MAGIC 0x87c42d1eU
/* NOTE: Do not make gratuitous changes to the names or organization of the
below class. The layout is checksummed to determine compatibility between

View File

@ -787,6 +787,9 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, bool need_subpr
{
memset (this, 0, in_cb);
cb = in_cb;
msv_count = in_cb / 5;
intro = PROC_MAGIC_GENERIC;
magic = CHILD_INFO_MAGIC;
type = chtype;

View File

@ -210,7 +210,7 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv,
/* Utility for spawn_guts. */
static HANDLE
handle (int fd, int direction)
handle (int fd, bool writing)
{
HANDLE h;
cygheap_fdget cfd (fd);
@ -219,10 +219,11 @@ handle (int fd, int direction)
h = INVALID_HANDLE_VALUE;
else if (cfd->close_on_exec ())
h = INVALID_HANDLE_VALUE;
else if (direction == 0)
else if (!writing)
h = cfd->get_handle ();
else
h = cfd->get_output_handle ();
return h;
}
@ -259,9 +260,9 @@ do_cleanup (void *args)
}
static int __stdcall
int __stdcall
spawn_guts (const char * prog_arg, const char *const *argv,
const char *const envp[], int mode)
const char *const envp[], int mode, int __stdin, int __stdout)
{
bool rc;
pid_t cygpid;
@ -298,14 +299,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
pthread_cleanup_push (do_cleanup, (void *) &cleanup);
av newargv;
linebuf one_line;
/* Allocate slightly bigger for call to CreateProcess to accomodate
needs_count_in_si_lpres2. */
struct {
child_info_spawn ch;
char filler[4];
} _ch;
#define ch _ch.ch
child_info_spawn ch;
char *envblock = NULL;
path_conv real_path;
bool reset_sendsig = false;
@ -316,7 +310,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
cygheap_exec_info *moreinfo;
bool null_app_name = false;
STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
NULL, NULL, NULL};
int looped = 0;
HANDLE orig_wr_proc_pipe = NULL;
@ -411,10 +406,13 @@ spawn_guts (const char * prog_arg, const char *const *argv,
pi.dwProcessId = pi.dwThreadId = 0;
si.lpReserved = NULL;
si.lpDesktop = NULL;
/* Set up needed handles for stdio */
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = handle (0, 0); /* Get input handle */
si.hStdOutput = handle (1, 1); /* Get output handle */
si.hStdError = handle (2, 1); /* Get output handle */
si.hStdInput = handle ((__stdin < 0 ? 0 : __stdin), false);
si.hStdOutput = handle ((__stdout < 0 ? 1 : __stdout), true);
si.hStdError = handle (2, true);
si.cb = sizeof (si);
if (!wincap.pty_needs_alloc_console () && newargv.iscui && myself->ctty == -1)
{
@ -483,14 +481,12 @@ spawn_guts (const char * prog_arg, const char *const *argv,
}
ch.set (chtype, real_path.iscygexec ());
ch.moreinfo = moreinfo;
ch.__stdin = __stdin;
ch.__stdout = __stdout;
si.lpReserved2 = (LPBYTE) &ch;
si.cbReserved2 = sizeof (ch);
/* See comment in dcrt0.cc, function get_cygwin_startup_info. */
if (wincap.needs_count_in_si_lpres2 ())
ch.zero[0] = sizeof (ch) / 5;
/* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different
effective vs. real ids.

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;
}

View File

@ -170,6 +170,9 @@ void dll_crt0 (per_process *) __asm__ ("_dll_crt0__FP11per_process");
extern "C" void __stdcall _dll_crt0 ();
extern void dll_crt0_1 (void *);
extern void dll_dllcrt0_1 (void *);
extern int __stdcall spawn_guts (const char * prog_arg, const char *const *argv,
const char *const envp[], int mode,
int __stdin = -1, int __stdout = -1);
/* dynamically loaded dll initialization */
extern "C" int dll_dllcrt0 (HMODULE, per_process *);