* 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.
This commit is contained in:
Corinna Vinschen 2011-05-06 10:56:37 +00:00
parent 92ddb74290
commit a4e5706eb2
5 changed files with 145 additions and 64 deletions

View File

@ -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().

View File

@ -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,

View File

@ -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);
}

View File

@ -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)
@ -1530,6 +1538,14 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags)
return ret;
}
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)

View File

@ -898,65 +898,41 @@ getsid (pid_t pid)
extern "C" ssize_t
read (int fd, void *ptr, size_t len)
{
const iovec iov =
{
iov_base: ptr,
iov_len: len
};
pthread_testcancel ();
return readv (fd, &iov, 1);
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)
{
set_errno (EBADF);
goto done;
}
/* 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)
{
pthread_testcancel ();
ssize_t res;
cygheap_fdget cfd (fd);
if (cfd < 0)
res = -1;
else
res = cfd->pread (ptr, len, off);
syscall_printf ("%d = pread (%d, %p, %d, %d), errno %d",
res, fd, ptr, len, off, get_errno ());
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;
}
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)
{
@ -967,7 +943,6 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
return -1;
ssize_t res = -1;
const int e = get_errno ();
const ssize_t tot = check_iovec_for_read (iov, iovcnt);
cygheap_fdget cfd (fd);
@ -992,13 +967,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
fd, iov, iovcnt, cfd->is_nonblocking () ? "non" : "",
sigcatchers);
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->readv (iov, iovcnt, tot);
done:
syscall_printf ("%d = readv (%d, %p, %d), errno %d", res, fd, iov, iovcnt,
@ -1007,6 +976,66 @@ done:
return res;
}
extern "C" ssize_t
pread (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->pread (ptr, len, off);
syscall_printf ("%d = pread (%d, %p, %d, %d), errno %d",
res, fd, ptr, len, off, get_errno ());
return res;
}
extern "C" ssize_t
write (int fd, const void *ptr, size_t len)
{
pthread_testcancel ();
myfault efault;
if (efault.faulted (EFAULT))
return -1;
int res = -1;
cygheap_fdget cfd (fd);
if (cfd < 0)
goto done;
if ((cfd->get_flags () & O_ACCMODE) == O_RDONLY)
{
set_errno (EBADF);
goto done;
}
/* Could block, so let user know we at least got here. */
if (fd == 1 || fd == 2)
paranoid_printf ("write (%d, %p, %d)", fd, ptr, len);
else
syscall_printf ("write (%d, %p, %d)", fd, ptr, len);
res = cfd->write (ptr, len);
done:
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. */