* dtable.cc (dtable::build_fhandler): Issue internal error on unknown device.

* fhandler.cc (fhandler_base::close): Show both name and handle in debugging
output.
* fhandler.h (fhandler_base::get_guard): New virtual method.
(fhandler_pipe::get_guard): New method.
(fhandler_socket::ready_for_read): Delete declaration.
(fhandler_pipe::ready_for_read): Ditto.
(fhandler_serial::ready_for_read): Ditto.
(fhandler_console::ready_for_read): Ditto.
(fhandler_tty_common::ready_for_read): Ditto.
(fhandler_windows::ready_for_read): Ditto.
(struct select_record::peek): Declare new method.
* select.cc (MAKEready): Delete.
(peek_pipe): Use get_guard method to retrieve potential guard mutex handle.
(fhandler_base::ready_for_read): Rewrite as generic ready-for-read handler.
Should only be called for "slow" devices.
(fhandler_socket::ready_for_read): Delete definition.
(fhandler_pipe::ready_for_read): Ditto.
(fhandler_serial::ready_for_read): Ditto.
(fhandler_console::ready_for_read): Ditto.
(fhandler_tty_common::ready_for_read): Ditto.
(fhandler_windows::ready_for_read): Ditto.
(fhandler_pipe::select_read): Fill in new peek record in select_record
structure.
(fhandler_console::select_read): Ditto.
(fhandler_tty_common::select_read): Ditto.
(fhandler_serial::select_read): Ditto.
(fhandler_socket::select_read): Ditto.
(fhandler_socket::select_read): Ditto.
(fhandler_tty_slave::ready_for_read): Check for tty not open.  Set errnos
appropriately.
* syscalls.cc (_read): Allow ready_for_read to set errno.
* pinfo.cc (pinfo::init): Return spawn/NO_WAIT process as valid if it is
initializing.
* sigproc.cc (getsem): Adjust wait for process to initialize downward to avoid
huge waits.
This commit is contained in:
Christopher Faylor 2001-11-01 21:15:53 +00:00
parent 5cf6708ef4
commit 1229d4f4ee
9 changed files with 146 additions and 119 deletions

View File

@ -1,3 +1,46 @@
2001-11-01 Christopher Faylor <cgf@redhat.com>
* dtable.cc (dtable::build_fhandler): Issue internal error on unknown
device.
* fhandler.cc (fhandler_base::close): Show both name and handle in
debugging output.
* fhandler.h (fhandler_base::get_guard): New virtual method.
(fhandler_pipe::get_guard): New method.
(fhandler_socket::ready_for_read): Delete declaration.
(fhandler_pipe::ready_for_read): Ditto.
(fhandler_serial::ready_for_read): Ditto.
(fhandler_console::ready_for_read): Ditto.
(fhandler_tty_common::ready_for_read): Ditto.
(fhandler_windows::ready_for_read): Ditto.
(struct select_record::peek): Declare new method.
* select.cc (MAKEready): Delete.
(peek_pipe): Use get_guard method to retrieve potential guard mutex
handle.
(fhandler_base::ready_for_read): Rewrite as generic ready-for-read
handler. Should only be called for "slow" devices.
(fhandler_socket::ready_for_read): Delete definition.
(fhandler_pipe::ready_for_read): Ditto.
(fhandler_serial::ready_for_read): Ditto.
(fhandler_console::ready_for_read): Ditto.
(fhandler_tty_common::ready_for_read): Ditto.
(fhandler_windows::ready_for_read): Ditto.
(fhandler_pipe::select_read): Fill in new peek record in select_record
structure.
(fhandler_console::select_read): Ditto.
(fhandler_tty_common::select_read): Ditto.
(fhandler_serial::select_read): Ditto.
(fhandler_socket::select_read): Ditto.
(fhandler_socket::select_read): Ditto.
(fhandler_tty_slave::ready_for_read): Check for tty not open. Set
errnos appropriately.
* syscalls.cc (_read): Allow ready_for_read to set errno.
* pinfo.cc (pinfo::init): Return spawn/NO_WAIT process as valid if it
is initializing.
* sigproc.cc (getsem): Adjust wait for process to initialize downward
to avoid huge waits.
2001-10-31 Christopher Faylor <cgf@redhat.com> 2001-10-31 Christopher Faylor <cgf@redhat.com>
* environ.cc: Set reset_com to false to mimic linux behavior more * environ.cc: Set reset_com to false to mimic linux behavior more

View File

@ -325,14 +325,11 @@ dtable::build_fhandler (int fd, DWORD dev, const char *name, int unit)
fh = cnew (fhandler_dev_dsp) (); fh = cnew (fhandler_dev_dsp) ();
break; break;
default: default:
{ system_printf ("internal error -- unknown device - %p", dev);
/* FIXME - this could recurse forever */ fh = NULL;
path_conv pc;
return build_fhandler_from_name (fd, name, NULL, pc);
}
} }
debug_printf ("%s - fd %d, fh %p", fh->get_name () ?: "", fd, fh); debug_printf ("%s - fd %d, fh %p", fd, fh);
return fd >= 0 ? (fds[fd] = fh) : fh; return fd >= 0 ? (fds[fd] = fh) : fh;
} }

View File

@ -784,7 +784,7 @@ fhandler_base::close ()
{ {
int res = -1; int res = -1;
syscall_printf ("handle %p", get_handle()); syscall_printf ("closing '%s' handle %p", get_name (), get_handle());
if (CloseHandle (get_handle())) if (CloseHandle (get_handle()))
res = 0; res = 0;
else else

View File

@ -371,6 +371,7 @@ public:
rabuf = NULL; rabuf = NULL;
} }
void operator delete (void *); void operator delete (void *);
HANDLE get_guard () const {return NULL;}
}; };
class fhandler_socket: public fhandler_base class fhandler_socket: public fhandler_base
@ -410,7 +411,6 @@ public:
select_record *select_read (select_record *s); select_record *select_read (select_record *s);
select_record *select_write (select_record *s); select_record *select_write (select_record *s);
select_record *select_except (select_record *s); select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
int get_addr_family () {return addr_family;} int get_addr_family () {return addr_family;}
void set_addr_family (int af) {addr_family = af;} void set_addr_family (int af) {addr_family = af;}
void set_connect_secret (); void set_connect_secret ();
@ -434,7 +434,6 @@ public:
select_record *select_read (select_record *s); select_record *select_read (select_record *s);
select_record *select_write (select_record *s); select_record *select_write (select_record *s);
select_record *select_except (select_record *s); select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
void set_close_on_exec (int val); void set_close_on_exec (int val);
int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3)));
int close (); int close ();
@ -443,6 +442,7 @@ public:
void fixup_after_fork (HANDLE); void fixup_after_fork (HANDLE);
bool hit_eof (); bool hit_eof ();
friend int make_pipe (int fildes[2], unsigned int psize, int mode); friend int make_pipe (int fildes[2], unsigned int psize, int mode);
HANDLE get_guard () const {return guard;}
}; };
class fhandler_dev_raw: public fhandler_base class fhandler_dev_raw: public fhandler_base
@ -607,7 +607,6 @@ public:
select_record *select_read (select_record *s); select_record *select_read (select_record *s);
select_record *select_write (select_record *s); select_record *select_write (select_record *s);
select_record *select_except (select_record *s); select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
}; };
#define acquire_output_mutex(ms) \ #define acquire_output_mutex(ms) \
@ -764,7 +763,6 @@ public:
select_record *select_read (select_record *s); select_record *select_read (select_record *s);
select_record *select_write (select_record *s); select_record *select_write (select_record *s);
select_record *select_except (select_record *s); select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
void fixup_after_exec (HANDLE); void fixup_after_exec (HANDLE);
void set_close_on_exec (int val); void set_close_on_exec (int val);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
@ -806,7 +804,6 @@ public:
select_record *select_read (select_record *s); select_record *select_read (select_record *s);
select_record *select_write (select_record *s); select_record *select_write (select_record *s);
select_record *select_except (select_record *s); select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
}; };
class fhandler_tty_slave: public fhandler_tty_common class fhandler_tty_slave: public fhandler_tty_common
@ -992,7 +989,6 @@ public:
select_record *select_read (select_record *s); select_record *select_read (select_record *s);
select_record *select_write (select_record *s); select_record *select_write (select_record *s);
select_record *select_except (select_record *s); select_record *select_except (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
}; };
class fhandler_dev_dsp : public fhandler_base class fhandler_dev_dsp : public fhandler_base
@ -1055,6 +1051,7 @@ struct select_record
int (*startup) (select_record *me, class select_stuff *stuff); int (*startup) (select_record *me, class select_stuff *stuff);
int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds, int (*poll) (select_record *me, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds); fd_set *exceptfds);
int (*peek) (select_record *, int);
int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds, int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds); fd_set *exceptfds);
void (*cleanup) (select_record *me, class select_stuff *stuff); void (*cleanup) (select_record *me, class select_stuff *stuff);

View File

@ -182,7 +182,8 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
procinfo = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); procinfo = (_pinfo *) MapViewOfFile (h, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
ProtectHandle1 (h, pinfo_shared_handle); ProtectHandle1 (h, pinfo_shared_handle);
if ((procinfo->process_state & PID_INITIALIZING) && (flag & PID_NOREDIR)) if ((procinfo->process_state & PID_INITIALIZING) && (flag & PID_NOREDIR)
&& cygwin_pid (procinfo->dwProcessId) != procinfo->pid)
{ {
release (); release ();
set_errno (ENOENT); set_errno (ENOENT);

View File

@ -26,7 +26,8 @@ static unsigned pipecount;
static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u"; static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u";
fhandler_pipe::fhandler_pipe (DWORD devtype) fhandler_pipe::fhandler_pipe (DWORD devtype)
: fhandler_base (devtype), guard (0), writepipe_exists(0), orig_pid (0), id (0) : fhandler_base (devtype), guard (NULL), writepipe_exists(0),
orig_pid (0), id (0)
{ {
} }

View File

@ -84,24 +84,6 @@ typedef long fd_mask;
#define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n))) #define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n)))
#define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n)); #define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
/* Make a fhandler_foo::ready_for_ready method.
Assumption: The "ready_for_read" methods are called with one level of
signal blocking. */
#define MAKEready(what) \
int \
fhandler_##what::ready_for_read (int fd, DWORD howlong, int ignra) \
{ \
select_record me (this); \
me.fd = fd; \
while (select_read (&me) && !me.read_ready && \
!peek_##what (&me, ignra) && howlong == INFINITE) \
if (fd >= 0 && cygheap->fdtab.not_open (fd)) \
break; \
else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) \
break; \
return me.read_ready; \
}
#define set_handle_or_return_if_not_open(h, s) \ #define set_handle_or_return_if_not_open(h, s) \
h = (s)->fh->get_handle (); \ h = (s)->fh->get_handle (); \
if (cygheap->fdtab.not_open ((s)->fd)) \ if (cygheap->fdtab.not_open ((s)->fd)) \
@ -400,13 +382,14 @@ no_verify (select_record *, fd_set *, fd_set *, fd_set *)
} }
static int static int
peek_pipe (select_record *s, int ignra, HANDLE guard_mutex = NULL) peek_pipe (select_record *s, int ignra)
{ {
int n = 0; int n = 0;
int gotone = 0; int gotone = 0;
fhandler_base *fh = s->fh; fhandler_base *fh = s->fh;
HANDLE h; HANDLE h;
HANDLE guard_mutex = s->fh->get_guard ();
set_handle_or_return_if_not_open (h, s); set_handle_or_return_if_not_open (h, s);
/* Don't perform complicated tests if we don't need to. */ /* Don't perform complicated tests if we don't need to. */
@ -499,21 +482,6 @@ poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds,
0; 0;
} }
int
fhandler_pipe::ready_for_read (int fd, DWORD howlong, int ignra)
{
select_record me (this);
me.fd = fd;
(void) select_read (&me);
while (!peek_pipe (&me, ignra, guard) && howlong == INFINITE)
if (fd >= 0 && cygheap->fdtab.not_open (fd))
break;
else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
break;
select_printf ("returning %d", me.read_ready);
return me.read_ready;
}
static int start_thread_pipe (select_record *me, select_stuff *stuff); static int start_thread_pipe (select_record *me, select_stuff *stuff);
struct pipeinf struct pipeinf
@ -596,6 +564,7 @@ fhandler_pipe::select_read (select_record *s)
s = new select_record; s = new select_record;
s->startup = start_thread_pipe; s->startup = start_thread_pipe;
s->poll = poll_pipe; s->poll = poll_pipe;
s->peek = peek_pipe;
s->verify = verify_ok; s->verify = verify_ok;
s->read_selected = TRUE; s->read_selected = TRUE;
s->cleanup = pipe_cleanup; s->cleanup = pipe_cleanup;
@ -693,8 +662,6 @@ poll_console (select_record *me, fd_set *readfds, fd_set *writefds,
0; 0;
} }
MAKEready (console)
select_record * select_record *
fhandler_console::select_read (select_record *s) fhandler_console::select_read (select_record *s)
{ {
@ -707,6 +674,7 @@ fhandler_console::select_read (select_record *s)
set_cursor_maybe (); set_cursor_maybe ();
} }
s->peek = peek_console;
s->h = get_handle (); s->h = get_handle ();
s->read_selected = TRUE; s->read_selected = TRUE;
return s; return s;
@ -745,21 +713,6 @@ fhandler_console::select_except (select_record *s)
return s; return s;
} }
int
fhandler_tty_common::ready_for_read (int fd, DWORD howlong, int ignra)
{
select_record me (this);
me.fd = fd;
(void) select_read (&me);
while (!peek_pipe (&me, ignra) && howlong == INFINITE)
if (fd >= 0 && cygheap->fdtab.not_open (fd))
break;
else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
break;
select_printf ("returning %d", me.read_ready);
return me.read_ready;
}
select_record * select_record *
fhandler_tty_common::select_read (select_record *s) fhandler_tty_common::select_read (select_record *s)
{ {
@ -795,6 +748,7 @@ fhandler_tty_slave::select_read (select_record *s)
s->h = input_available_event; s->h = input_available_event;
s->startup = no_startup; s->startup = no_startup;
s->poll = poll_pipe; s->poll = poll_pipe;
s->peek = peek_pipe;
s->verify = verify_tty_slave; s->verify = verify_tty_slave;
s->read_selected = TRUE; s->read_selected = TRUE;
s->cleanup = NULL; s->cleanup = NULL;
@ -805,6 +759,11 @@ int
fhandler_tty_slave::ready_for_read (int fd, DWORD howlong, int ignra) fhandler_tty_slave::ready_for_read (int fd, DWORD howlong, int ignra)
{ {
HANDLE w4[2]; HANDLE w4[2];
if (!cygheap->fdtab.not_open (fd))
{
set_errno (EBADF);
return 1;
}
if (!ignra && get_readahead_valid ()) if (!ignra && get_readahead_valid ())
{ {
select_printf ("readahead"); select_printf ("readahead");
@ -814,13 +773,18 @@ fhandler_tty_slave::ready_for_read (int fd, DWORD howlong, int ignra)
w4[1] = input_available_event; w4[1] = input_available_event;
switch (WaitForMultipleObjects (2, w4, FALSE, howlong)) switch (WaitForMultipleObjects (2, w4, FALSE, howlong))
{ {
case WAIT_OBJECT_0:
set_errno (EINTR);
return 0;
case WAIT_OBJECT_0 + 1: case WAIT_OBJECT_0 + 1:
return 1; return 1;
case WAIT_FAILED: case WAIT_FAILED:
select_printf ("wait failed %E"); select_printf ("wait failed %E");
case WAIT_OBJECT_0: set_errno (EINVAL); /* FIXME: correct errno? */
case WAIT_TIMEOUT: return 0;
default: default:
if (!howlong)
set_errno (EAGAIN);
return 0; return 0;
} }
} }
@ -1058,8 +1022,6 @@ poll_serial (select_record *me, fd_set *readfds, fd_set *writefds,
0; 0;
} }
MAKEready (serial)
select_record * select_record *
fhandler_serial::select_read (select_record *s) fhandler_serial::select_read (select_record *s)
{ {
@ -1071,6 +1033,7 @@ fhandler_serial::select_read (select_record *s)
s->verify = verify_ok; s->verify = verify_ok;
s->cleanup = serial_cleanup; s->cleanup = serial_cleanup;
} }
s->peek = peek_serial;
s->read_selected = TRUE; s->read_selected = TRUE;
return s; return s;
} }
@ -1107,9 +1070,40 @@ fhandler_serial::select_except (select_record *s)
} }
int int
fhandler_base::ready_for_read (int, DWORD, int) fhandler_base::ready_for_read (int fd, DWORD howlong, int ignra)
{ {
return 1; int avail = 0;
select_record me (this);
me.fd = fd;
while (!avail)
{
(void) select_read (&me);
avail = me.read_ready ?: me.peek (&me, ignra);
if (fd >= 0 && cygheap->fdtab.not_open (fd))
{
set_errno (EBADF);
avail = 0;
break;
}
if (howlong != INFINITE)
{
if (!avail)
set_errno (EAGAIN);
break;
}
if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0)
{
set_errno (EINTR);
avail = 0;
break;
}
}
select_printf ("read_ready %d, avail %d", me.read_ready, avail);
return avail;
} }
select_record * select_record *
@ -1226,8 +1220,6 @@ poll_socket (select_record *me, fd_set *readfds, fd_set *writefds,
0; 0;
} }
MAKEready (socket)
static int start_thread_socket (select_record *, select_stuff *); static int start_thread_socket (select_record *, select_stuff *);
static DWORD WINAPI static DWORD WINAPI
@ -1406,6 +1398,7 @@ fhandler_socket::select_read (select_record *s)
s->verify = verify_true; s->verify = verify_true;
s->cleanup = socket_cleanup; s->cleanup = socket_cleanup;
} }
s->peek = peek_socket;
s->read_ready = saw_shutdown_read (); s->read_ready = saw_shutdown_read ();
s->read_selected = TRUE; s->read_selected = TRUE;
return s; return s;
@ -1475,8 +1468,6 @@ poll_windows (select_record *me, fd_set *readfds, fd_set *writefds,
0; 0;
} }
MAKEready (windows)
select_record * select_record *
fhandler_windows::select_read (select_record *s) fhandler_windows::select_read (select_record *s)
{ {
@ -1487,6 +1478,7 @@ fhandler_windows::select_read (select_record *s)
s->poll = poll_windows; s->poll = poll_windows;
s->verify = poll_windows; s->verify = poll_windows;
} }
s->peek = peek_windows;
s->h = get_handle (); s->h = get_handle ();
s->read_selected = TRUE; s->read_selected = TRUE;
s->h = get_handle (); s->h = get_handle ();

View File

@ -899,7 +899,7 @@ getsem (_pinfo *p, const char *str, int init, int max)
set_errno (ESRCH); set_errno (ESRCH);
return NULL; return NULL;
} }
int wait = 10000; int wait = 1000;
sigproc_printf ("pid %d, ppid %d, wait %d, initializing %x", p->pid, p->ppid, wait, sigproc_printf ("pid %d, ppid %d, wait %d, initializing %x", p->pid, p->ppid, wait,
ISSTATE (p, PID_INITIALIZING)); ISSTATE (p, PID_INITIALIZING));
for (int i = 0; ISSTATE (p, PID_INITIALIZING) && i < wait; i++) for (int i = 0; ISSTATE (p, PID_INITIALIZING) && i < wait; i++)

View File

@ -314,10 +314,6 @@ _read (int fd, void *ptr, size_t len)
debug_printf ("non-interruptible read\n"); debug_printf ("non-interruptible read\n");
else if (!cfd->ready_for_read (fd, wait, 0)) else if (!cfd->ready_for_read (fd, wait, 0))
{ {
if (!wait)
set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */
else
set_sig_errno (EINTR);
res = -1; res = -1;
goto out; goto out;
} }