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-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.
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
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)
(void) InterlockedExchange ((LPLONG) &this->avail, avail);
}
}
+ return signalled;
}
void
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);
/* 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:
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
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)
}
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
#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)
}
#endif
- debug_printf ("returning %d chars, text mode", copied_chars);
- return copied_chars;
+ debug_printf ("returning %d chars, text mode", len);
+ return;
}
int
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.
{
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)
{
nbytes -= frag;
}
- return res;
+ return tot;
}
ssize_t
rabuflen (0),
unix_path_name (NULL),
win32_path_name (NULL),
- open_status (0)
+ open_status (0),
+ read_state (NULL)
{
}
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);
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);
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
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);
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);
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 ();
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);
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);
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);
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 ();
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);
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)));
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);
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; }
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);
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);
}
}
-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)
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);
}
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
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 ();
int copied_chars = get_readahead_into_buffer (buf, buflen);
if (copied_chars)
- return copied_chars;
+ {
+ buflen = copied_chars;
+ return;
+ }
HANDLE w4[2];
DWORD nwait;
{
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))
case WAIT_OBJECT_0 + 1:
goto sig_exit;
default:
- __seterrno ();
- return -1;
+ goto err;
}
DWORD nread;
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 */
}
#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
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
__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);
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)
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);
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
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
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;
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)
{
debug_printf ("return -1, set errno to EACCES");
set_errno (EACCES);
- return -1;
+ goto err;
}
if (is_eof (ret))
{
debug_printf ("return -1, set errno to ENOSPC");
set_errno (ENOSPC);
- return -1;
+ goto err;
}
break;
}
{
debug_printf ("return -1, set errno to EACCES");
set_errno (EACCES);
- return -1;
+ goto err;
}
if (bytes_read)
{
{
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
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;
}
out:
- return tot;
+ ulen = tot;
}
/* Cover function to WriteFile to provide Posix interface and semantics
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
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);
}
}
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;
if (totalread > 0)
break;
set_sig_errno (EINTR);
- return -1;
+ (ssize_t) len = -1;
+ return;
}
rc = WaitForSingleObject (input_mutex, 1000);
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)));
waiter = time_to_wait;
}
termios_printf ("%d=read(%x, %d)", totalread, ptr, len);
- return totalread;
+ (ssize_t) len = totalread;
+ return;
}
int
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
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
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
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
{
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 ()
CloseHandle (guard);
if (writepipe_exists)
CloseHandle (writepipe_exists);
+ if (read_state)
+ CloseHandle (read_state);
return res;
}
return ev == NULL;
}
+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)
{
fork_fixup (parent, guard, "guard");
if (writepipe_exists)
fork_fixup (parent, writepipe_exists, "guard");
+ fixup_after_exec (parent);
}
int
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;
fildes[0] = fdr;
fildes[1] = fdw;
+ fhr->read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
res = 0;
fhr->create_guard (sa);