4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-20 16:01:10 +08:00

* 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.
This commit is contained in:
Christopher Faylor 2001-09-24 21:50:44 +00:00
parent 4367ec036f
commit 35f879a6d0
8 changed files with 117 additions and 43 deletions

View File

@ -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

View File

@ -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 *

View File

@ -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

View File

@ -223,7 +223,7 @@ process_input (void *)
}
}
BOOL
bool
fhandler_pty_master::hit_eof ()
{
if (get_ttyp ()->was_opened && !get_ttyp ()->slave_alive ())

View File

@ -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().

View File

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

View File

@ -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)

View File

@ -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");
}