summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog15
-rw-r--r--winsup/cygwin/fhandler.h2
-rw-r--r--winsup/cygwin/fhandler_procsys.cc2
-rw-r--r--winsup/cygwin/fhandler_socket.cc16
-rw-r--r--winsup/cygwin/syscalls.cc154
5 files changed, 135 insertions, 54 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 7ef8f0101..ba024a10e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,18 @@
+2011-05-06 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (fhandler_socket::read): Declare.
+ (fhandler_socket::write): Declare.
+ * fhandler_procsys.cc (fhandler_procsys::read): Add FIXME comment.
+ (fhandler_procsys::write): Ditto.
+ * fhandler_socket.cc (fhandler_socket::read): New method.
+ (fhandler_socket::write): New method.
+ * syscalls.cc: Rearrange order of read/write functions.
+ (read): Call fhandler read method directly instead of just readv.
+ (readv): Remove EINTR loop. This is done in all affected fhandler's
+ now.
+ (write): Call fhandler write method directly instead of just writev.
+ Fix debug output.
+
2011-05-05 Christopher Faylor <me.cygwin2011@cgf.cx>
* cygheap.cc (cygheap::close_ctty): Close ctty via close_with_arch().
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 6ceaff33a..2dcbd9d8f 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -524,12 +524,14 @@ class fhandler_socket: public fhandler_base
int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid);
int open (int flags, mode_t mode = 0);
+ void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
inline ssize_t recv_internal (struct _WSAMSG *wsamsg);
ssize_t recvfrom (void *ptr, size_t len, int flags,
struct sockaddr *from, int *fromlen);
ssize_t recvmsg (struct msghdr *msg, int flags);
+ ssize_t __stdcall write (const void *ptr, size_t len);
ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags);
ssize_t sendto (const void *ptr, size_t len, int flags,
diff --git a/winsup/cygwin/fhandler_procsys.cc b/winsup/cygwin/fhandler_procsys.cc
index dc73be56c..53d68cf77 100644
--- a/winsup/cygwin/fhandler_procsys.cc
+++ b/winsup/cygwin/fhandler_procsys.cc
@@ -398,6 +398,7 @@ fhandler_procsys::read (void *ptr, size_t& len)
IO_STATUS_BLOCK io;
LARGE_INTEGER off = { QuadPart:0LL };
+ /* FIXME: Implement nonblocking I/O, interruptibility and cancelability. */
status = NtReadFile (get_handle (), NULL, NULL, NULL, &io, ptr, len,
&off, NULL);
if (!NT_SUCCESS (status))
@@ -412,6 +413,7 @@ fhandler_procsys::read (void *ptr, size_t& len)
ssize_t __stdcall
fhandler_procsys::write (const void *ptr, size_t len)
{
+ /* FIXME: Implement nonblocking I/O, interruptibility and cancelability. */
return fhandler_base::raw_write (ptr, len);
}
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 1151f89fe..d97dc4f55 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -1316,6 +1316,14 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
return res;
}
+void __stdcall
+fhandler_socket::read (void *in_ptr, size_t& len)
+{
+ WSABUF wsabuf = { len, (char *) in_ptr };
+ WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
+ len = recv_internal (&wsamsg);
+}
+
int
fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
ssize_t tot)
@@ -1531,6 +1539,14 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags)
}
int
+fhandler_socket::write (const void *ptr, size_t len)
+{
+ WSABUF wsabuf = { len, (char *) ptr };
+ WSAMSG wsamsg = { NULL, 0, &wsabuf, 1, { 0, NULL }, 0 };
+ return send_internal (&wsamsg, 0);
+}
+
+int
fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
ssize_t tot)
{
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index d122c8dc2..70eb8ea1f 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -898,36 +898,86 @@ getsid (pid_t pid)
extern "C" ssize_t
read (int fd, void *ptr, size_t len)
{
- const iovec iov =
+ pthread_testcancel ();
+
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+
+ size_t res = (size_t) -1;
+
+ cygheap_fdget cfd (fd);
+ if (cfd < 0)
+ goto done;
+
+ if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY)
{
- iov_base: ptr,
- iov_len: len
- };
+ set_errno (EBADF);
+ goto done;
+ }
- return readv (fd, &iov, 1);
+ /* Could block, so let user know we at least got here. */
+ extern int sigcatchers;
+ syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d",
+ fd, ptr, len, cfd->is_nonblocking () ? "non" : "",
+ sigcatchers);
+
+ cfd->read (ptr, res = len);
+
+done:
+ syscall_printf ("%d = read (%d, %p, %d), errno %d", res, fd, ptr, len,
+ get_errno ());
+ MALLOC_CHECK;
+ return (ssize_t) res;
}
EXPORT_ALIAS (read, _read)
extern "C" ssize_t
-pread (int fd, void *ptr, size_t len, _off64_t off)
+readv (int fd, const struct iovec *const iov, const int iovcnt)
{
pthread_testcancel ();
- ssize_t res;
+ myfault efault;
+ if (efault.faulted (EFAULT))
+ return -1;
+
+ ssize_t res = -1;
+ const ssize_t tot = check_iovec_for_read (iov, iovcnt);
+
cygheap_fdget cfd (fd);
if (cfd < 0)
- res = -1;
- else
- res = cfd->pread (ptr, len, off);
+ goto done;
- syscall_printf ("%d = pread (%d, %p, %d, %d), errno %d",
- res, fd, ptr, len, off, get_errno ());
+ if (tot <= 0)
+ {
+ res = tot;
+ goto done;
+ }
+
+ if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY)
+ {
+ set_errno (EBADF);
+ goto done;
+ }
+
+ /* Could block, so let user know we at least got here. */
+ extern int sigcatchers;
+ syscall_printf ("readv (%d, %p, %d) %sblocking, sigcatchers %d",
+ fd, iov, iovcnt, cfd->is_nonblocking () ? "non" : "",
+ sigcatchers);
+
+ res = cfd->readv (iov, iovcnt, tot);
+
+done:
+ syscall_printf ("%d = readv (%d, %p, %d), errno %d", res, fd, iov, iovcnt,
+ get_errno ());
+ MALLOC_CHECK;
return res;
}
extern "C" ssize_t
-pwrite (int fd, void *ptr, size_t len, _off64_t off)
+pread (int fd, void *ptr, size_t len, _off64_t off)
{
pthread_testcancel ();
@@ -936,9 +986,9 @@ pwrite (int fd, void *ptr, size_t len, _off64_t off)
if (cfd < 0)
res = -1;
else
- res = cfd->pwrite (ptr, len, off);
+ res = cfd->pread (ptr, len, off);
- syscall_printf ("%d = pwrite (%d, %p, %d, %d), errno %d",
+ syscall_printf ("%d = pread (%d, %p, %d, %d), errno %d",
res, fd, ptr, len, off, get_errno ());
return res;
}
@@ -946,67 +996,46 @@ pwrite (int fd, void *ptr, size_t len, _off64_t off)
extern "C" ssize_t
write (int fd, const void *ptr, size_t len)
{
- const struct iovec iov =
- {
- iov_base: (void *) ptr, // const_cast
- iov_len: len
- };
-
- return writev (fd, &iov, 1);
-}
-
-EXPORT_ALIAS (write, _write)
-
-extern "C" ssize_t
-readv (int fd, const struct iovec *const iov, const int iovcnt)
-{
pthread_testcancel ();
myfault efault;
if (efault.faulted (EFAULT))
return -1;
- ssize_t res = -1;
- const int e = get_errno ();
- const ssize_t tot = check_iovec_for_read (iov, iovcnt);
+ int res = -1;
cygheap_fdget cfd (fd);
if (cfd < 0)
goto done;
- if (tot <= 0)
- {
- res = tot;
- goto done;
- }
-
- if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY)
+ if ((cfd->get_flags () & O_ACCMODE) == O_RDONLY)
{
set_errno (EBADF);
goto done;
}
/* Could block, so let user know we at least got here. */
- extern int sigcatchers;
- syscall_printf ("readv (%d, %p, %d) %sblocking, sigcatchers %d",
- fd, iov, iovcnt, cfd->is_nonblocking () ? "non" : "",
- sigcatchers);
+ if (fd == 1 || fd == 2)
+ paranoid_printf ("write (%d, %p, %d)", fd, ptr, len);
+ else
+ syscall_printf ("write (%d, %p, %d)", fd, ptr, len);
- while (1)
- {
- res = cfd->readv (iov, iovcnt, tot);
- if (res >= 0 || get_errno () != EINTR || !_my_tls.call_signal_handler ())
- break;
- set_errno (e);
- }
+ res = cfd->write (ptr, len);
done:
- syscall_printf ("%d = readv (%d, %p, %d), errno %d", res, fd, iov, iovcnt,
- get_errno ());
+ if (fd == 1 || fd == 2)
+ paranoid_printf ("%d = write (%d, %p, %d), errno %d",
+ res, fd, ptr, len, get_errno ());
+ else
+ syscall_printf ("%d = write (%d, %p, %d), errno %d",
+ res, fd, ptr, len, get_errno ());
+
MALLOC_CHECK;
return res;
}
+EXPORT_ALIAS (write, _write)
+
extern "C" ssize_t
writev (const int fd, const struct iovec *const iov, const int iovcnt)
{
@@ -1045,16 +1074,33 @@ writev (const int fd, const struct iovec *const iov, const int iovcnt)
done:
if (fd == 1 || fd == 2)
- paranoid_printf ("%d = write (%d, %p, %d), errno %d",
+ paranoid_printf ("%d = writev (%d, %p, %d), errno %d",
res, fd, iov, iovcnt, get_errno ());
else
- syscall_printf ("%d = write (%d, %p, %d), errno %d",
+ syscall_printf ("%d = writev (%d, %p, %d), errno %d",
res, fd, iov, iovcnt, get_errno ());
MALLOC_CHECK;
return res;
}
+extern "C" ssize_t
+pwrite (int fd, void *ptr, size_t len, _off64_t off)
+{
+ pthread_testcancel ();
+
+ ssize_t res;
+ cygheap_fdget cfd (fd);
+ if (cfd < 0)
+ res = -1;
+ else
+ res = cfd->pwrite (ptr, len, off);
+
+ syscall_printf ("%d = pwrite (%d, %p, %d, %d), errno %d",
+ res, fd, ptr, len, off, get_errno ());
+ return res;
+}
+
/* _open */
/* newlib's fcntl.h defines _open as taking variable args so we must
correspond. The third arg if it exists is: mode_t mode. */