From 35f879a6d0b6c24045570cf882d1474e1ab0de00 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 24 Sep 2001 21:50:44 +0000 Subject: * fhandler.h (fhandler_pipe::hit_eof): New method. (writepipe_exists): New class element. (orig_pid): Ditto. (id): Ditto. (is_slow): Eliminate. * pipe.cc (fhandler_pipe::set_close_on_exec): Set inheritance on writepipe_exists, if it exists. (fhandler_pipe::hit_eof): New method, modelled after tty. (fhandler_pipe::dup): Duplicate writepipe_exists, if it exists. (make_pipe): Set up a dummy event for pipes on windows 9x. The nonexistence of this event means that the write side of the pipe has closed. (_dup): Move to syscalls.cc (_dup2): Ditto. * dtable.cc (dtable::build_fhandler): Fill out set_names here, if appropriate. * syscalls.cc (_open): Call set_names in build_fhandler. --- winsup/cygwin/ChangeLog | 22 ++++++++++++ winsup/cygwin/dtable.cc | 6 +++- winsup/cygwin/fhandler.h | 10 ++++-- winsup/cygwin/fhandler_tty.cc | 2 +- winsup/cygwin/how-vfork-works.txt | 4 +-- winsup/cygwin/pipe.cc | 72 +++++++++++++++++++++++++++------------ winsup/cygwin/select.cc | 11 +++--- winsup/cygwin/syscalls.cc | 33 +++++++++++++----- 8 files changed, 117 insertions(+), 43 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index b14ef4e8f..d824d8233 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,25 @@ +Mon Sep 24 17:41:03 2001 Christopher Faylor + + * fhandler.h (fhandler_pipe::hit_eof): New method. + (writepipe_exists): New class element. + (orig_pid): Ditto. + (id): Ditto. + (is_slow): Eliminate. + * pipe.cc (fhandler_pipe::set_close_on_exec): Set inheritance on + writepipe_exists, if it exists. + (fhandler_pipe::hit_eof): New method, modelled after tty. + (fhandler_pipe::dup): Duplicate writepipe_exists, if it exists. + (make_pipe): Set up a dummy event for pipes on windows 9x. The + nonexistence of this event means that the write side of the + pipe has closed. + (_dup): Move to syscalls.cc + (_dup2): Ditto. + + * dtable.cc (dtable::build_fhandler): Fill out set_names here, if + appropriate. + * syscalls.cc (_open): Call set_names in build_fhandler. + + Sun Sep 23 16:55:00 2001 Corinna Vinschen * syscalls.cc (_open): Set name in fhandler object after successful diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index d39713365..e08ed4209 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -232,6 +232,7 @@ dtable::build_fhandler (int fd, const char *name, HANDLE handle, path_conv *pc) { int unit; DWORD devn; + fhandler_base *fh; if (!pc) devn = get_device_number (name, unit); @@ -265,7 +266,10 @@ dtable::build_fhandler (int fd, const char *name, HANDLE handle, path_conv *pc) devn = FH_DISK; } - return build_fhandler (fd, devn, name, unit); + fh = build_fhandler (fd, devn, name, unit); + if (pc) + fh->set_name (name, *pc); + return fh; } fhandler_base * diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 1fe6990d0..ed9ca350b 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -368,7 +368,7 @@ public: virtual HANDLE& get_handle () { return io_handle; } virtual HANDLE& get_io_handle () { return io_handle; } virtual HANDLE& get_output_handle () { return io_handle; } - virtual BOOL hit_eof () {return FALSE;} + virtual bool hit_eof () {return FALSE;} virtual select_record *select_read (select_record *s); virtual select_record *select_write (select_record *s); virtual select_record *select_except (select_record *s); @@ -437,10 +437,12 @@ public: class fhandler_pipe: public fhandler_base { HANDLE guard; + HANDLE writepipe_exists; + DWORD orig_pid; + unsigned id; public: fhandler_pipe (const char *name = 0, DWORD devtype = FH_PIPE); off_t lseek (off_t offset, int whence); - BOOL is_slow () {return !wincap.has_unreliable_pipes ();} select_record *select_read (select_record *s); select_record *select_write (select_record *s); select_record *select_except (select_record *s); @@ -450,6 +452,8 @@ public: int close (); void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);} int dup (fhandler_base *child); + bool hit_eof (); + friend int make_pipe (int fildes[2], unsigned int psize, int mode); }; class fhandler_dev_raw: public fhandler_base @@ -863,7 +867,7 @@ public: char *ptsname (); void set_close_on_exec (int val); - BOOL hit_eof (); + bool hit_eof (); }; class fhandler_tty_master: public fhandler_pty_master diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 4aa3b0572..1a46ecb3b 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -223,7 +223,7 @@ process_input (void *) } } -BOOL +bool fhandler_pty_master::hit_eof () { if (get_ttyp ()->was_opened && !get_ttyp ()->slave_alive ()) diff --git a/winsup/cygwin/how-vfork-works.txt b/winsup/cygwin/how-vfork-works.txt index c45228cad..7148366db 100644 --- a/winsup/cygwin/how-vfork-works.txt +++ b/winsup/cygwin/how-vfork-works.txt @@ -28,8 +28,8 @@ the result of a vfork and closes the extra file handles. This all relies on the fact that the child in a vfork call can affect just about everything in the parent except for the parent's fds. -The assumption is that you don't return from the call that invoked the -vfork. +The assumption is that a vfork is always just used as a method for +starting a program. The assumption is also that all of this is much faster than the slow method that cygwin uses to implement fork(). diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 04a1fbece..aab242b89 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -18,9 +18,15 @@ details. */ #include "dtable.h" #include "cygheap.h" #include "thread.h" +#include "sigproc.h" +#include "pinfo.h" + +static unsigned pipecount; +static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u"; fhandler_pipe::fhandler_pipe (const char *name, DWORD devtype) : - fhandler_base (devtype, name), guard (0) + fhandler_base (devtype, name), + guard (0), writepipe_exists(0), orig_pid (0), id (0) { set_cb (sizeof *this); } @@ -37,7 +43,10 @@ void fhandler_pipe::set_close_on_exec (int val) { this->fhandler_base::set_close_on_exec (val); - set_inheritance (guard, val); + if (guard) + set_inheritance (guard, val); + if (writepipe_exists) + set_inheritance (writepipe_exists, val); } int @@ -53,9 +62,27 @@ int fhandler_pipe::close () int res = this->fhandler_base::close (); if (guard) CloseHandle (guard); + if (writepipe_exists) +{debug_printf ("writepipe_exists closed"); + CloseHandle (writepipe_exists); +} return res; } +bool +fhandler_pipe::hit_eof () +{ + char buf[80]; + HANDLE ev; + if (!orig_pid) + return bg_ok; + __small_sprintf (buf, pipeid_fmt, orig_pid, id); + if ((ev = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf))) + CloseHandle (ev); + debug_printf ("%s %p", buf, ev); + return ev == NULL; +} + int fhandler_pipe::dup (fhandler_base *child) { @@ -70,10 +97,21 @@ fhandler_pipe::dup (fhandler_base *child) else if (!DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, 1, DUPLICATE_SAME_ACCESS)) return -1; + + if (writepipe_exists == NULL) + ftp->writepipe_exists = NULL; + else if (!DuplicateHandle (hMainProc, writepipe_exists, hMainProc, + &ftp->writepipe_exists, 0, 1, + DUPLICATE_SAME_ACCESS)) + return -1; + + ftp->id = id; + ftp->orig_pid = orig_pid; return 0; } -static int + +int make_pipe (int fildes[2], unsigned int psize, int mode) { SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "make_pipe"); @@ -108,6 +146,15 @@ make_pipe (int fildes[2], unsigned int psize, int mode) res = 0; fhr->create_guard (sa); + if (wincap.has_unreliable_pipes ()) + { + char buf[80]; + int count = pipecount++; /* FIXME: Should this be InterlockedIncrement? */ + __small_sprintf (buf, pipeid_fmt, myself->pid, count); + fhw->writepipe_exists = CreateEvent (sa, TRUE, FALSE, buf); + fhr->orig_pid = myself->pid; + fhr->id = count; + } } syscall_printf ("%d = make_pipe ([%d, %d], %d, %p)", res, fdr, fdw, psize, mode); @@ -131,22 +178,3 @@ _pipe (int filedes[2], unsigned int psize, int mode) cygheap->fdtab[filedes[0]]->set_r_no_interrupt (1); return res; } - -int -dup (int fd) -{ - int res; - SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); - - res = dup2 (fd, cygheap->fdtab.find_unused_handle ()); - - ReleaseResourceLock(LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); - - return res; -} - -int -dup2 (int oldfd, int newfd) -{ - return cygheap->fdtab.dup2 (oldfd, newfd); -} diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 67365d925..b01d833ef 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -420,11 +420,6 @@ peek_pipe (select_record *s, int ignra, HANDLE guard_mutex = NULL) gotone = 1; goto out; } - if (fh->bg_check (SIGTTIN) <= bg_eof) - { - gotone = s->read_ready = 1; - goto out; - } switch (fh->get_device ()) { @@ -444,6 +439,12 @@ peek_pipe (select_record *s, int ignra, HANDLE guard_mutex = NULL) goto out; } } + + if (fh->bg_check (SIGTTIN) <= bg_eof) + { + gotone = s->read_ready = 1; + goto out; + } } if (fh->get_device () == FH_PIPEW) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 559582bfd..9f5c8ac88 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -81,6 +81,25 @@ check_ttys_fds (void) return res; } +int +dup (int fd) +{ + int res; + SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); + + res = dup2 (fd, cygheap->fdtab.find_unused_handle ()); + + ReleaseResourceLock(LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); + + return res; +} + +int +dup2 (int oldfd, int newfd) +{ + return cygheap->fdtab.dup2 (oldfd, newfd); +} + extern "C" int _unlink (const char *ourname) { @@ -489,17 +508,13 @@ _open (const char *unix_path, int flags, ...) path_conv pc; if (!(fh = cygheap->fdtab.build_fhandler (fd, unix_path, NULL, &pc))) res = -1; // errno already set - else + else if (!fh->open (pc, flags, (mode & 07777) & ~cygheap->umask)) { - fh->set_name (unix_path, pc.get_win32 ()); - if (!fh->open (pc, flags, (mode & 07777) & ~cygheap->umask)) - { - cygheap->fdtab.release (fd); - res = -1; - } - else if ((res = fd) <= 2) - set_std_handle (res); + cygheap->fdtab.release (fd); + res = -1; } + else if ((res = fd) <= 2) + set_std_handle (res); } ReleaseResourceLock (LOCK_FD_LIST,WRITE_LOCK|READ_LOCK," open"); } -- cgit v1.2.3