* 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:
parent
e79c01f84e
commit
c16548b2a2
|
@ -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.
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
|
Loading…
Reference in New Issue