Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog104
-rw-r--r--winsup/cygwin/child_info.h9
-rw-r--r--winsup/cygwin/dcrt0.cc42
-rw-r--r--winsup/cygwin/dtable.cc8
-rw-r--r--winsup/cygwin/dtable.h1
-rw-r--r--winsup/cygwin/fhandler.cc28
-rw-r--r--winsup/cygwin/fhandler.h16
-rw-r--r--winsup/cygwin/fork.cc4
-rw-r--r--winsup/cygwin/pipe.cc3
-rw-r--r--winsup/cygwin/shared.cc6
-rw-r--r--winsup/cygwin/shared_info.h2
-rw-r--r--winsup/cygwin/sigproc.cc3
-rw-r--r--winsup/cygwin/spawn.cc36
-rw-r--r--winsup/cygwin/syscalls.cc107
-rw-r--r--winsup/cygwin/winsup.h3
15 files changed, 251 insertions, 121 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a20dfb6bc..05071df0b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index d2b712e88..41abe00f6 100644
--- a/winsup/cygwin/child_info.h
+++ b/winsup/cygwin/child_info.h
@@ -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 ()
{
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 38b4b67f3..727163e08 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -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
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index bb84574d4..b436c88c6 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -663,6 +663,14 @@ dtable::fixup_before_fork (DWORD target_proc_id)
}
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)
{
lock ();
diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h
index 5e136ab9b..bc52a8f1a 100644
--- a/winsup/cygwin/dtable.h
+++ b/winsup/cygwin/dtable.h
@@ -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 ();
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index f6882e874..5070855dd 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -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);
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index af267d92c..6e7bf4821 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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);
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index cc5beceb7..b94a28d0b 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -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 ();
diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc
index d56b32aff..99231e7f1 100644
--- a/winsup/cygwin/pipe.cc
+++ b/winsup/cygwin/pipe.cc
@@ -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))
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index 4c4b7bc72..4e54a7558 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -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;
diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h
index a1a4be0db..d9b37d72a 100644
--- a/winsup/cygwin/shared_info.h
+++ b/winsup/cygwin/shared_info.h
@@ -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
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index d2c9109c8..3a764fe63 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -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;
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 12418df92..352e51c87 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -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.
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index bde4d65cf..4a3114d4c 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -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;
+}
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 4c0f514f3..9e9aea271 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -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 *);