aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-09-24 21:50:44 +0000
committerChristopher Faylor <me@cgf.cx>2001-09-24 21:50:44 +0000
commit35f879a6d0b6c24045570cf882d1474e1ab0de00 (patch)
tree958334eb496e1b3d8f1311d572d78092717787b7 /winsup
parent4367ec036fabc17ed167b798449537d2a05dda71 (diff)
downloadnewlib-35f879a6d0b6c24045570cf882d1474e1ab0de00.zip
newlib-35f879a6d0b6c24045570cf882d1474e1ab0de00.tar.gz
newlib-35f879a6d0b6c24045570cf882d1474e1ab0de00.tar.bz2
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog22
-rw-r--r--winsup/cygwin/dtable.cc6
-rw-r--r--winsup/cygwin/fhandler.h10
-rw-r--r--winsup/cygwin/fhandler_tty.cc2
-rw-r--r--winsup/cygwin/how-vfork-works.txt4
-rw-r--r--winsup/cygwin/pipe.cc72
-rw-r--r--winsup/cygwin/select.cc11
-rw-r--r--winsup/cygwin/syscalls.cc33
8 files changed, 117 insertions, 43 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index b14ef4e..d824d82 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,25 @@
+Mon Sep 24 17:41:03 2001 Christopher Faylor <cgf@redhat.com>
+
+ * 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 <corinna@vinschen.de>
* syscalls.cc (_open): Set name in fhandler object after successful
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index d397133..e08ed42 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 1fe6990..ed9ca35 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 4aa3b05..1a46ecb 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 c45228c..7148366 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 04a1fbe..aab242b 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 67365d9..b01d833 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 559582b..9f5c8ac 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");
}