From e88c882ecc9557ea14734a418252c2c8a5d8caf9 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 10 Feb 2002 17:21:02 +0000 Subject: 2002-02-10 Marcus Brinkmann * term.h: Include `hurd/hurd_types.h'. (struct bottomhalf): Change the return types of the following members from void to error_t: abandon_physical_output, suspend_physical_output, notice_input_flushed, desert_dtr, set_break, clear_break, start_output, set_bits (which now takes an struct termios * as argument), mdmctl and mdmstate (which now takes an int * as argument). Add new members init and type. (bottom): Define as const. (devio_bottom, ptyio_bottom): Declare as const. (drop_output): Change return type from void to error_t. (ptyio_init): Remove prototype. * devio.c (devio_abandon_physical_output): Change return value to error_t, and return 0. (devio_suspend_physical_output): Likewise. (devio_notice_input_flushed): Likewise. (devio_desert_dtr): Likewise. (devio_set_break): Likewise. (devio_clear_break): Likewise. (devio_start_output): Likewise. (devio_set_bits): Likewise. (devio_mdmctl): Likewise. (devio_mdmstate): Likewise. (init_devio): Rename to ... (devio_init): ... this. Do not give constructor attribute. Change return type to error_t, and return an error value, rather than bailing out. Declare as static. (devio_bottom): Add type TERM_ON_MACHDEV and init function devio_init. (devio_set_bits): Accept new argument STATE and use that to work out the terminal state, rather than changing the global termstate. (devio_mdmstate): Accept new argument STATE and use that to return the bits. * ptyio.c: Do not include `hurd/hurd_types.h'. (ptyio_suspend_physical_output): Change return value to error_t, and return 0. Likewise. (ptyio_notice_input_flushed): Likewise. (ptyio_desert_dtr): Likewise. (ptyio_set_bits): Likewise. (ptyio_set_break): Likewise. (ptyio_clear_break): Likewise. (ptyio_mdmctl): Likewise. (ptyio_start_output): Likewise. (ptyio_abandon_physical_output): Likewise. (ptyio_mdmstate): Likewise, and accept new argument STATE. (ptyio_init): Declare as static and change return type to error_t. (ptyio_bottom): Add type TERM_ON_MASTERPTY and init function ptyio_init. (ptyio_set_bits): Accept new argument STATE and use that to work out the terminal state, rather than changing the global termstate. (ptyio_mdmstate): Accept new argument STATE and use that to return the bits. * munge.c (drop_output): Change return value to error_t. Only clear queue if there was no error. * users.c (S_term_get_bottom_type): Just return bottom->type. (set_state): Rework logic to take possible errors into account, and to delay changing the termstate until we know that we won't fail. (S_tioctl_tiocflush): Return errors properly, and clear queue only if notice_input_flushed succeeded. (open_hook): Save error value of set_bits. Save old termflags and restore them if if set_bits failed. Call set_bits with correct arguments. (S_tioctl_tiocmods): Set err to result of mdmctl. (S_tioctl_tiocmset): Likewise. (S_tioctl_tiocmbic): Likewise. (S_tioctl_tiocmbis): Likewise. (S_tioctl_tioccdtr): Likewise. (S_tioctl_tiocsdtr): Likewise. (S_tioctl_tioccbrk): Likewise for clear_break. (S_tioctl_tiocsbrk): Likewise for set_break. (S_tioctl_tiocstart): Likewise for start_output. Save old termflags and restore them if if start_output failed. (S_tioctl_tiocstop): Likewise for stop_output. (S_trivfs_io_write): Abort the operation if start_output fails. Do not call start_output if it just failed, or if there was no data to be written. * main.c (main): Initialize bottom handler (rather than special casing this for ptyio). * users.c (open_hook): Use memcpy instead bcopy and memset instead bzero. (S_tioctl_tiocgeta): Likewise. (set_state): Likewise. (open_hook): Likewise. * munge.c (rescan_inputq): Likewise. --- term/ChangeLog | 88 +++++++++++++++++++++++++++++++ term/devio.c | 86 +++++++++++++++++------------- term/main.c | 10 ++-- term/munge.c | 14 +++-- term/ptyio.c | 52 +++++++++++------- term/term.h | 32 +++++------ term/users.c | 164 ++++++++++++++++++++++++++++----------------------------- 7 files changed, 282 insertions(+), 164 deletions(-) (limited to 'term') diff --git a/term/ChangeLog b/term/ChangeLog index ecbd117b..c9bfff50 100644 --- a/term/ChangeLog +++ b/term/ChangeLog @@ -1,3 +1,91 @@ +2002-02-10 Marcus Brinkmann + + * term.h: Include `hurd/hurd_types.h'. + (struct bottomhalf): Change the return types of the following + members from void to error_t: abandon_physical_output, + suspend_physical_output, notice_input_flushed, desert_dtr, + set_break, clear_break, start_output, set_bits (which now takes an + struct termios * as argument), mdmctl and mdmstate (which now + takes an int * as argument). Add new members init and type. + (bottom): Define as const. + (devio_bottom, ptyio_bottom): Declare as const. + (drop_output): Change return type from void to error_t. + (ptyio_init): Remove prototype. + * devio.c (devio_abandon_physical_output): Change return value to + error_t, and return 0. + (devio_suspend_physical_output): Likewise. + (devio_notice_input_flushed): Likewise. + (devio_desert_dtr): Likewise. + (devio_set_break): Likewise. + (devio_clear_break): Likewise. + (devio_start_output): Likewise. + (devio_set_bits): Likewise. + (devio_mdmctl): Likewise. + (devio_mdmstate): Likewise. + (init_devio): Rename to ... + (devio_init): ... this. Do not give constructor attribute. + Change return type to error_t, and return an error value, rather + than bailing out. Declare as static. + (devio_bottom): Add type TERM_ON_MACHDEV and init function + devio_init. + (devio_set_bits): Accept new argument STATE and use that to work + out the terminal state, rather than changing the global termstate. + (devio_mdmstate): Accept new argument STATE and use that to return + the bits. + * ptyio.c: Do not include `hurd/hurd_types.h'. + (ptyio_suspend_physical_output): Change return value to error_t, + and return 0. Likewise. + (ptyio_notice_input_flushed): Likewise. + (ptyio_desert_dtr): Likewise. + (ptyio_set_bits): Likewise. + (ptyio_set_break): Likewise. + (ptyio_clear_break): Likewise. + (ptyio_mdmctl): Likewise. + (ptyio_start_output): Likewise. + (ptyio_abandon_physical_output): Likewise. + (ptyio_mdmstate): Likewise, and accept new argument STATE. + (ptyio_init): Declare as static and change return type to error_t. + (ptyio_bottom): Add type TERM_ON_MASTERPTY and init function + ptyio_init. + (ptyio_set_bits): Accept new argument STATE and use that to work + out the terminal state, rather than changing the global termstate. + (ptyio_mdmstate): Accept new argument STATE and use that to return + the bits. + * munge.c (drop_output): Change return value to error_t. Only + clear queue if there was no error. + * users.c (S_term_get_bottom_type): Just return bottom->type. + (set_state): Rework logic to take possible errors into account, + and to delay changing the termstate until we know that we won't + fail. + (S_tioctl_tiocflush): Return errors properly, and clear queue only + if notice_input_flushed succeeded. + (open_hook): Save error value of set_bits. Save old termflags and + restore them if if set_bits failed. Call set_bits with correct + arguments. + (S_tioctl_tiocmods): Set err to result of mdmctl. + (S_tioctl_tiocmset): Likewise. + (S_tioctl_tiocmbic): Likewise. + (S_tioctl_tiocmbis): Likewise. + (S_tioctl_tioccdtr): Likewise. + (S_tioctl_tiocsdtr): Likewise. + (S_tioctl_tioccbrk): Likewise for clear_break. + (S_tioctl_tiocsbrk): Likewise for set_break. + (S_tioctl_tiocstart): Likewise for start_output. Save old + termflags and restore them if if start_output failed. + (S_tioctl_tiocstop): Likewise for stop_output. + (S_trivfs_io_write): Abort the operation if start_output fails. + Do not call start_output if it just failed, or if there was no + data to be written. + * main.c (main): Initialize bottom handler (rather than special + casing this for ptyio). + + * users.c (open_hook): Use memcpy instead bcopy and memset instead + bzero. + (S_tioctl_tiocgeta): Likewise. + (set_state): Likewise. + (open_hook): Likewise. + * munge.c (rescan_inputq): Likewise. + 2002-01-30 Marcus Brinkmann * users.c (trivfs_S_io_select): Remove IDTAG argument. diff --git a/term/devio.c b/term/devio.c index f1bdab2d..55b26336 100644 --- a/term/devio.c +++ b/term/devio.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995,96,98,99,2000,01 Free Software Foundation, Inc. + Copyright (C) 1995,96,98,99,2000,01,02 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -98,20 +98,20 @@ static int output_stopped; static int char_size_mask_xxx = 0xff; /* Forward */ -static void devio_desert_dtr (); +static error_t devio_desert_dtr (); -static void init_devio (void) __attribute__ ((constructor)); -static void -init_devio () +static error_t +devio_init (void) { mach_port_t host_priv; error_t err; err = get_privileged_ports (&host_priv, &device_master); if (err) - error (1, err, "Getting priviliged ports"); + return err; mach_port_deallocate (mach_task_self (), host_priv); phys_reply_class = ports_create_class (0, 0); + return 0; } /* XXX Convert a real speed to a bogus Mach speed. Return @@ -237,7 +237,7 @@ bogus_speed_to_real_speed (int bspeed) /* If there are characters on the output queue and no pending output requests, then send them. */ -static void +static error_t devio_start_output () { char *cp; @@ -247,7 +247,7 @@ devio_start_output () size = qsize (outputq); if (!size || output_pending || (termflags & USER_OUTPUT_SUSP)) - return; + return 0; if (output_stopped) { @@ -278,6 +278,7 @@ devio_start_output () devio_desert_dtr (); else if (!err) output_pending = 1; + return 0; } error_t @@ -368,19 +369,21 @@ device_read_reply_inband (mach_port_t replypt, return 0; } -static void +static error_t devio_set_break () { device_set_status (phys_device, TTY_SET_BREAK, 0, 0); + return 0; } -static void +static error_t devio_clear_break () { device_set_status (phys_device, TTY_CLEAR_BREAK, 0, 0); + return 0; } -static void +static error_t devio_abandon_physical_output () { int val = D_WRITE; @@ -388,7 +391,7 @@ devio_abandon_physical_output () /* If this variable is clear, then carrier is gone, so we have nothing to do. */ if (!phys_reply_writes_pi) - return; + return 0; mach_port_deallocate (mach_task_self (), phys_reply_writes); ports_reallocate_port (phys_reply_writes_pi); @@ -397,9 +400,10 @@ devio_abandon_physical_output () device_set_status (phys_device, TTY_FLUSH, &val, TTY_FLUSH_COUNT); npending_output = 0; output_pending = 0; + return 0; } -static void +static error_t devio_suspend_physical_output () { if (!output_stopped) @@ -407,11 +411,13 @@ devio_suspend_physical_output () device_set_status (phys_device, TTY_STOP, 0, 0); output_stopped = 1; } + return 0; } -static void +static error_t devio_notice_input_flushed () { + return 0; } static int @@ -460,7 +466,7 @@ initial_open () return err; } -static void +static error_t devio_desert_dtr () { int bits; @@ -471,6 +477,7 @@ devio_desert_dtr () (dev_status_t) &bits, TTY_MODEM_COUNT); report_carrier_off (); + return 0; } static error_t @@ -580,20 +587,20 @@ device_open_reply (mach_port_t replyport, /* Adjust physical state on the basis of the terminal state. Where it isn't possible, mutate terminal state to match reality. */ -static void -devio_set_bits () +static error_t +devio_set_bits (struct termios *state) { - if (!(termstate.c_cflag & CIGNORE) && phys_device != MACH_PORT_NULL) + if (!(state->c_cflag & CIGNORE) && phys_device != MACH_PORT_NULL) { struct tty_status ttystat; int cnt = TTY_STATUS_COUNT; /* Find the current state. */ device_get_status (phys_device, TTY_STATUS, (dev_status_t) &ttystat, &cnt); - if (termstate.__ispeed) - real_speed_to_bogus_speed (termstate.__ispeed, &ttystat.tt_ispeed); - if (termstate.__ospeed) - real_speed_to_bogus_speed (termstate.__ospeed, &ttystat.tt_ospeed); + if (state->__ispeed) + real_speed_to_bogus_speed (state->__ispeed, &ttystat.tt_ispeed); + if (state->__ospeed) + real_speed_to_bogus_speed (state->__ospeed, &ttystat.tt_ospeed); /* Try and set it. */ device_set_status (phys_device, TTY_STATUS, @@ -602,19 +609,19 @@ devio_set_bits () /* And now make termstate match reality. */ cnt = TTY_STATUS_COUNT; device_get_status (phys_device, TTY_STATUS, (dev_status_t) &ttystat, &cnt); - termstate.__ispeed = bogus_speed_to_real_speed (ttystat.tt_ispeed); - termstate.__ospeed = bogus_speed_to_real_speed (ttystat.tt_ospeed); + state->__ispeed = bogus_speed_to_real_speed (ttystat.tt_ispeed); + state->__ospeed = bogus_speed_to_real_speed (ttystat.tt_ospeed); /* Mach forces us to use the normal stop bit convention: two bits at 110 bps; 1 bit otherwise. */ - if (termstate.__ispeed == 110) - termstate.c_cflag |= CSTOPB; + if (state->__ispeed == 110) + state->c_cflag |= CSTOPB; else - termstate.c_cflag &= ~CSTOPB; + state->c_cflag &= ~CSTOPB; /* Figure out how to munge input, since we are unable to actually affect what the hardware does. */ - switch (termstate.c_cflag & CSIZE) + switch (state->c_cflag & CSIZE) { case CS5: char_size_mask_xxx = 0x1f; @@ -633,12 +640,13 @@ devio_set_bits () char_size_mask_xxx = 0xff; break; } - if (termstate.c_cflag & PARENB) + if (state->c_cflag & PARENB) char_size_mask_xxx |= 0x80; } + return 0; } -static void +static error_t devio_mdmctl (int how, int bits) { int oldbits, newbits; @@ -661,21 +669,25 @@ devio_mdmctl (int how, int bits) device_set_status (phys_device, TTY_MODEM, (dev_status_t) &newbits, TTY_MODEM_COUNT); + + return 0; } -static int -devio_mdmstate () +static error_t +devio_mdmstate (int *state) { int bits, cnt; cnt = TTY_MODEM_COUNT; device_get_status (phys_device, TTY_MODEM, (dev_status_t) &bits, &cnt); - if (cnt != TTY_MODEM_COUNT) - return 0; + if (cnt == TTY_MODEM_COUNT) + *state = bits; else - return bits; + *state = 0; + return 0; } + /* Unused stubs */ kern_return_t device_read_reply (mach_port_t port, @@ -747,8 +759,10 @@ ports_do_mach_notify_send_once (mach_port_t notify) } -struct bottomhalf devio_bottom = +const struct bottomhalf devio_bottom = { + TERM_ON_MACHDEV, + devio_init, devio_start_output, devio_set_break, devio_clear_break, diff --git a/term/main.c b/term/main.c index 8d35a679..c49168c7 100644 --- a/term/main.c +++ b/term/main.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -194,8 +194,12 @@ main (int argc, char **argv) outputq = create_queue (256, QUEUE_LOWAT, QUEUE_HIWAT); - if (bottom == &ptyio_bottom) - ptyio_init (); + errno = (*bottom->init) (); + if (errno) + { + perror ("Initializing bottom handler"); + exit (1); + } condition_init (&carrier_alert); condition_init (&select_alert); diff --git a/term/munge.c b/term/munge.c index 34d2210a..32d87c98 100644 --- a/term/munge.c +++ b/term/munge.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1999, 2002 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -681,20 +681,24 @@ rescan_inputq () n = qsize (inputq); buf = alloca (n * sizeof (quoted_char)); - bcopy (inputq->cs, buf, n * sizeof (quoted_char)); + memcpy (buf, inputq->cs, n * sizeof (quoted_char)); clear_queue (inputq); for (i = 0; i < n; i++) input_character (unquote_char (buf[i])); } -void + +error_t drop_output () { - clear_queue (outputq); - (*bottom->abandon_physical_output) (); + error_t err = (*bottom->abandon_physical_output) (); + if (!err) + clear_queue (outputq); + return err; } + error_t drain_output () { diff --git a/term/ptyio.c b/term/ptyio.c index 9ea632a7..f2ff96e6 100644 --- a/term/ptyio.c +++ b/term/ptyio.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1999, 2002 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -19,7 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ #include -#include #include #include #include @@ -56,11 +55,12 @@ static int ptyopen = 0; static int nptyperopens = 0; -void -ptyio_init () +static error_t +ptyio_init (void) { condition_implies (inputq->wait, &pty_select_wakeup); condition_implies (&pty_read_wakeup, &pty_select_wakeup); + return 0; } error_t @@ -138,7 +138,7 @@ wake_reader () /* Lower half for tty node */ -static void +static error_t ptyio_start_output () { if (packet_mode && output_stopped && (!(termflags & USER_OUTPUT_SUSP))) @@ -148,9 +148,10 @@ ptyio_start_output () output_stopped = 0; } wake_reader (); + return 0; } -static void +static error_t ptyio_abandon_physical_output () { if (packet_mode) @@ -158,9 +159,10 @@ ptyio_abandon_physical_output () control_byte |= TIOCPKT_FLUSHWRITE; wake_reader (); } + return 0; } -static void +static error_t ptyio_suspend_physical_output () { if (packet_mode) @@ -170,6 +172,7 @@ ptyio_suspend_physical_output () output_stopped = 1; wake_reader (); } + return 0; } static int @@ -179,7 +182,7 @@ ptyio_pending_output_size () return 0; } -static void +static error_t ptyio_notice_input_flushed () { if (packet_mode) @@ -187,6 +190,7 @@ ptyio_notice_input_flushed () control_byte |= TIOCPKT_FLUSHREAD; wake_reader (); } + return 0; } static error_t @@ -196,22 +200,23 @@ ptyio_assert_dtr () return 0; } -static void +static error_t ptyio_desert_dtr () { dtr_on = 0; wake_reader (); + return 0; } -static void -ptyio_set_bits () +static error_t +ptyio_set_bits (struct termios *state) { if (packet_mode) { int wakeup = 0; - int stop = ((termstate.c_iflag & IXON) - && CCEQ (termstate.c_cc[VSTOP], CHAR_DC3) - && CCEQ (termstate.c_cc[VSTART], CHAR_DC1)); + int stop = ((state->c_iflag & IXON) + && CCEQ (state->c_cc[VSTOP], CHAR_DC3) + && CCEQ (state->c_cc[VSTART], CHAR_DC1)); if (external_processing) { @@ -237,33 +242,40 @@ ptyio_set_bits () if (wakeup) wake_reader (); } + return 0; } /* These do nothing. In BSD the associated ioctls get errors, but I'd rather just ignore them. */ -static void +static error_t ptyio_set_break () { + return 0; } -static void +static error_t ptyio_clear_break () { + return 0; } -static void +static error_t ptyio_mdmctl (int a, int b) { + return 0; } -static int -ptyio_mdmstate () +static error_t +ptyio_mdmstate (int *state) { + *state = 0; return 0; } -struct bottomhalf ptyio_bottom = +const struct bottomhalf ptyio_bottom = { + TERM_ON_MASTERPTY, + ptyio_init, ptyio_start_output, ptyio_set_break, ptyio_clear_break, diff --git a/term/term.h b/term/term.h index 565fe2f2..aafc844a 100644 --- a/term/term.h +++ b/term/term.h @@ -25,6 +25,7 @@ #include #include #include +#include #undef MDMBUF #undef ECHO @@ -140,22 +141,24 @@ mode_t term_mode; /* Functions a bottom half defines */ struct bottomhalf { - void (*start_output) (void); - void (*set_break) (void); - void (*clear_break) (void); - void (*abandon_physical_output) (void); - void (*suspend_physical_output) (void); + enum term_bottom_type type; + error_t (*init) (void); + error_t (*start_output) (void); + error_t (*set_break) (void); + error_t (*clear_break) (void); + error_t (*abandon_physical_output) (void); + error_t (*suspend_physical_output) (void); int (*pending_output_size) (void); - void (*notice_input_flushed) (void); + error_t (*notice_input_flushed) (void); error_t (*assert_dtr) (void); - void (*desert_dtr) (void); - void (*set_bits) (void); - void (*mdmctl) (int, int); - int (*mdmstate) (void); + error_t (*desert_dtr) (void); + error_t (*set_bits) (struct termios *state); + error_t (*mdmctl) (int how, int bits); + error_t (*mdmstate) (int *state); }; -struct bottomhalf *bottom; -extern struct bottomhalf devio_bottom, ptyio_bottom; +const struct bottomhalf *bottom; +extern const struct bottomhalf devio_bottom, ptyio_bottom; /* Character queues */ @@ -313,7 +316,7 @@ void report_carrier_error (error_t); /* Other decls */ -void drop_output (void); +error_t drop_output (void); void send_signal (int); error_t drain_output (); void output_character (int); @@ -322,9 +325,6 @@ void rescan_inputq (void); void write_character (int); void init_users (void); -/* Call this before using ptyio_bottom. */ -void ptyio_init (void); - /* kludge--these are pty versions of trivfs_S_io_* functions called by the real functions in users.c to do work for ptys. */ error_t pty_io_write (struct trivfs_protid *, char *, diff --git a/term/users.c b/term/users.c index 77af90d6..0d3297b2 100644 --- a/term/users.c +++ b/term/users.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995,96,97,98,99,2000,01 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,01,02 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -152,7 +152,7 @@ open_hook (struct trivfs_control *cntl, if (!(termflags & TTY_OPEN)) { - bzero (&termstate, sizeof termstate); + memset (&termstate, 0, sizeof termstate); /* This is different from BSD: we don't turn on ISTRIP, and we use CS8 rather than CS7|PARENB. */ @@ -162,9 +162,9 @@ open_hook (struct trivfs_control *cntl, | ECHOE|ECHOKE|ECHOCTL); termstate.c_cflag |= CREAD | CS8 | HUPCL; - bcopy (ttydefchars, termstate.c_cc, NCCS); + memcpy (termstate.c_cc, ttydefchars, NCCS); - bzero (&window_size, sizeof window_size); + memset (&window_size, 0, sizeof window_size); termflags |= NO_OWNER; } @@ -212,8 +212,13 @@ open_hook (struct trivfs_control *cntl, if (!err) { - termflags |= TTY_OPEN; - (*bottom->set_bits) (); + struct termios state = termstate; + err = (*bottom->set_bits) (&state); + if (!err) + { + termstate = state; + termflags |= TTY_OPEN; + } } mutex_unlock (&global_lock); @@ -560,6 +565,7 @@ trivfs_S_io_write (struct trivfs_protid *cred, { int i; int cancel; + error_t err = 0; if (!cred) return EOPNOTSUPP; @@ -595,9 +601,14 @@ trivfs_S_io_write (struct trivfs_protid *cred, { while (!qavail (outputq) && !cancel) { - (*bottom->start_output) (); - if (!qavail (outputq)) - cancel = hurd_condition_wait (outputq->wait, &global_lock); + err = (*bottom->start_output) (); + if (err) + cancel = 1; + else + { + if (!qavail (outputq)) + cancel = hurd_condition_wait (outputq->wait, &global_lock); + } } if (cancel) break; @@ -607,7 +618,8 @@ trivfs_S_io_write (struct trivfs_protid *cred, *amt = i; - (*bottom->start_output) (); + if (!err && datalen) + (*bottom->start_output) (); trivfs_set_mtime (termctl); @@ -615,7 +627,7 @@ trivfs_S_io_write (struct trivfs_protid *cred, mutex_unlock (&global_lock); - return ((cancel && datalen && !*amt) ? EINTR : 0); + return ((cancel && datalen && !*amt) ? (err ?: EINTR) : 0); } /* Called for user reads from the terminal. */ @@ -882,6 +894,8 @@ S_tioctl_tiocmodg (io_t port, int *state) { struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); + error_t err = 0; + if (!cred) return EOPNOTSUPP; @@ -893,11 +907,11 @@ S_tioctl_tiocmodg (io_t port, } mutex_lock (&global_lock); - *state = (*bottom->mdmstate) (); + err = (*bottom->mdmstate) (state); mutex_unlock (&global_lock); ports_port_deref (cred); - return 0; + return err; } /* TIOCMODS ioctl -- Set modem state */ @@ -922,10 +936,7 @@ S_tioctl_tiocmods (io_t port, if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->mdmctl) (MDMCTL_SET, state); - err = 0; - } + err = (*bottom->mdmctl) (MDMCTL_SET, state); mutex_unlock (&global_lock); @@ -1001,8 +1012,8 @@ S_tioctl_tiocflush (io_t port, int flags) { struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); + error_t err = 0; - error_t err; if (!cred) return EOPNOTSUPP; @@ -1024,14 +1035,13 @@ S_tioctl_tiocflush (io_t port, if (flags & O_READ) { - clear_queue (inputq); - (*bottom->notice_input_flushed) (); + err = (*bottom->notice_input_flushed) (); + if (!err) + clear_queue (inputq); } - if (flags & O_WRITE) - drop_output (); - - err = 0; + if (!err && (flags & O_WRITE)) + err = drop_output (); } mutex_unlock (&global_lock); @@ -1063,7 +1073,7 @@ S_tioctl_tiocgeta (io_t port, modes[1] = termstate.c_oflag; modes[2] = termstate.c_cflag; modes[3] = termstate.c_lflag; - bcopy (termstate.c_cc, ccs, NCCS); + memcpy (ccs, termstate.c_cc, NCCS); speeds[0] = termstate.__ispeed; speeds[1] = termstate.__ospeed; mutex_unlock (&global_lock); @@ -1084,6 +1094,7 @@ set_state (io_t port, struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); error_t err; int oldlflag; + struct termios state; if (!cred) return EOPNOTSUPP; @@ -1105,42 +1116,47 @@ set_state (io_t port, { if (cred->pi.class == pty_class) { + err = (*bottom->abandon_physical_output) (); + if (err) + goto leave; clear_queue (outputq); - (*bottom->abandon_physical_output) (); } if (draino) { err = drain_output (); if (err) - { - mutex_unlock (&global_lock); - ports_port_deref (cred); - return err; - } + goto leave; } if (flushi) { + err = (*bottom->notice_input_flushed) (); + if (err) + goto leave; clear_queue (inputq); - (*bottom->notice_input_flushed) (); } - oldlflag = termstate.c_lflag; - termstate.c_iflag = modes[0]; - termstate.c_oflag = modes[1]; - termstate.c_cflag = modes[2]; - termstate.c_lflag = modes[3]; - bcopy (ccs, termstate.c_cc, NCCS); - termstate.__ispeed = speeds[0]; - termstate.__ospeed = speeds[1]; + state = termstate; + state.c_iflag = modes[0]; + state.c_oflag = modes[1]; + state.c_cflag = modes[2]; + state.c_lflag = modes[3]; + memcpy (state.c_cc, ccs, NCCS); + state.__ispeed = speeds[0]; + state.__ospeed = speeds[1]; if (external_processing) - termstate.c_lflag |= EXTPROC; + state.c_lflag |= EXTPROC; else - termstate.c_lflag &= ~EXTPROC; + state.c_lflag &= ~EXTPROC; + + err = (*bottom->set_bits) (&state); + if (err) + goto leave; - (*bottom->set_bits) (); + oldlflag = termstate.c_lflag; + termstate = state; if (oldlflag & ICANON) { @@ -1152,17 +1168,15 @@ set_state (io_t port, if (termstate.c_lflag & ICANON) rescan_inputq (); } - err = 0; } + leave: mutex_unlock (&global_lock); - ports_port_deref (cred); return err; } - /* TIOCSETA -- Set termios state */ kern_return_t S_tioctl_tiocseta (io_t port, @@ -1354,6 +1368,7 @@ S_tioctl_tiocmget (io_t port, int *bits) { struct trivfs_protid *cred = ports_lookup_port (term_bucket, port, 0); + error_t err = 0; if (!cred) return EOPNOTSUPP; @@ -1366,11 +1381,11 @@ S_tioctl_tiocmget (io_t port, } mutex_lock (&global_lock); - *bits = (*bottom->mdmstate) (); + err = (*bottom->mdmstate) (bits); mutex_unlock (&global_lock); ports_port_deref (cred); - return 0; + return err; } /* TIOCMSET -- Set all modem bits */ @@ -1395,10 +1410,7 @@ S_tioctl_tiocmset (io_t port, if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->mdmctl) (MDMCTL_SET, bits); - err = 0; - } + err = (*bottom->mdmctl) (MDMCTL_SET, bits); mutex_unlock (&global_lock); ports_port_deref (cred); @@ -1427,10 +1439,7 @@ S_tioctl_tiocmbic (io_t port, if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->mdmctl) (MDMCTL_BIC, bits); - err = 0; - } + err = (*bottom->mdmctl) (MDMCTL_BIC, bits); mutex_unlock (&global_lock); ports_port_deref (cred); @@ -1460,10 +1469,7 @@ S_tioctl_tiocmbis (io_t port, if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->mdmctl) (MDMCTL_BIS, bits); - err = 0; - } + err = (*bottom->mdmctl) (MDMCTL_BIS, bits); mutex_unlock (&global_lock); ports_port_deref (cred); return err; @@ -1492,9 +1498,12 @@ S_tioctl_tiocstart (io_t port) err = EBADF; else { + int old_termflags = termflags; + termflags &= ~USER_OUTPUT_SUSP; - (*bottom->start_output) (); - err = 0; + err = (*bottom->start_output) (); + if (err) + termflags = old_termflags; } mutex_unlock (&global_lock); @@ -1524,9 +1533,11 @@ S_tioctl_tiocstop (io_t port) err = EBADF; else { + int old_termflags = termflags; termflags |= USER_OUTPUT_SUSP; - (*bottom->suspend_physical_output) (); - err = 0; + err = (*bottom->suspend_physical_output) (); + if (err) + termflags = old_termflags; } mutex_unlock (&global_lock); @@ -1690,10 +1701,7 @@ S_tioctl_tioccdtr (io_t port) if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->mdmctl) (MDMCTL_BIC, TIOCM_DTR); - err = 0; - } + err = (*bottom->mdmctl) (MDMCTL_BIC, TIOCM_DTR); mutex_unlock (&global_lock); ports_port_deref (cred); @@ -1721,10 +1729,7 @@ S_tioctl_tiocsdtr (io_t port) if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->mdmctl) (MDMCTL_BIS, TIOCM_DTR); - err = 0; - } + err = (*bottom->mdmctl) (MDMCTL_BIS, TIOCM_DTR); mutex_unlock (&global_lock); ports_port_deref (cred); @@ -1752,10 +1757,7 @@ S_tioctl_tioccbrk (io_t port) if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->clear_break) (); - err = 0; - } + err = (*bottom->clear_break) (); mutex_unlock (&global_lock); ports_port_deref (cred); @@ -1783,10 +1785,7 @@ S_tioctl_tiocsbrk (io_t port) if (!(cred->po->openmodes & (O_READ|O_WRITE))) err = EBADF; else - { - (*bottom->set_break) (); - err = 0; - } + err = (*bottom->set_break) (); mutex_unlock (&global_lock); ports_port_deref (cred); @@ -2237,10 +2236,7 @@ S_term_get_bottom_type (io_t arg, return EOPNOTSUPP; ports_port_deref (cred); - if (bottom == &devio_bottom) - *ttype = TERM_ON_MACHDEV; - else - *ttype = TERM_ON_MASTERPTY; + *ttype = bottom->type; return 0; } -- cgit v1.2.3