home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mitsch75.zip
/
scheme-7_5_17-src.zip
/
scheme-7.5.17
/
src
/
microcode
/
uxterm.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-12-05
|
22KB
|
881 lines
/* -*-C-*-
$Id: uxterm.c,v 1.28 2000/12/05 21:23:49 cph Exp $
Copyright (c) 1990-2000 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ux.h"
#include "uxterm.h"
#include "uxio.h"
#include "ospty.h"
#include "prims.h"
extern long EXFUN (arg_nonnegative_integer, (int));
extern long EXFUN (arg_index_integer, (int, long));
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
# ifndef ISTRIP
# define ISTRIP 0
# endif
# ifndef CS8
# define CS8 0
# endif
# ifndef PARENB
# define PARENB 0
# endif
# define TIO(s) (& ((s) -> tio))
#else
# ifdef HAVE_SGTTY_H
/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
# ifndef LPASS8
# define LPASS8 0
# endif
# endif /* HAVE_SGTTY_H */
#endif /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
struct terminal_state
{
int buffer;
Ttty_state state;
};
static struct terminal_state * terminal_table;
#define TERMINAL_BUFFER(channel) ((terminal_table[(channel)]) . buffer)
#define TERMINAL_ORIGINAL_STATE(channel) ((terminal_table[(channel)]) . state)
void
DEFUN_VOID (UX_initialize_terminals)
{
terminal_table =
(UX_malloc (OS_channel_table_size * (sizeof (struct terminal_state))));
if (terminal_table == 0)
{
fprintf (stderr, "\nUnable to allocate terminal table.\n");
fflush (stderr);
termination_init_error ();
}
}
void
DEFUN_VOID (UX_reset_terminals)
{
UX_free (terminal_table);
terminal_table = 0;
}
/* This is called from the file-opening code. */
void
DEFUN (terminal_open, (channel), Tchannel channel)
{
(TERMINAL_BUFFER (channel)) = (-1);
get_terminal_state (channel, (& (TERMINAL_ORIGINAL_STATE (channel))));
}
void
DEFUN (get_terminal_state, (channel, s), Tchannel channel AND Ttty_state * s)
{
STD_VOID_SYSTEM_CALL
(syscall_terminal_get_state,
(UX_terminal_get_state ((CHANNEL_DESCRIPTOR (channel)), s)));
}
void
DEFUN (set_terminal_state, (channel, s), Tchannel channel AND Ttty_state * s)
{
extern int EXFUN (UX_terminal_control_ok, (int fd));
if (UX_terminal_control_ok (CHANNEL_DESCRIPTOR (channel)))
STD_VOID_SYSTEM_CALL
(syscall_terminal_set_state,
(UX_terminal_set_state ((CHANNEL_DESCRIPTOR (channel)), s)));
}
unsigned int
DEFUN (terminal_state_get_ospeed, (s), Ttty_state * s)
{
#ifdef HAVE_TERMIOS_H
return (cfgetospeed (TIO (s)));
#else
#ifdef HAVE_TERMIO_H
return (((TIO (s)) -> c_cflag) & CBAUD);
#else
#ifdef HAVE_SGTTY_H
return (s -> sg . sg_ospeed);
#endif /* HAVE_SGTTY_H */
#endif /* not HAVE_TERMIO_H */
#endif /* not HAVE_TERMIOS_H */
}
unsigned int
DEFUN (terminal_state_get_ispeed, (s), Ttty_state * s)
{
#ifdef HAVE_TERMIOS_H
return (cfgetispeed (TIO (s)));
#else
#ifdef HAVE_TERMIO_H
return (((TIO (s)) -> c_cflag) & CBAUD);
#else
#ifdef HAVE_SGTTY_H
return (s -> sg . sg_ispeed);
#endif /* HAVE_SGTTY_H */
#endif /* not HAVE_TERMIO_H */
#endif /* not HAVE_TERMIOS_H */
}
void
DEFUN (terminal_state_set_ospeed, (s, b),
Ttty_state * s AND
unsigned int b)
{
#ifdef HAVE_TERMIOS_H
cfsetospeed ((TIO (s)), b);
#else
#ifdef HAVE_TERMIO_H
((TIO (s)) -> c_cflag) = ((((TIO (s)) -> c_cflag) &~ CBAUD) | b);
#else
#ifdef HAVE_SGTTY_H
(s -> sg . sg_ospeed) = b;
#endif /* HAVE_SGTTY_H */
#endif /* not HAVE_TERMIO_H */
#endif /* not HAVE_TERMIOS_H */
}
void
DEFUN (terminal_state_set_ispeed, (s, b),
Ttty_state * s AND
unsigned int b)
{
#ifdef HAVE_TERMIOS_H
cfsetispeed ((TIO (s)), b);
#else
#ifdef HAVE_TERMIO_H
((TIO (s)) -> c_cflag) =
((((TIO (s)) -> c_cflag) &~ CIBAUD) | (b << IBSHIFT));
#else
#ifdef HAVE_SGTTY_H
(s -> sg . sg_ispeed) = b;
#endif /* HAVE_SGTTY_H */
#endif /* not HAVE_TERMIO_H */
#endif /* not HAVE_TERMIOS_H */
}
int
DEFUN (terminal_state_cooked_output_p, (s), Ttty_state * s)
{
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
return ((((TIO (s)) -> c_oflag) & OPOST) != 0);
#else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
#ifdef HAVE_SGTTY_H
return (((s -> sg . sg_flags) & LLITOUT) == 0);
#endif /* HAVE_SGTTY_H */
#endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
}
void
DEFUN (terminal_state_raw_output, (s), Ttty_state * s)
{
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
((TIO (s)) -> c_oflag) &=~ OPOST;
#else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
#ifdef HAVE_SGTTY_H
(s -> sg . sg_flags) &=~ ALLDELAY;
(s -> lmode) |= LLITOUT;
#endif /* HAVE_SGTTY_H */
#endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
}
void
DEFUN (terminal_state_cooked_output, (s, channel),
Ttty_state * s AND Tchannel channel)
{
Ttty_state * os = (& (TERMINAL_ORIGINAL_STATE (channel)));
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
((TIO (s)) -> c_oflag) |= (((TIO (os)) -> c_oflag) & OPOST);
#else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
#ifdef HAVE_SGTTY_H
(s -> sg . sg_flags) =
(((s -> sg . sg_flags) &~ ALLDELAY) | ((os -> sg . sg_flags) & ALLDELAY));
(s -> lmode) &=~ ((os -> lmode) & LLITOUT);
#endif /* HAVE_SGTTY_H */
#endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
}
int
DEFUN (terminal_state_buffered_p, (s), Ttty_state * s)
{
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
return ((((TIO (s)) -> c_lflag) & ICANON) != 0);
#else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
#ifdef HAVE_SGTTY_H
return (((s -> sg . sg_flags) & (CBREAK | RAW)) == 0);
#endif /* HAVE_SGTTY_H */
#endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
}
void
DEFUN (terminal_state_nonbuffered, (s, fd, polling),
Ttty_state * s AND
int fd AND
int polling)
{
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
((TIO (s)) -> c_lflag) &=~ (ICANON | ECHO);
#ifdef IEXTEN
((TIO (s)) -> c_lflag) &=~ IEXTEN;
#endif
((TIO (s)) -> c_lflag) |= ISIG;
((TIO (s)) -> c_iflag) |= IGNBRK;
((TIO (s)) -> c_iflag) &=~ (ICRNL | IXON | ISTRIP);
((TIO (s)) -> c_cflag) |= CS8;
((TIO (s)) -> c_cflag) &=~ PARENB;
(((TIO (s)) -> c_cc) [VMIN]) = (polling ? 0 : 1);
(((TIO (s)) -> c_cc) [VTIME]) = 0;
#ifdef HAVE_TERMIOS_H
{
cc_t disable = (UX_PC_VDISABLE (fd));
(((TIO (s)) -> c_cc) [VSTOP]) = disable;
(((TIO (s)) -> c_cc) [VSTART]) = disable;
}
#endif
#else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
#ifdef HAVE_SGTTY_H
(s -> sg . sg_flags) &=~ (ECHO | CRMOD);
(s -> sg . sg_flags) |= (ANYP | CBREAK);
(s -> lmode) |= (LPASS8 | LNOFLSH);
(s -> tc . t_startc) = (-1);
(s -> tc . t_stopc) = (-1);
(s -> tc . t_eofc) = (-1);
(s -> tc . t_brkc) = (-1);
#ifdef HAVE_STRUCT_LTCHARS
(s -> ltc . t_rprntc) = (-1);
(s -> ltc . t_flushc) = (-1);
(s -> ltc . t_werasc) = (-1);
(s -> ltc . t_lnextc) = (-1);
#endif /* HAVE_STRUCT_LTCHARS */
#endif /* HAVE_SGTTY_H */
#endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
}
void
DEFUN (terminal_state_raw, (s, fd), Ttty_state * s AND int fd)
{
terminal_state_nonbuffered (s, fd, 0);
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
((TIO (s)) -> c_lflag) &=~ ISIG;
#else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
#ifdef HAVE_SGTTY_H
(s -> sg . sg_flags) &=~ CBREAK;
(s -> sg . sg_flags) |= RAW;
(s -> tc . t_intrc) = (-1);
(s -> tc . t_quitc) = (-1);
#ifdef HAVE_STRUCT_LTCHARS
(s -> ltc . t_suspc) = (-1);
(s -> ltc . t_dsuspc) = (-1);
#endif /* HAVE_STRUCT_LTCHARS */
#endif /* HAVE_SGTTY_H */
#endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
}
void
DEFUN (terminal_state_buffered, (s, channel),
Ttty_state * s AND
Tchannel channel)
{
Ttty_state * os = (& (TERMINAL_ORIGINAL_STATE (channel)));
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
((TIO (s)) -> c_lflag) |= (ICANON | ISIG);
((TIO (s)) -> c_lflag) |= (((TIO (os)) -> c_lflag) & ECHO);
#ifdef IEXTEN
((TIO (s)) -> c_lflag) |= (((TIO (os)) -> c_lflag) & IEXTEN);
#endif
((TIO (s)) -> c_iflag) = ((TIO (os)) -> c_iflag);
((TIO (s)) -> c_cflag) |= CS8;
((TIO (s)) -> c_cflag) &=~ PARENB;
(((TIO (s)) -> c_cc) [VMIN]) = (((TIO (os)) -> c_cc) [VMIN]);
(((TIO (s)) -> c_cc) [VTIME]) = (((TIO (os)) -> c_cc) [VTIME]);
#ifdef HAVE_TERMIOS_H
(((TIO (s)) -> c_cc) [VSTOP]) = (((TIO (os)) -> c_cc) [VSTOP]);
(((TIO (s)) -> c_cc) [VSTART]) = (((TIO (os)) -> c_cc) [VSTART]);
#endif
#else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
#ifdef HAVE_SGTTY_H
(s -> sg . sg_flags) &=~ (CBREAK | RAW);
(s -> sg . sg_flags) |= ANYP;
(s -> sg . sg_flags) |= ((os -> sg . sg_flags) & (ECHO | CRMOD));
(s -> lmode) &=~ LNOFLSH;
(s -> lmode) |= LPASS8;
(s -> tc . t_intrc) = (os -> tc . t_intrc);
(s -> tc . t_quitc) = (os -> tc . t_quitc);
(s -> tc . t_startc) = (os -> tc . t_startc);
(s -> tc . t_stopc) = (os -> tc . t_stopc);
(s -> tc . t_eofc) = (os -> tc . t_eofc);
(s -> tc . t_brkc) = (os -> tc . t_brkc);
#ifdef HAVE_STRUCT_LTCHARS
(s -> ltc . t_suspc) = (os -> ltc . t_suspc);
(s -> ltc . t_dsuspc) = (os -> ltc . t_dsuspc);
(s -> ltc . t_rprntc) = (os -> ltc . t_rprntc);
(s -> ltc . t_flushc) = (os -> ltc . t_flushc);
(s -> ltc . t_werasc) = (os -> ltc . t_werasc);
(s -> ltc . t_lnextc) = (os -> ltc . t_lnextc);
#endif /* HAVE_STRUCT_LTCHARS */
#endif /* HAVE_SGTTY_H */
#endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
}
unsigned int
DEFUN (OS_terminal_get_ispeed, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
return (terminal_state_get_ispeed (&s));
}
unsigned int
DEFUN (OS_terminal_get_ospeed, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
return (terminal_state_get_ospeed (&s));
}
void
DEFUN (OS_terminal_set_ispeed, (channel, baud),
Tchannel channel AND
unsigned int baud)
{
Ttty_state s;
get_terminal_state (channel, (&s));
terminal_state_set_ispeed ((&s), baud);
set_terminal_state (channel, (&s));
}
void
DEFUN (OS_terminal_set_ospeed, (channel, baud),
Tchannel channel AND
unsigned int baud)
{
Ttty_state s;
get_terminal_state (channel, (&s));
terminal_state_set_ospeed ((&s), baud);
set_terminal_state (channel, (&s));
}
unsigned int
DEFUN (arg_baud_index, (argument), unsigned int argument)
{
unsigned long index = (arg_nonnegative_integer (argument));
switch (index)
{
case B0:
case B50:
case B75:
case B110:
case B134:
case B150:
case B200:
case B300:
case B600:
case B1200:
case B1800:
case B2400:
case B4800:
case B9600:
case B19200:
case B38400:
#ifdef B57600
case B57600:
#endif
#ifdef B115200
case B115200:
#endif
#ifdef B230400
case B230400:
#endif
#ifdef B460800
case B460800:
#endif
#ifdef B500000
case B500000:
#endif
#ifdef B576000
case B576000:
#endif
#ifdef B921600
case B921600:
#endif
#ifdef B1000000
case B1000000:
#endif
#ifdef B1152000
case B1152000:
#endif
#ifdef B1500000
case B1500000:
#endif
#ifdef B2000000
case B2000000:
#endif
#ifdef B2500000
case B2500000:
#endif
#ifdef B3000000
case B3000000:
#endif
#ifdef B3500000
case B3500000:
#endif
#ifdef B4000000
case B4000000:
#endif
break;
default:
error_bad_range_arg (argument);
}
return (index);
}
unsigned int
DEFUN (OS_baud_index_to_rate, (index), unsigned int index)
{
switch (index)
{
case B0: return (0);
case B50: return (50);
case B75: return (75);
case B110: return (110);
case B134: return (134);
case B150: return (150);
case B200: return (200);
case B300: return (300);
case B600: return (600);
case B1200: return (1200);
case B1800: return (1800);
case B2400: return (2400);
case B4800: return (4800);
case B9600: return (9600);
case B19200: return (19200);
case B38400: return (38400);
#ifdef B57600
case B57600: return (57600);
#endif
#ifdef B115200
case B115200: return (115200);
#endif
#ifdef B230400
case B230400: return (230400);
#endif
#ifdef B460800
case B460800: return (460800);
#endif
#ifdef B500000
case B500000: return (500000);
#endif
#ifdef B576000
case B576000: return (576000);
#endif
#ifdef B921600
case B921600: return (921600);
#endif
#ifdef B1000000
case B1000000: return (1000000);
#endif
#ifdef B1152000
case B1152000: return (1152000);
#endif
#ifdef B1500000
case B1500000: return (1500000);
#endif
#ifdef B2000000
case B2000000: return (2000000);
#endif
#ifdef B2500000
case B2500000: return (2500000);
#endif
#ifdef B3000000
case B3000000: return (3000000);
#endif
#ifdef B3500000
case B3500000: return (3500000);
#endif
#ifdef B4000000
case B4000000: return (4000000);
#endif
default: abort (); return (0);
}
}
int
DEFUN (OS_baud_rate_to_index, (rate), unsigned int rate)
{
switch (rate)
{
case 0: return (B0);
case 50: return (B50);
case 75: return (B75);
case 110: return (B110);
case 134: return (B134);
case 150: return (B150);
case 200: return (B200);
case 300: return (B300);
case 600: return (B600);
case 1200: return (B1200);
case 1800: return (B1800);
case 2400: return (B2400);
case 4800: return (B4800);
case 9600: return (B9600);
case 19200: return (B19200);
case 38400: return (B38400);
#ifdef B57600
case 57600: return (B57600);
#endif
#ifdef B115200
case 115200: return (B115200);
#endif
#ifdef B230400
case 230400: return (B230400);
#endif
#ifdef B460800
case 460800: return (B460800);
#endif
#ifdef B500000
case 500000: return (B500000);
#endif
#ifdef B576000
case 576000: return (B576000);
#endif
#ifdef B921600
case 921600: return (B921600);
#endif
#ifdef B1000000
case 1000000: return (B1000000);
#endif
#ifdef B1152000
case 1152000: return (B1152000);
#endif
#ifdef B1500000
case 1500000: return (B1500000);
#endif
#ifdef B2000000
case 2000000: return (B2000000);
#endif
#ifdef B2500000
case 2500000: return (B2500000);
#endif
#ifdef B3000000
case 3000000: return (B3000000);
#endif
#ifdef B3500000
case 3500000: return (B3500000);
#endif
#ifdef B4000000
case 4000000: return (B4000000);
#endif
default: return (-1);
}
}
unsigned int
DEFUN_VOID (OS_terminal_state_size)
{
return (sizeof (Ttty_state));
}
void
DEFUN (OS_terminal_get_state, (channel, statep),
Tchannel channel AND
PTR statep)
{
get_terminal_state (channel, statep);
}
void
DEFUN (OS_terminal_set_state, (channel, statep),
Tchannel channel AND
PTR statep)
{
set_terminal_state (channel, statep);
}
int
DEFUN (OS_terminal_cooked_output_p, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
return (terminal_state_cooked_output_p (&s));
}
void
DEFUN (OS_terminal_raw_output, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
terminal_state_raw_output (&s);
set_terminal_state (channel, (&s));
}
void
DEFUN (OS_terminal_cooked_output, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
terminal_state_cooked_output ((&s), channel);
set_terminal_state (channel, (&s));
}
int
DEFUN (OS_terminal_buffered_p, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
return (terminal_state_buffered_p (&s));
}
void
DEFUN (OS_terminal_buffered, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
terminal_state_buffered ((&s), channel);
set_terminal_state (channel, (&s));
}
void
DEFUN (OS_terminal_nonbuffered, (channel), Tchannel channel)
{
Ttty_state s;
get_terminal_state (channel, (&s));
terminal_state_nonbuffered ((&s), (CHANNEL_DESCRIPTOR (channel)), 0);
set_terminal_state (channel, (&s));
}
void
DEFUN (OS_terminal_flush_input, (channel), Tchannel channel)
{
STD_VOID_SYSTEM_CALL
(syscall_tcflush, (UX_tcflush ((CHANNEL_DESCRIPTOR (channel)), TCIFLUSH)));
}
void
DEFUN (OS_terminal_flush_output, (channel), Tchannel channel)
{
STD_VOID_SYSTEM_CALL
(syscall_tcflush, (UX_tcflush ((CHANNEL_DESCRIPTOR (channel)), TCOFLUSH)));
}
void
DEFUN (OS_terminal_drain_output, (channel), Tchannel channel)
{
STD_VOID_SYSTEM_CALL
(syscall_tcdrain, (UX_tcdrain (CHANNEL_DESCRIPTOR (channel))));
}
int
DEFUN_VOID (OS_job_control_p)
{
return (UX_SC_JOB_CONTROL ());
}
int
DEFUN_VOID (OS_have_ptys_p)
{
#ifdef HAVE_GRANTPT
return (1);
#else
static int result = 0;
static int result_valid = 0;
const char * p1;
if (result_valid)
return (result);
for (p1 = "pqrstuvwxyzPQRST"; ((*p1) != 0); p1 += 1)
{
char master_name [24];
struct stat s;
sprintf (master_name, "/dev/pty%c0", (*p1));
retry_stat:
if ((UX_stat (master_name, (&s))) < 0)
{
if (errno == EINTR)
goto retry_stat;
continue;
}
result = 1;
result_valid = 1;
return (result);
}
result = 0;
result_valid = 1;
return (result);
#endif
}
static CONST char *
DEFUN (open_pty_master_bsd, (master_fd, master_fname),
Tchannel * master_fd AND
CONST char ** master_fname)
{
static char master_name [24];
static char slave_name [24];
const char * p1;
const char * p2;
int fd;
for (p1 = "pqrstuvwxyzPQRST"; ((*p1) != 0); p1 += 1)
for (p2 = "0123456789abcdef"; ((*p2) != 0); p2 += 1)
{
sprintf (master_name, "/dev/pty%c%c", (*p1), (*p2));
sprintf (slave_name, "/dev/tty%c%c", (*p1), (*p2));
retry_open:
fd = (UX_open (master_name, O_RDWR, 0));
if (fd < 0)
{
if (errno == ENOENT)
return (0);
if (errno != EINTR)
continue;
deliver_pending_interrupts ();
goto retry_open;
}
if ((UX_access (slave_name, (R_OK | W_OK))) < 0)
{
UX_close (fd);
continue;
}
MAKE_CHANNEL (fd, channel_type_unix_pty_master, (*master_fd) =);
(*master_fname) = master_name;
return (slave_name);
}
return (0);
}
/* Open an available pty, putting channel in (*ptyv),
and return the file name of the pty.
Signal error if none available. */
CONST char *
DEFUN (OS_open_pty_master, (master_fd, master_fname),
Tchannel * master_fd AND
CONST char ** master_fname)
{
#ifdef HAVE_GRANTPT
while (1)
{
static char slave_name [24];
int fd = (UX_open ("/dev/ptmx", O_RDWR, 0));
if (fd < 0)
{
if (errno == EINTR)
{
deliver_pending_interrupts ();
continue;
}
/* Try BSD open. This is needed for Linux which might have
Unix98 support in the library but not the kernel. */
return (open_pty_master_bsd (master_fd, master_fname));
}
#ifdef sonyrisc
sony_block_sigchld ();
#endif
grantpt (fd);
unlockpt (fd);
strcpy (slave_name, (ptsname (fd)));
#ifdef sonyrisc
sony_unblock_sigchld ();
#endif
MAKE_CHANNEL (fd, channel_type_unix_pty_master, (*master_fd) =);
(*master_fname) = "/dev/ptmx";
return (slave_name);
}
#else /* not HAVE_GRANTPT */
if (!OS_have_ptys_p ())
error_unimplemented_primitive ();
return (open_pty_master_bsd (master_fd, master_fname));
#endif /* not HAVE_GRANTPT */
}
void
DEFUN (OS_pty_master_send_signal, (channel, sig), Tchannel channel AND int sig)
{
#ifdef TIOCSIGSEND
STD_VOID_SYSTEM_CALL
(syscall_ioctl_TIOCSIGSEND,
(UX_ioctl ((CHANNEL_DESCRIPTOR (channel)), TIOCSIGSEND, sig)));
#else
int gid = (UX_tcgetpgrp (CHANNEL_DESCRIPTOR (channel)));
if (gid < 0)
{
if (errno == ENOSYS)
error_unimplemented_primitive ();
else
error_system_call (errno, syscall_tcgetpgrp);
}
STD_VOID_SYSTEM_CALL (syscall_kill, (UX_kill ((-gid), sig)));
#endif
}
void
DEFUN (OS_pty_master_kill, (channel), Tchannel channel)
{
OS_pty_master_send_signal (channel, SIGKILL);
}
void
DEFUN (OS_pty_master_stop, (channel), Tchannel channel)
{
OS_pty_master_send_signal (channel, SIGTSTP);
}
void
DEFUN (OS_pty_master_continue, (channel), Tchannel channel)
{
OS_pty_master_send_signal (channel, SIGCONT);
}
void
DEFUN (OS_pty_master_interrupt, (channel), Tchannel channel)
{
OS_pty_master_send_signal (channel, SIGINT);
}
void
DEFUN (OS_pty_master_quit, (channel), Tchannel channel)
{
OS_pty_master_send_signal (channel, SIGQUIT);
}
void
DEFUN (OS_pty_master_hangup, (channel), Tchannel channel)
{
OS_pty_master_send_signal (channel, SIGHUP);
}