Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-12-14 07:01:32 +0300
committerChristopher Faylor <me@cgf.cx>2002-12-14 07:01:32 +0300
commit8bce0d723c50924b908dca1467037c8008e872be (patch)
treedcaf982175c090c0e7668af5fa00dac09fb07b27
parentec085641a9b4d25e16df12d7449f7ad689934117 (diff)
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.
-rw-r--r--winsup/cygwin/ChangeLog14
-rw-r--r--winsup/cygwin/cygthread.cc20
-rw-r--r--winsup/cygwin/cygthread.h2
-rw-r--r--winsup/cygwin/fhandler.cc124
-rw-r--r--winsup/cygwin/fhandler.h32
-rw-r--r--winsup/cygwin/fhandler_clipboard.cc39
-rw-r--r--winsup/cygwin/fhandler_console.cc31
-rw-r--r--winsup/cygwin/fhandler_dsp.cc6
-rw-r--r--winsup/cygwin/fhandler_floppy.cc5
-rw-r--r--winsup/cygwin/fhandler_mem.cc20
-rw-r--r--winsup/cygwin/fhandler_random.cc20
-rw-r--r--winsup/cygwin/fhandler_raw.cc26
-rw-r--r--winsup/cygwin/fhandler_serial.cc6
-rw-r--r--winsup/cygwin/fhandler_socket.cc11
-rw-r--r--winsup/cygwin/fhandler_tty.cc24
-rw-r--r--winsup/cygwin/fhandler_virtual.cc28
-rw-r--r--winsup/cygwin/fhandler_windows.cc21
-rw-r--r--winsup/cygwin/fhandler_zero.cc6
-rw-r--r--winsup/cygwin/pipe.cc49
19 files changed, 295 insertions, 189 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 18ac5ab69..e107aaed1 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,17 @@
+2002-12-13 Christopher Faylor <cgf@redhat.com>
+
+ 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 <corinna@vinschen.de>
* Makefile.in: Add MINGW_LDFLAGS when linking cygrun.exe.
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index 0c591d01f..48f6c5b15 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 479a0682c..b0c07af0a 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 ffb67b6cc..b1b53e31d 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 56be17b59..0e7b02704 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 aeb5933dc..9cf1b287d 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 a7b13c6b9..96ef4284f 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 063e79126..5c7f42a0e 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 c1df34ada..fe338317b 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 177e645c0..089b56b4b 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 2447b4e78..6d02db587 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 2b8470a36..45ce414dc 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 a2676444a..7081db3d5 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 fa44f2e03..33e795458 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 3b47f567a..60918f6bd 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 937caf352..4316efa69 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 ac1fe044d..d6b3059e6 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 86b84fb30..997abf764 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 49093728c..2b711b7df 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);