From 8bce0d723c50924b908dca1467037c8008e872be Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 14 Dec 2002 04:01:32 +0000 Subject: Throughout, change fhandler_*::read and fhandler_*::raw_read to void functions whose second arguments are both the lenght and the return value. * fhandler.cc (fhandler_base::read): Rework slightly to use second argument as input/output. Tweak CRLF stuff. (fhandler_base::readv): Accommodate fhandler_*::read changes. * cygthread.h (cygthread::detach): Declare as taking optional handle argument. (cygthread::detach): When given a handle argument, wait for the handle to be signalled before waiting for thread to detach. Return true when signal detected. --- winsup/cygwin/ChangeLog | 14 ++++ winsup/cygwin/cygthread.cc | 20 ++++-- winsup/cygwin/cygthread.h | 2 +- winsup/cygwin/fhandler.cc | 124 +++++++++++++++++++++--------------- winsup/cygwin/fhandler.h | 32 +++++----- winsup/cygwin/fhandler_clipboard.cc | 39 ++++++------ winsup/cygwin/fhandler_console.cc | 31 ++++++--- winsup/cygwin/fhandler_dsp.cc | 6 +- winsup/cygwin/fhandler_floppy.cc | 5 +- winsup/cygwin/fhandler_mem.cc | 20 ++++-- winsup/cygwin/fhandler_random.cc | 20 ++++-- winsup/cygwin/fhandler_raw.cc | 26 +++++--- winsup/cygwin/fhandler_serial.cc | 6 +- winsup/cygwin/fhandler_socket.cc | 11 ++-- winsup/cygwin/fhandler_tty.cc | 24 ++++--- winsup/cygwin/fhandler_virtual.cc | 28 ++++---- winsup/cygwin/fhandler_windows.cc | 21 +++--- winsup/cygwin/fhandler_zero.cc | 6 +- winsup/cygwin/pipe.cc | 49 ++++++++++---- 19 files changed, 295 insertions(+), 189 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 18ac5ab..e107aae 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2002-12-13 Christopher Faylor + + Throughout, change fhandler_*::read and fhandler_*::raw_read to void + functions whose second arguments are both the lenght and the return + value. + * fhandler.cc (fhandler_base::read): Rework slightly to use second + argument as input/output. Tweak CRLF stuff. + (fhandler_base::readv): Accommodate fhandler_*::read changes. + * cygthread.h (cygthread::detach): Declare as taking optional handle + argument. + (cygthread::detach): When given a handle argument, wait for the handle + to be signalled before waiting for thread to detach. Return true when + signal detected. + 2002-12-12 Corinna Vinschen * Makefile.in: Add MINGW_LDFLAGS when linking cygrun.exe. diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 0c591d0..48f6c5b 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -268,9 +268,10 @@ cygthread::terminate_thread () theory is that cygthreads are only associated with one thread. So, there should be no problems with multiple threads doing waits on the one cygthread. */ -void -cygthread::detach (bool wait_for_sig) +bool +cygthread::detach (HANDLE sigwait) { + bool signalled = false; if (avail) system_printf ("called detach on available thread %d?", avail); else @@ -278,24 +279,32 @@ cygthread::detach (bool wait_for_sig) DWORD avail = id; DWORD res; - if (!wait_for_sig) + if (!sigwait) res = WaitForSingleObject (*this, INFINITE); else { HANDLE w4[2]; w4[0] = signal_arrived; w4[1] = *this; + res = WaitForSingleObject (sigwait, INFINITE); + if (res != WAIT_OBJECT_0) + system_printf ("WFSO sigwait failed, res %u", res); res = WaitForMultipleObjects (2, w4, FALSE, INFINITE); - if (res == WAIT_OBJECT_0) + if (res != WAIT_OBJECT_0) + /* nothing */; + else if (WaitForSingleObject (sigwait, 5) == WAIT_OBJECT_0) + res = WaitForSingleObject (*this, INFINITE); + else { terminate_thread (); set_errno (EINTR); /* caller should be dealing with return values. */ avail = 0; + signalled = true; } } - thread_printf ("%s returns %d, id %p", wait_for_sig ? "WFMO" : "WFSO", + thread_printf ("%s returns %d, id %p", sigwait ? "WFMO" : "WFSO", res, id); if (!avail) @@ -312,6 +321,7 @@ cygthread::detach (bool wait_for_sig) (void) InterlockedExchange ((LPLONG) &this->avail, avail); } } + return signalled; } void diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index 479a068..b0c07af 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -27,7 +27,7 @@ class cygthread cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); cygthread () {}; static void init (); - void detach (bool = false); + bool detach (HANDLE = NULL); operator HANDLE (); static bool is (); void * operator new (size_t); diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index ffb67b6..b1b53e3 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -249,18 +249,23 @@ fhandler_base::set_flags (int flags, int supplied_bin) /* Cover function to ReadFile to achieve (as much as possible) Posix style semantics and use of errno. */ -int -fhandler_base::raw_read (void *ptr, size_t ulen) +void +fhandler_base::raw_read (void *ptr, size_t& ulen) { - DWORD bytes_read; - - if (!ReadFile (get_handle (), ptr, ulen, &bytes_read, 0)) +#define bytes_read ((ssize_t) ulen) + + DWORD len = ulen; + (ssize_t) ulen = -1; + if (read_state) + SetEvent (read_state); + BOOL res = ReadFile (get_handle (), ptr, len, (DWORD *) &ulen, 0); + if (read_state) + SetEvent (read_state); + if (!res) { - int errcode; - /* Some errors are not really errors. Detect such cases here. */ - errcode = GetLastError (); + DWORD errcode = GetLastError (); switch (errcode) { case ERROR_BROKEN_PIPE: @@ -272,24 +277,27 @@ fhandler_base::raw_read (void *ptr, size_t ulen) break; case ERROR_NOACCESS: if (is_at_eof (get_handle (), errcode)) - return 0; + { + bytes_read = 0; + break; + } case ERROR_INVALID_FUNCTION: case ERROR_INVALID_PARAMETER: case ERROR_INVALID_HANDLE: if (openflags & O_DIROPEN) { set_errno (EISDIR); - return -1; + bytes_read = -1; + break; } default: syscall_printf ("ReadFile %s failed, %E", unix_path_name); __seterrno_from_win_error (errcode); - return -1; + bytes_read = -1; break; } } - - return bytes_read; +#undef bytes_read } /* Cover function to WriteFile to provide Posix interface and semantics @@ -486,14 +494,13 @@ done: an \n. If last char is an \r, look ahead one more char, if \n then modify \r, if not, remember char. */ -int -fhandler_base::read (void *in_ptr, size_t in_len) +void +fhandler_base::read (void *in_ptr, size_t& len) { - int len = (int) in_len; + size_t in_len = len; char *ptr = (char *) in_ptr; - + ssize_t copied_chars = 0; int c; - int copied_chars = 0; while (len) if ((c = get_readahead ()) < 0) @@ -505,23 +512,31 @@ fhandler_base::read (void *in_ptr, size_t in_len) } if (copied_chars && is_slow ()) - return copied_chars; + { + len = (size_t) copied_chars; + return; + } if (len) { - int readlen = raw_read (ptr + copied_chars, len); - if (copied_chars == 0) - copied_chars = readlen; /* Propagate error or EOF */ - else if (readlen > 0) /* FIXME: should flag EOF for next read */ - copied_chars += readlen; + raw_read (ptr + copied_chars, len); + if (!copied_chars) + /* nothing */; + else if ((ssize_t) len > 0) + len += copied_chars; + else + len = copied_chars; + } + else if (copied_chars <= 0) + { + len = (size_t) copied_chars; + return; } - if (copied_chars <= 0) - return copied_chars; if (get_r_binary ()) { - debug_printf ("returning %d chars, binary mode", copied_chars); - return copied_chars; + debug_printf ("returning %d chars, binary mode", len); + return; } #if 0 @@ -543,35 +558,37 @@ fhandler_base::read (void *in_ptr, size_t in_len) #endif /* Scan buffer and turn \r\n into \n */ - register char *src = (char *) ptr; - register char *dst = (char *) ptr; - register char *end = src + copied_chars - 1; + char *src = (char *) ptr; + char *dst = (char *) ptr; + char *end = src + len - 1; /* Read up to the last but one char - the last char needs special handling */ while (src < end) { - *dst = *src++; - if (*dst != '\r' || *src != '\n') - dst++; + if (*src == '\r' && src[1] == '\n') + src++; + *dst++ = *src++; } - c = *src; + len = dst - (char *) ptr; + /* if last char is a '\r' then read one more to see if we should translate this one too */ - if (c == '\r') + if (len < in_len && *src == '\r') { - char c1 = 0; - len = raw_read (&c1, 1); - if (len <= 0) + size_t clen = 1; + raw_read (&c, clen); + if (clen <= 0) /* nothing */; - else if (c1 == '\n') - c = '\n'; + else if (c != '\n') + set_readahead_valid (1, c); else - set_readahead_valid (1, c1); + { + *dst++ = '\n'; + len++; + } } - *dst++ = c; - copied_chars = dst - (char *) ptr; #ifndef NOSTRACE if (strace.active) @@ -591,8 +608,8 @@ fhandler_base::read (void *in_ptr, size_t in_len) } #endif - debug_printf ("returning %d chars, text mode", copied_chars); - return copied_chars; + debug_printf ("returning %d chars, text mode", len); + return; } int @@ -717,7 +734,11 @@ fhandler_base::readv (const struct iovec *const iov, const int iovcnt, assert (iovcnt >= 1); if (iovcnt == 1) - return read (iov->iov_base, iov->iov_len); + { + size_t len = iov->iov_len; + read (iov->iov_base, len); + return len; + } if (tot == -1) // i.e. if not pre-calculated by the caller. { @@ -744,10 +765,10 @@ fhandler_base::readv (const struct iovec *const iov, const int iovcnt, return -1; } - const ssize_t res = read (buf, tot); + read (buf, (size_t) tot); const struct iovec *iovptr = iov; - int nbytes = res; + int nbytes = tot; while (nbytes > 0) { @@ -758,7 +779,7 @@ fhandler_base::readv (const struct iovec *const iov, const int iovcnt, nbytes -= frag; } - return res; + return tot; } ssize_t @@ -1150,7 +1171,8 @@ fhandler_base::fhandler_base (DWORD devtype, int unit): rabuflen (0), unix_path_name (NULL), win32_path_name (NULL), - open_status (0) + open_status (0), + read_state (NULL) { } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 56be17b..0e7b027 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -166,6 +166,7 @@ class fhandler_base const char *unix_path_name; const char *win32_path_name; DWORD open_status; + HANDLE read_state; public: void set_name (const char * unix_path, const char *win32_path = NULL, int unit = 0); @@ -304,7 +305,7 @@ class fhandler_base virtual int ioctl (unsigned int cmd, void *); virtual int fcntl (int cmd, void *); virtual char const * ttyname () { return get_name(); } - virtual int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + virtual void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); virtual int write (const void *ptr, size_t len); virtual ssize_t readv (const struct iovec *, int iovcnt, ssize_t tot = -1); virtual ssize_t writev (const struct iovec *, int iovcnt, ssize_t tot = -1); @@ -339,7 +340,7 @@ class fhandler_base virtual class fhandler_console *is_console () { return 0; } virtual int is_windows () {return 0; } - virtual int raw_read (void *ptr, size_t ulen); + virtual void raw_read (void *ptr, size_t& ulen); virtual int raw_write (const void *ptr, size_t ulen); /* Virtual accessor functions to hide the fact @@ -463,12 +464,13 @@ class fhandler_pipe: public fhandler_base select_record *select_write (select_record *s); select_record *select_except (select_record *s); void set_close_on_exec (int val); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); int close (); void create_guard (SECURITY_ATTRIBUTES *sa) {guard = CreateMutex (sa, FALSE, NULL);} int dup (fhandler_base *child); int ioctl (unsigned int cmd, void *); void fixup_after_fork (HANDLE); + void fixup_after_exec (HANDLE); bool hit_eof (); void set_eof () {broken_pipe = true;} friend int make_pipe (int fildes[2], unsigned int psize, int mode); @@ -509,7 +511,7 @@ class fhandler_dev_raw: public fhandler_base int open (path_conv *, int flags, mode_t mode = 0); int close (void); - int raw_read (void *ptr, size_t ulen); + void raw_read (void *ptr, size_t& ulen); int raw_write (const void *ptr, size_t ulen); int dup (fhandler_base *child); @@ -655,7 +657,7 @@ class fhandler_serial: public fhandler_base void init (HANDLE h, DWORD a, mode_t flags); void overlapped_setup (); int dup (fhandler_base *child); - int raw_read (void *ptr, size_t ulen); + void raw_read (void *ptr, size_t& ulen); int raw_write (const void *ptr, size_t ulen); int tcsendbreak (int); int tcdrain (); @@ -823,7 +825,7 @@ class fhandler_console: public fhandler_termios int write (const void *ptr, size_t len); void doecho (const void *str, DWORD len) { (void) write (str, len); } - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); int close (); int tcflush (int); @@ -894,7 +896,7 @@ class fhandler_tty_slave: public fhandler_tty_common int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); void init (HANDLE, DWORD, mode_t); int tcsetattr (int a, const struct termios *t); @@ -921,7 +923,7 @@ class fhandler_pty_master: public fhandler_tty_common int accept_input (); int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); int close (); int tcsetattr (int a, const struct termios *t); @@ -966,7 +968,7 @@ class fhandler_dev_zero: public fhandler_base fhandler_dev_zero (); int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); __off64_t lseek (__off64_t offset, int whence); void dump (); @@ -988,7 +990,7 @@ class fhandler_dev_random: public fhandler_base int get_unit () { return unit; } int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); __off64_t lseek (__off64_t offset, int whence); int close (void); int dup (fhandler_base *child); @@ -1009,7 +1011,7 @@ class fhandler_dev_mem: public fhandler_base int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t ulen); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); __off64_t lseek (__off64_t offset, int whence); int close (void); int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3))); @@ -1031,7 +1033,7 @@ class fhandler_dev_clipboard: public fhandler_base int is_windows (void) { return 1; } int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); __off64_t lseek (__off64_t offset, int whence); int close (void); @@ -1056,7 +1058,7 @@ class fhandler_windows: public fhandler_base int is_windows (void) { return 1; } int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); int ioctl (unsigned int cmd, void *); __off64_t lseek (__off64_t, int) { return 0; } int close (void) { return 0; } @@ -1082,7 +1084,7 @@ class fhandler_dev_dsp : public fhandler_base int open (path_conv *, int flags, mode_t mode = 0); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); int ioctl (unsigned int cmd, void *); __off64_t lseek (__off64_t, int); int close (void); @@ -1110,7 +1112,7 @@ class fhandler_virtual : public fhandler_base void rewinddir (DIR *); int closedir (DIR *); int write (const void *ptr, size_t len); - int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3))); + void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3))); __off64_t lseek (__off64_t, int); int dup (fhandler_base * child); int open (path_conv *, int flags, mode_t mode = 0); diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index aeb5933..9cf1b28 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -185,19 +185,30 @@ fhandler_dev_clipboard::write (const void *buf, size_t len) } } -int __stdcall -fhandler_dev_clipboard::read (void *ptr, size_t len) +void __stdcall +fhandler_dev_clipboard::read (void *ptr, size_t& len) { HGLOBAL hglb; size_t ret; UINT formatlist[2]; UINT format; - if (!eof) + if (eof) + len = 0; + else { formatlist[0] = cygnativeformat; formatlist[1] = current_codepage == ansi_cp ? CF_TEXT : CF_OEMTEXT; OpenClipboard (0); - if ((format = GetPriorityClipboardFormat (formatlist, 2)) > 0) + if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0) + { + CloseClipboard (); +#if 0 + system_printf ("a non-accepted format! %d", format); +#endif + set_errno (0); + len = 0; + } + else { hglb = GetClipboardData (format); if (format == cygnativeformat) @@ -216,9 +227,8 @@ fhandler_dev_clipboard::read (void *ptr, size_t len) LPSTR lpstr; lpstr = (LPSTR) GlobalLock (hglb); - ret = - ((len > (strlen (lpstr) - pos)) ? (strlen (lpstr) - pos) : - len); + ret = ((len > (strlen (lpstr) - pos)) ? (strlen (lpstr) - pos) + : len); memcpy (ptr, lpstr + pos, ret); //ret = snprintf((char *) ptr, len, "%s", lpstr);//+pos); @@ -229,22 +239,9 @@ fhandler_dev_clipboard::read (void *ptr, size_t len) } CloseClipboard (); set_errno (0); - return ret; - } - else - { - CloseClipboard (); -#if 0 - system_printf ("a non-accepted format! %d", format); -#endif - set_errno (0); - return 0; + len = ret; } } - else - { - return 0; - } } __off64_t diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index a7b13c6..96ef428 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -216,8 +216,8 @@ fhandler_console::send_winch_maybe () tc->kill_pgrp (SIGWINCH); } -int __stdcall -fhandler_console::read (void *pv, size_t buflen) +void __stdcall +fhandler_console::read (void *pv, size_t& buflen) { HANDLE h = get_io_handle (); @@ -229,7 +229,10 @@ fhandler_console::read (void *pv, size_t buflen) int copied_chars = get_readahead_into_buffer (buf, buflen); if (copied_chars) - return copied_chars; + { + buflen = copied_chars; + return; + } HANDLE w4[2]; DWORD nwait; @@ -248,7 +251,10 @@ fhandler_console::read (void *pv, size_t buflen) { int bgres; if ((bgres = bg_check (SIGTTIN)) <= bg_eof) - return bgres; + { + buflen = bgres; + return; + } set_cursor_maybe (); /* to make cursor appear on the screen immediately */ switch (WaitForMultipleObjects (nwait, w4, FALSE, INFINITE)) @@ -258,8 +264,7 @@ fhandler_console::read (void *pv, size_t buflen) case WAIT_OBJECT_0 + 1: goto sig_exit; default: - __seterrno (); - return -1; + goto err; } DWORD nread; @@ -268,9 +273,8 @@ fhandler_console::read (void *pv, size_t buflen) if (!ReadConsoleInput (h, &input_rec, 1, &nread)) { - __seterrno (); syscall_printf ("ReadConsoleInput failed, %E"); - return -1; /* seems to be failure */ + goto err; /* seems to be failure */ } /* check the event that occurred */ @@ -476,11 +480,18 @@ fhandler_console::read (void *pv, size_t buflen) } #undef buf - return copied_chars; + buflen = copied_chars; + return; + +err: + __seterrno (); + (ssize_t) buflen = -1; + return; sig_exit: set_sig_errno (EINTR); - return -1; + (ssize_t) buflen = -1; + return; } void diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc index 063e791..5c7f42a 100644 --- a/winsup/cygwin/fhandler_dsp.cc +++ b/winsup/cygwin/fhandler_dsp.cc @@ -481,10 +481,10 @@ fhandler_dev_dsp::write (const void *ptr, size_t len) return len; } -int __stdcall -fhandler_dev_dsp::read (void *ptr, size_t len) +void __stdcall +fhandler_dev_dsp::read (void *ptr, size_t& len) { - return len; + return; } __off64_t diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc index c1df34a..fe33831 100644 --- a/winsup/cygwin/fhandler_floppy.cc +++ b/winsup/cygwin/fhandler_floppy.cc @@ -179,7 +179,10 @@ fhandler_dev_floppy::lseek (__off64_t offset, int whence) __seterrno (); return -1; } - return sector_aligned_offset + raw_read (buf, bytes_left); + + size_t len = bytes_left; + raw_read (buf, len); + return sector_aligned_offset + bytes_left; } set_errno (EINVAL); diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc index 177e645..089b56b 100644 --- a/winsup/cygwin/fhandler_mem.cc +++ b/winsup/cygwin/fhandler_mem.cc @@ -176,16 +176,20 @@ fhandler_dev_mem::write (const void *ptr, size_t ulen) return ulen; } -int __stdcall -fhandler_dev_mem::read (void *ptr, size_t ulen) +void __stdcall +fhandler_dev_mem::read (void *ptr, size_t& ulen) { if (!ulen || pos >= mem_size) - return 0; + { + ulen = 0; + return; + } if (!(get_access () & GENERIC_READ)) { set_errno (EINVAL); - return -1; + (ssize_t) ulen = -1; + return; } if (pos + ulen > mem_size) @@ -209,7 +213,8 @@ fhandler_dev_mem::read (void *ptr, size_t ulen) PAGE_READONLY)) != STATUS_SUCCESS) { __seterrno_from_win_error (RtlNtStatusToDosError (ret)); - return -1; + (ssize_t) ulen = -1; + return; } memcpy (ptr, (char *) viewmem + (pos - phys.QuadPart), ulen); @@ -217,11 +222,12 @@ fhandler_dev_mem::read (void *ptr, size_t ulen) if (!NT_SUCCESS (ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem))) { __seterrno_from_win_error (RtlNtStatusToDosError (ret)); - return -1; + (ssize_t) ulen = -1; + return; } pos += ulen; - return ulen; + return; } int diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc index 2447b4e..6d02db5 100644 --- a/winsup/cygwin/fhandler_random.cc +++ b/winsup/cygwin/fhandler_random.cc @@ -110,27 +110,33 @@ fhandler_dev_random::pseudo_read (void *ptr, size_t len) return len; } -int __stdcall -fhandler_dev_random::read (void *ptr, size_t len) +void __stdcall +fhandler_dev_random::read (void *ptr, size_t& len) { if (!len) - return 0; + return; + if (!ptr) { set_errno (EINVAL); - return -1; + (ssize_t) len = -1; + return; } if (crypt_gen_random (ptr, len)) - return len; + return; + /* If device is /dev/urandom, use pseudo number generator as fallback. Don't do this for /dev/random since it's intended for uses that need very high quality randomness. */ if (unit == URANDOM) - return pseudo_read (ptr, len); + { + len = pseudo_read (ptr, len); + return; + } __seterrno (); - return -1; + (ssize_t) len = -1; } __off64_t diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index 2b8470a..45ce414 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -189,8 +189,8 @@ fhandler_dev_raw::close (void) return fhandler_base::close (); } -int -fhandler_dev_raw::raw_read (void *ptr, size_t ulen) +void +fhandler_dev_raw::raw_read (void *ptr, size_t& ulen) { DWORD bytes_read = 0; DWORD read2; @@ -204,21 +204,22 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) if (ret) { set_errno (is_eom (ret) ? ENOSPC : EACCES); - return -1; + goto err; } /* Checking a previous end of file */ if (eof_detected && !lastblk_to_read) { eof_detected = 0; - return 0; + ulen = 0; + return; } /* Checking a previous end of media */ if (eom_detected && !lastblk_to_read) { set_errno (ENOSPC); - return -1; + goto err; } if (devbuf) @@ -269,7 +270,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { debug_printf ("return -1, set errno to EACCES"); set_errno (EACCES); - return -1; + goto err; } if (is_eof (ret)) @@ -283,7 +284,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { debug_printf ("return -1, set errno to ENOSPC"); set_errno (ENOSPC); - return -1; + goto err; } break; } @@ -311,7 +312,7 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { debug_printf ("return -1, set errno to EACCES"); set_errno (EACCES); - return -1; + goto err; } if (bytes_read) { @@ -324,11 +325,16 @@ fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { debug_printf ("return -1, set errno to ENOSPC"); set_errno (ENOSPC); - return -1; + goto err; } } - return bytes_read; + (ssize_t) ulen = bytes_read; + return; + +err: + (ssize_t) ulen = -1; + return; } int diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc index a267644..7081db3 100644 --- a/winsup/cygwin/fhandler_serial.cc +++ b/winsup/cygwin/fhandler_serial.cc @@ -38,8 +38,8 @@ fhandler_serial::overlapped_setup () overlapped_armed = 0; } -int -fhandler_serial::raw_read (void *ptr, size_t ulen) +void +fhandler_serial::raw_read (void *ptr, size_t& ulen) { int tot; DWORD n; @@ -146,7 +146,7 @@ fhandler_serial::raw_read (void *ptr, size_t ulen) } out: - return tot; + ulen = tot; } /* Cover function to WriteFile to provide Posix interface and semantics diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index fa44f2e..33e7954 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -124,10 +124,13 @@ fhandler_socket::set_connect_secret () delete entropy_source; entropy_source = NULL; } - if (!entropy_source || - (entropy_source->read (connect_secret, sizeof (connect_secret)) != - sizeof (connect_secret))) - bzero ((char*) connect_secret, sizeof (connect_secret)); + if (!entropy_source) + { + size_t len = sizeof (connect_secret); + entropy_source->read (connect_secret, len); + if (len != sizeof (connect_secret)) + bzero ((char*) connect_secret, sizeof (connect_secret)); + } } void diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 3b47f56..60918f6 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -199,8 +199,8 @@ process_input (void *) while (1) { - int nraw = tty_master->console->read ((void *) rawbuf, - (size_t) INP_BUFFER_SIZE); + size_t nraw = INP_BUFFER_SIZE; + tty_master->console->read ((void *) rawbuf, nraw); (void) tty_master->line_edit (rawbuf, nraw); } } @@ -634,8 +634,8 @@ fhandler_tty_slave::write (const void *ptr, size_t len) return towrite; } -int __stdcall -fhandler_tty_slave::read (void *ptr, size_t len) +void __stdcall +fhandler_tty_slave::read (void *ptr, size_t& len) { int totalread = 0; int vmin = 0; @@ -692,7 +692,8 @@ fhandler_tty_slave::read (void *ptr, size_t len) if (totalread > 0) break; set_sig_errno (EINTR); - return -1; + (ssize_t) len = -1; + return; } rc = WaitForSingleObject (input_mutex, 1000); @@ -716,7 +717,8 @@ fhandler_tty_slave::read (void *ptr, size_t len) if (!vmin && !time_to_wait) { ReleaseMutex (input_mutex); - return bytes_in_pipe; + (ssize_t) len = bytes_in_pipe; + return; } readlen = min (bytes_in_pipe, min (len, sizeof (buf))); @@ -795,7 +797,8 @@ fhandler_tty_slave::read (void *ptr, size_t len) waiter = time_to_wait; } termios_printf ("%d=read(%x, %d)", totalread, ptr, len); - return totalread; + (ssize_t) len = totalread; + return; } int @@ -1085,10 +1088,11 @@ fhandler_pty_master::write (const void *ptr, size_t len) return i; } -int __stdcall -fhandler_pty_master::read (void *ptr, size_t len) +void __stdcall +fhandler_pty_master::read (void *ptr, size_t& len) { - return process_slave_output ((char *) ptr, len, pktmode); + (ssize_t) len = process_slave_output ((char *) ptr, len, pktmode); + return; } int diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index 937caf3..4316efa 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -170,27 +170,29 @@ fhandler_virtual::close () return 0; } -int -fhandler_virtual::read (void *ptr, size_t len) +void +fhandler_virtual::read (void *ptr, size_t& len) { if (len == 0) - return 0; + return; if (openflags & O_DIROPEN) { set_errno (EISDIR); - return -1; + (ssize_t) len = -1; + return; } if (!filebuf) - return 0; - int read = len; - if (read > filesize - position) - read = filesize - position; - if (read < 0) - read = 0; + { + (ssize_t) len = 0; + return; + } + if ((ssize_t) len > filesize - position) + (ssize_t) len = filesize - position; + if ((ssize_t) len < 0) + (ssize_t) len = 0; else - memcpy (ptr, filebuf + position, read); - position += read; - return read; + memcpy (ptr, filebuf + position, len); + position += len; } int diff --git a/winsup/cygwin/fhandler_windows.cc b/winsup/cygwin/fhandler_windows.cc index ac1fe04..d6b3059 100644 --- a/winsup/cygwin/fhandler_windows.cc +++ b/winsup/cygwin/fhandler_windows.cc @@ -79,26 +79,25 @@ fhandler_windows::write (const void *buf, size_t) return SendMessage (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam); } -int __stdcall -fhandler_windows::read (void *buf, size_t len) +void __stdcall +fhandler_windows::read (void *buf, size_t& len) { MSG *ptr = (MSG *) buf; - int ret; if (len < sizeof (MSG)) { set_errno (EINVAL); - return -1; + (ssize_t) len = -1; + return; } - ret = GetMessage (ptr, hWnd_, 0, 0); + (ssize_t) len = GetMessage (ptr, hWnd_, 0, 0); - if (ret == -1) - { - __seterrno (); - } - set_errno (0); - return ret; + if ((ssize_t) len == -1) + __seterrno (); + else + set_errno (0); + return; } int diff --git a/winsup/cygwin/fhandler_zero.cc b/winsup/cygwin/fhandler_zero.cc index 86b84fb..997abf7 100644 --- a/winsup/cygwin/fhandler_zero.cc +++ b/winsup/cygwin/fhandler_zero.cc @@ -35,11 +35,11 @@ fhandler_dev_zero::write (const void *, size_t len) return len; } -int __stdcall -fhandler_dev_zero::read (void *ptr, size_t len) +void __stdcall +fhandler_dev_zero::read (void *ptr, size_t& len) { memset (ptr, 0, len); - return len; + return; } __off64_t diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 4909372..2b711b7 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -55,32 +55,32 @@ struct pipeargs { fhandler_base *fh; void *ptr; - size_t len; - int res; + size_t *len; }; static DWORD WINAPI read_pipe (void *arg) { pipeargs *pi = (pipeargs *) arg; - pi->res = pi->fh->fhandler_base::read (pi->ptr, pi->len); + pi->fh->fhandler_base::read (pi->ptr, *pi->len); return 0; } -int __stdcall -fhandler_pipe::read (void *in_ptr, size_t in_len) +void __stdcall +fhandler_pipe::read (void *in_ptr, size_t& in_len) { if (broken_pipe) - return 0; - pipeargs pi; - pi.fh = this; - pi.ptr = in_ptr; - pi.len = in_len; - pi.res = -1; - cygthread *th = new cygthread (read_pipe, &pi, "read_pipe"); - th->detach (1); + in_len = 0; + else + { + pipeargs pi = {this, in_ptr, &in_len}; + ResetEvent (read_state); + cygthread *th = new cygthread (read_pipe, &pi, "read_pipe"); + if (th->detach (read_state) && !in_len) + (ssize_t) in_len = -1; /* received a signal */ + } (void) ReleaseMutex (guard); - return pi.res; + return; } int fhandler_pipe::close () @@ -90,6 +90,8 @@ int fhandler_pipe::close () CloseHandle (guard); if (writepipe_exists) CloseHandle (writepipe_exists); + if (read_state) + CloseHandle (read_state); return res; } @@ -110,6 +112,13 @@ fhandler_pipe::hit_eof () } void +fhandler_pipe::fixup_after_exec (HANDLE parent) +{ + if (read_state) + read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); +} + +void fhandler_pipe::fixup_after_fork (HANDLE parent) { this->fhandler_base::fixup_after_fork (parent); @@ -117,6 +126,7 @@ fhandler_pipe::fixup_after_fork (HANDLE parent) fork_fixup (parent, guard, "guard"); if (writepipe_exists) fork_fixup (parent, writepipe_exists, "guard"); + fixup_after_exec (parent); } int @@ -147,6 +157,16 @@ fhandler_pipe::dup (fhandler_base *child) return -1; } + if (read_state == NULL) + ftp->read_state = NULL; + else if (!DuplicateHandle (hMainProc, read_state, hMainProc, + &ftp->read_state, 0, 1, + DUPLICATE_SAME_ACCESS)) + { + debug_printf ("couldn't duplicate read_state %p, %E", writepipe_exists); + return -1; + } + ftp->id = id; ftp->orig_pid = orig_pid; return 0; @@ -183,6 +203,7 @@ make_pipe (int fildes[2], unsigned int psize, int mode) fildes[0] = fdr; fildes[1] = fdw; + fhr->read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); res = 0; fhr->create_guard (sa); -- cgit v1.1