aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1999-03-08 21:01:20 +0000
committerRoland McGrath <roland@gnu.org>1999-03-08 21:01:20 +0000
commite4419715172bda2b260daa9afd757eca861cb90e (patch)
treea46fac06c54e70a0ea383ffee85cc1d1aff02770 /sysdeps/mach/hurd/ioctl.c
parentUpdate. (diff)
downloadglibc-e4419715172bda2b260daa9afd757eca861cb90e.tar.gz
glibc-e4419715172bda2b260daa9afd757eca861cb90e.tar.bz2
glibc-e4419715172bda2b260daa9afd757eca861cb90e.zip
1999-03-09 Roland McGrath <roland@baalperazim.frob.com>
* sysdeps/mach/hurd/ioctl.c (__ioctl): Move the marshalling of the arguments into the request message buffer inside `send_rpc' subfunction. We must repeat the marshalling when retrying the RPC after a SIGTTOU delivery.
Diffstat (limited to 'sysdeps/mach/hurd/ioctl.c')
-rw-r--r--sysdeps/mach/hurd/ioctl.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c
index 8d8ac9adcd..ac8e8040ee 100644
--- a/sysdeps/mach/hurd/ioctl.c
+++ b/sysdeps/mach/hurd/ioctl.c
@@ -60,7 +60,7 @@ __ioctl (int fd, unsigned long int request, ...)
_IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
} msg;
mach_msg_header_t *const m = &msg.header.Head;
- mach_msg_type_t *t = &msg.header.RetCodeType;
+ mach_msg_type_t *t;
mach_msg_id_t msgid;
unsigned int reply_size;
@@ -73,6 +73,44 @@ __ioctl (int fd, unsigned long int request, ...)
error_t send_rpc (io_t ioport)
{
error_t err;
+ mach_msg_type_t *t = &msg.header.RetCodeType;
+
+ /* Marshal the request arguments into the message buffer.
+ We must redo this work each time we retry the RPC after a SIGTTOU,
+ because the reply message containing the EBACKGROUND error code
+ clobbers the same message buffer also used for the request. */
+
+ if (_IOC_INOUT (request) & IOC_IN)
+ {
+ /* Pack an argument into the message buffer. */
+ void in (unsigned int count, enum __ioctl_datum type)
+ {
+ if (count > 0)
+ {
+ void *p = &t[1];
+ const size_t len = count * typesize ((unsigned int) type);
+ *t = io2mach_type (count, type);
+ memcpy (p, arg, len);
+ arg += len;
+ p += len;
+ p = (void *) (((unsigned long int) p + sizeof (*t) - 1)
+ & ~(sizeof (*t) - 1));
+ t = p;
+ }
+ }
+
+ /* Pack the argument data. */
+ in (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
+ in (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
+ in (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
+ }
+ else if (_IOC_INOUT (request) == IOC_VOID)
+ {
+ /* The RPC takes a single integer_t argument.
+ Rather than pointing to the value, ARG is the value itself. */
+ *t++ = io2mach_type (1, _IOTS (int));
+ *((int *) t)++ = (int) arg;
+ }
m->msgh_size = (char *) t - (char *) &msg;
m->msgh_remote_port = ioport;
@@ -148,38 +186,6 @@ __ioctl (int fd, unsigned long int request, ...)
parts of the ioctl request. */
msgid = IOC_MSGID (request);
- if (_IOC_INOUT (request) & IOC_IN)
- {
- /* Pack an argument into the message buffer. */
- void in (unsigned int count, enum __ioctl_datum type)
- {
- if (count > 0)
- {
- void *p = &t[1];
- const size_t len = count * typesize ((unsigned int) type);
- *t = io2mach_type (count, type);
- memcpy (p, arg, len);
- arg += len;
- p += len;
- p = (void *) (((unsigned long int) p + sizeof (*t) - 1)
- & ~(sizeof (*t) - 1));
- t = p;
- }
- }
-
- /* Pack the argument data. */
- in (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
- in (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
- in (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
- }
- else if (_IOC_INOUT (request) == IOC_VOID)
- {
- /* The RPC takes a single integer_t argument.
- Rather than pointing to the value, ARG is the value itself. */
- *t++ = io2mach_type (1, _IOTS (int));
- *((int *) t)++ = (int) arg;
- }
-
/* Compute the expected size of the reply. There is a standard header
consisting of the message header and the reply code. Then, for out
and in/out ioctls, there come the data with their type headers. */
@@ -203,6 +209,9 @@ __ioctl (int fd, unsigned long int request, ...)
figure_reply (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
}
+ /* Marshal the arguments into the request message and make the RPC.
+ This wrapper function handles EBACKGROUND returns, turning them
+ into either SIGTTOU or EIO. */
err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc));
t = (mach_msg_type_t *) msg.data;