Split out tty and shared_info stuff into their own headers and use throughout.

Include sys/termios.h for files which need it.
* tty.h: New file.
* shared_info.h: New file.
* fhandler.h: Move inline methods that rely on tty stuff to
fhandler_console.cc.
* fhandler_tty.cc (fhandler_pty_master::process_slave_output): Set
output_done_event immediately after reading data to speed up tty output
processing.
(process_output): Set write_error to errno or zero.
(fhandler_tty_slave::write): Check previous write error prior to writing to
slave end of pipe.  This allows tty output to be slightly less synchronous.
* fhandler_console.cc (fhandler_console::tcsetpgrp): Moved here from
fhandler.h.
(fhandler_console::set_input_state): Ditto.
This commit is contained in:
Christopher Faylor 2000-09-07 16:23:51 +00:00
parent c1644acb23
commit 29ac7f89e3
24 changed files with 371 additions and 307 deletions

View File

@ -1,3 +1,22 @@
Thu Sep 7 12:14:43 2000 Christopher Faylor <cgf@cygnus.com>
Split out tty and shared_info stuff into their own headers and use
throughout. Include sys/termios.h for files which need it.
* tty.h: New file.
* shared_info.h: New file.
* fhandler.h: Move inline methods that rely on tty stuff to
fhandler_console.cc.
* fhandler_tty.cc (fhandler_pty_master::process_slave_output): Set
output_done_event immediately after reading data to speed up tty output
processing.
(process_output): Set write_error to errno or zero.
(fhandler_tty_slave::write): Check previous write error prior to
writing to slave end of pipe. This allows tty output to be slightly
less synchronous.
* fhandler_console.cc (fhandler_console::tcsetpgrp): Moved here from
fhandler.h.
(fhandler_console::set_input_state): Ditto.
Wed Sep 6 21:11:13 2000 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (signal_exit): Reset all mutos owned by the main

View File

@ -28,6 +28,8 @@ details. */
#include "path.h"
#include "dtable.h"
#include "thread.h"
#include "tty.h"
#include "shared_info.h"
#define MAX_AT_FILE_LEVEL 10

View File

@ -20,6 +20,8 @@ details. */
#include "cygerrno.h"
#include "thread.h"
#include "perthread.h"
#include "tty.h"
#include "shared_info.h"
char debugger_command[2 * MAX_PATH + 20];

View File

@ -16,6 +16,8 @@ details. */
#include "sigproc.h"
#include "pinfo.h"
#include <exceptions.h>
#include "tty.h"
#include "shared_info.h"
static external_pinfo *
fillout_pinfo (pid_t pid, int winpid)

View File

@ -18,6 +18,8 @@ details. */
#include "cygerrno.h"
#include "fhandler.h"
#include "path.h"
#include "tty.h"
#include "shared_info.h"
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */

View File

@ -511,6 +511,8 @@ public:
#define release_output_mutex() \
__release_output_mutex (__PRETTY_FUNCTION__, __LINE__);
class tty;
class tty_min;
class fhandler_termios: public fhandler_base
{
protected:
@ -594,7 +596,7 @@ public:
int tcsetattr (int a, const struct termios *t);
int tcgetattr (struct termios *t);
int tcsetpgrp (const pid_t pid) { tc->pgid = pid; return 0; }
int tcsetpgrp (const pid_t pid);
/* Special dup as we must dup two handles */
int dup (fhandler_base *child);
@ -609,11 +611,7 @@ public:
void fixup_after_exec (HANDLE);
void set_close_on_exec (int val);
void fixup_after_fork (HANDLE parent);
void set_input_state ()
{
if (TTYISSETF (RSTCONS))
input_tcsetattr (0, &tc->ti);
}
void set_input_state ();
};
class fhandler_tty_common: public fhandler_termios

View File

@ -24,6 +24,8 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "tty.h"
#include "shared_info.h"
/*
* Scroll the screen context.
@ -249,6 +251,21 @@ fhandler_console::read (void *pv, size_t buflen)
return copied_chars;
}
int
fhandler_console::tcsetpgrp (pid_t pid)
{
tc->pgid = pid;
return 0;
}
void
fhandler_console::set_input_state ()
{
if (TTYISSETF (RSTCONS))
input_tcsetattr (0, &tc->ti);
}
static struct
{
SHORT winTop;

View File

@ -18,6 +18,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include <sys/termios.h>
/**********************************************************************/
/* fhandler_serial */

View File

@ -19,6 +19,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "tty.h"
/* Common functions shared by tty/console */

View File

@ -23,6 +23,8 @@ details. */
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "tty.h"
#include "shared_info.h"
/* Tty master stuff */
@ -285,14 +287,12 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
}
termios_printf ("bytes read %u", n);
get_ttyp ()->write_error = 0;
if (output_done_event != NULL)
SetEvent (output_done_event);
if (get_ttyp ()->ti.c_lflag & FLUSHO)
{
get_ttyp ()->write_retval = n;
if (output_done_event != NULL)
SetEvent (output_done_event);
continue;
}
continue;
char *optr;
optr = buf;
@ -389,8 +389,7 @@ process_output (void *)
ExitThread (0);
}
n = tty_master->console->write ((void *) buf, (size_t) n);
tty_master->get_ttyp ()->write_retval = n == -1 ? -get_errno () : n;
SetEvent (tty_master->output_done_event);
tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0;
}
}
@ -554,6 +553,16 @@ fhandler_tty_slave::write (const void *ptr, size_t len)
ptr = (char *) ptr + n;
len -= n;
/* Previous write may have set write_error to != 0. Check it here.
This is less than optimal, but the alternative slows down tty
writes enormously. */
if (get_ttyp ()->write_error)
{
set_errno (get_ttyp ()->write_error);
towrite = (DWORD) -1;
break;
}
if (WriteFile (get_output_handle (), buf, n, &n, NULL) == FALSE)
{
DWORD err = GetLastError ();
@ -577,13 +586,6 @@ fhandler_tty_slave::write (const void *ptr, size_t len)
rc = WaitForSingleObject (output_done_event, x);
termios_printf("waited %d ms for output_done_event, WFSO %d", x, rc);
}
if (get_ttyp ()->write_retval < 0)
{
set_errno (-get_ttyp ()->write_retval);
towrite = (DWORD) -1;
break;
}
}
release_output_mutex ();
return towrite;
@ -931,12 +933,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
int
fhandler_pty_master::read (void *ptr, size_t len)
{
int x = process_slave_output ((char *) ptr, len, pktmode);
if (output_done_event != NULL)
SetEvent (output_done_event);
return x;
return process_slave_output ((char *) ptr, len, pktmode);
}
int

View File

@ -15,6 +15,8 @@ details. */
#include "sigproc.h"
#include "pinfo.h"
#include "heap.h"
#include "tty.h"
#include "shared_info.h"
#define assert(x)

View File

@ -17,6 +17,7 @@ details. */
#include "cygerrno.h"
#include "fhandler.h"
#include "dtable.h"
#include <sys/termios.h>
extern "C" int
ioctl (int fd, int cmd, void *buf)

View File

@ -20,6 +20,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include <sys/termios.h>
/* Read /etc/passwd only once for better performance. This is done
on the first call that needs information from it. */

View File

@ -65,6 +65,8 @@ details. */
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include "tty.h"
#include "shared_info.h"
static int normalize_win32_path (const char *src, char *dst);
static void slashify (const char *src, char *dst, int trailing_slash_p);

View File

@ -9,6 +9,8 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
#include "tty.h"
#include "shared_info.h"
char cygnus_class[] = "cygnus";

View File

@ -39,6 +39,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "perthread.h"
#include "tty.h"
/*
* All these defines below should be in sys/types.h

View File

@ -17,6 +17,8 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "tty.h"
#include "shared_info.h"
#define SHAREDVER (unsigned)(cygwin_version.api_major << 16 | \
cygwin_version.api_minor)

View File

@ -80,270 +80,14 @@ public:
char *__stdcall get_registry_hive_path (const PSID psid, char *path);
void __stdcall load_registry_hive (PSID psid);
/******** Mount Table ********/
/* Mount table entry */
class mount_item
{
public:
/* FIXME: Nasty static allocation. Need to have a heap in the shared
area [with the user being able to configure at runtime the max size]. */
/* Win32-style mounted partition source ("C:\foo\bar").
native_path[0] == 0 for unused entries. */
char native_path[MAX_PATH];
int native_pathlen;
/* POSIX-style mount point ("/foo/bar") */
char posix_path[MAX_PATH];
int posix_pathlen;
unsigned flags;
void init (const char *dev, const char *path, unsigned flags);
struct mntent *getmntent ();
};
/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
higher numbered registry entries. Don't change this number willy-nilly.
What we need is to have a more dynamic allocation scheme, but the current
scheme should be satisfactory for a long while yet. */
#define MAX_MOUNTS 30
class mount_info
{
int posix_sorted[MAX_MOUNTS];
int native_sorted[MAX_MOUNTS];
public:
int nmounts;
mount_item mount[MAX_MOUNTS];
/* Strings used by getmntent(). */
char mnt_type[20];
char mnt_opts[20];
char mnt_fsname[MAX_PATH];
char mnt_dir[MAX_PATH];
/* cygdrive_prefix is used as the root of the path automatically
prepended to a path when the path has no associated mount.
cygdrive_flags are the default flags for the cygdrives. */
char cygdrive[MAX_PATH];
size_t cygdrive_len;
unsigned cygdrive_flags;
/* Increment when setting up a reg_key if mounts area had to be
created so we know when we need to import old mount tables. */
int had_to_create_mount_areas;
void init ();
int add_item (const char *dev, const char *path, unsigned flags, int reg_p);
int del_item (const char *path, unsigned flags, int reg_p);
void from_registry ();
int add_reg_mount (const char * native_path, const char * posix_path,
unsigned mountflags);
int del_reg_mount (const char * posix_path, unsigned mountflags);
unsigned set_flags_from_win32_path (const char *path);
int conv_to_win32_path (const char *src_path, char *win32_path,
char *full_win32_path, DWORD &devn, int &unit,
unsigned *flags = NULL);
int conv_to_posix_path (const char *src_path, char *posix_path,
int keep_rel_p);
struct mntent *getmntent (int x);
int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags);
int get_cygdrive_prefixes (char *user, char *system);
void import_v1_mounts ();
private:
void sort ();
void read_mounts (reg_key& r);
void read_v1_mounts (reg_key r, unsigned which);
void mount_slash ();
void to_registry ();
int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
void slash_drive_to_win32_path (const char *path, char *buf, int trailing_slash_p);
void read_cygdrive_info_from_registry ();
};
/******** TTY Support ********/
/* tty tables */
#define INP_BUFFER_SIZE 256
#define OUT_BUFFER_SIZE 256
#define NTTYS 128
#define TTY_CONSOLE 0x40000000
#define tty_attached(p) ((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
/* Input/Output/ioctl events */
#define OUTPUT_DONE_EVENT "cygtty%d.output.done"
#define IOCTL_REQUEST_EVENT "cygtty%d.ioctl.request"
#define IOCTL_DONE_EVENT "cygtty%d.ioctl.done"
#define RESTART_OUTPUT_EVENT "cygtty%d.output.restart"
#define OUTPUT_MUTEX "cygtty%d.output.mutex"
#define TTY_SLAVE_ALIVE "cygtty%x.slave_alive"
#define TTY_MASTER_ALIVE "cygtty%x.master_alive"
#include <sys/termios.h>
enum
{
TTY_INITIALIZED = 1, /* Set if tty is initialized */
TTY_RSTCONS = 2 /* Set if console needs to be set to "non-cooked" */
};
#define TTYISSETF(x) __ISSETF (tc, x, TTY)
#define TTYSETF(x) __SETF (tc, x, TTY)
#define TTYCLEARF(x) __CLEARF (tc, x, TTY)
#define TTYCONDSETF(n, x) __CONDSETF(n, tc, x, TTY)
#ifndef MIN_CTRL_C_SLOP
#define MIN_CTRL_C_SLOP 50
#endif
class tty_min
{
pid_t sid; /* Session ID of tty */
public:
DWORD status;
pid_t pgid;
int OutputStopped;
int ntty;
DWORD last_ctrl_c; // tick count of last ctrl-c
tty_min (int t = -1, pid_t s = -1) : sid (s), ntty (t) {}
void setntty (int n) {ntty = n;}
pid_t getpgid () {return pgid;}
void setpgid (int pid) {pgid = pid;}
int getsid () {return sid;}
void setsid (pid_t tsid) {sid = tsid;}
struct termios ti;
struct winsize winsize;
/* ioctl requests buffer */
int cmd;
union
{
struct termios termios;
struct winsize winsize;
int value;
pid_t pid;
} arg;
/* XXX_retval variables holds master's completion codes. Error are stored as
* -ERRNO
*/
int ioctl_retval;
int write_retval;
};
class fhandler_pty_master;
class tty: public tty_min
{
HANDLE get_event (const char *fmt, BOOL inherit);
public:
HWND hwnd; /* Console window handle tty belongs to */
DWORD master_pid; /* Win32 PID of tty master process */
HANDLE from_master, to_slave;
HANDLE from_slave, to_master;
int read_retval;
BOOL was_opened; /* True if opened at least once. */
void init ();
HANDLE create_inuse (const char *);
BOOL common_init (fhandler_pty_master *);
BOOL alive (const char *fmt);
BOOL slave_alive ();
BOOL master_alive ();
HWND gethwnd () {return hwnd;}
void sethwnd (HWND wnd) {hwnd = wnd;}
int make_pipes (fhandler_pty_master *ptym);
HANDLE open_output_mutex (BOOL inherit = FALSE)
{
char buf[80];
__small_sprintf (buf, OUTPUT_MUTEX, ntty);
return OpenMutex (MUTEX_ALL_ACCESS, inherit, buf);
}
BOOL exists ()
{
HANDLE h = open_output_mutex ();
if (h)
{
CloseHandle (h);
return 1;
}
return slave_alive ();
}
};
class tty_list
{
tty ttys[NTTYS];
public:
tty * operator [](int n) {return ttys + n;}
int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */
int connect_tty (int);
void terminate ();
void init ();
tty_min *get_tty (int n);
};
void __stdcall tty_init ();
void __stdcall tty_terminate ();
int __stdcall attach_tty (int);
void __stdcall create_tty_master (int);
extern "C" int ttyslot (void);
/******** Shared Info ********/
/* Data accessible to all tasks */
class shared_info
{
DWORD inited;
public:
/* FIXME: Doesn't work if more than one user on system. */
mount_info mount;
int heap_chunk_in_mb;
unsigned heap_chunk_size (void);
tty_list tty;
delqueue_list delqueue;
void initialize (void);
};
/* Various types of security attributes for use in Create* functions. */
extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih;
extern SECURITY_ATTRIBUTES *__stdcall sec_user (PVOID sa_buf, PSID sid2 = NULL, BOOL inherit = TRUE);
extern SECURITY_ATTRIBUTES *__stdcall sec_user_nih (PVOID sa_buf, PSID sid2 = NULL);
extern shared_info *cygwin_shared;
extern HANDLE cygwin_shared_h;
extern HANDLE console_shared_h;
extern int __stdcall set_console_state_for_spawn ();
void __stdcall shared_init (void);
void __stdcall shared_terminate (void);
char *__stdcall shared_name (const char *, int);
void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);
extern "C" {
/* This is for programs that want to access the shared data. */
class shared_info *cygwin_getshared (void);

130
winsup/cygwin/shared_info.h Normal file
View File

@ -0,0 +1,130 @@
/* shared_sec.h: shared info for cygwin
Copyright 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
/* Mount table entry */
class mount_item
{
public:
/* FIXME: Nasty static allocation. Need to have a heap in the shared
area [with the user being able to configure at runtime the max size]. */
/* Win32-style mounted partition source ("C:\foo\bar").
native_path[0] == 0 for unused entries. */
char native_path[MAX_PATH];
int native_pathlen;
/* POSIX-style mount point ("/foo/bar") */
char posix_path[MAX_PATH];
int posix_pathlen;
unsigned flags;
void init (const char *dev, const char *path, unsigned flags);
struct mntent *getmntent ();
};
/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
higher numbered registry entries. Don't change this number willy-nilly.
What we need is to have a more dynamic allocation scheme, but the current
scheme should be satisfactory for a long while yet. */
#define MAX_MOUNTS 30
class mount_info
{
int posix_sorted[MAX_MOUNTS];
int native_sorted[MAX_MOUNTS];
public:
int nmounts;
mount_item mount[MAX_MOUNTS];
/* Strings used by getmntent(). */
char mnt_type[20];
char mnt_opts[20];
char mnt_fsname[MAX_PATH];
char mnt_dir[MAX_PATH];
/* cygdrive_prefix is used as the root of the path automatically
prepended to a path when the path has no associated mount.
cygdrive_flags are the default flags for the cygdrives. */
char cygdrive[MAX_PATH];
size_t cygdrive_len;
unsigned cygdrive_flags;
/* Increment when setting up a reg_key if mounts area had to be
created so we know when we need to import old mount tables. */
int had_to_create_mount_areas;
void init ();
int add_item (const char *dev, const char *path, unsigned flags, int reg_p);
int del_item (const char *path, unsigned flags, int reg_p);
void from_registry ();
int add_reg_mount (const char * native_path, const char * posix_path,
unsigned mountflags);
int del_reg_mount (const char * posix_path, unsigned mountflags);
unsigned set_flags_from_win32_path (const char *path);
int conv_to_win32_path (const char *src_path, char *win32_path,
char *full_win32_path, DWORD &devn, int &unit,
unsigned *flags = NULL);
int conv_to_posix_path (const char *src_path, char *posix_path,
int keep_rel_p);
struct mntent *getmntent (int x);
int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags);
int get_cygdrive_prefixes (char *user, char *system);
void import_v1_mounts ();
private:
void sort ();
void read_mounts (reg_key& r);
void read_v1_mounts (reg_key r, unsigned which);
void mount_slash ();
void to_registry ();
int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
void slash_drive_to_win32_path (const char *path, char *buf, int trailing_slash_p);
void read_cygdrive_info_from_registry ();
};
/******** Shared Info ********/
/* Data accessible to all tasks */
class shared_info
{
DWORD inited;
public:
/* FIXME: Doesn't work if more than one user on system. */
mount_info mount;
int heap_chunk_in_mb;
unsigned heap_chunk_size (void);
tty_list tty;
delqueue_list delqueue;
void initialize (void);
};
extern shared_info *cygwin_shared;
extern HANDLE cygwin_shared_h;
extern HANDLE console_shared_h;
void __stdcall shared_init (void);
void __stdcall shared_terminate (void);
char *__stdcall shared_name (const char *, int);
void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);

View File

@ -24,6 +24,8 @@ details. */
#include "child_info.h"
#include "perthread.h"
#include <assert.h>
#include "tty.h"
#include "shared_info.h"
/*
* Convenience defines

View File

@ -32,6 +32,8 @@ details. */
#include "sigproc.h"
#include "pinfo.h"
#include <unistd.h>
#include "tty.h"
#include "shared_info.h"
extern BOOL allow_ntsec;

View File

@ -16,10 +16,10 @@ details. */
#include "cygerrno.h"
#include "fhandler.h"
#include "dtable.h"
#include <sys/termios.h>
/* tcsendbreak: POSIX 7.2.2.1 */
extern "C"
int
extern "C" int
tcsendbreak (int fd, int duration)
{
int res = -1;
@ -47,8 +47,7 @@ out:
}
/* tcdrain: POSIX 7.2.2.1 */
extern "C"
int
extern "C" int
tcdrain (int fd)
{
int res = -1;
@ -78,8 +77,7 @@ out:
}
/* tcflush: POSIX 7.2.2.1 */
extern "C"
int
extern "C" int
tcflush (int fd, int queue)
{
int res = -1;
@ -107,8 +105,7 @@ out:
}
/* tcflow: POSIX 7.2.2.1 */
extern "C"
int
extern "C" int
tcflow (int fd, int action)
{
int res = -1;
@ -136,8 +133,7 @@ out:
}
/* tcsetattr: POSIX96 7.2.1.1 */
extern "C"
int
extern "C" int
tcsetattr (int fd, int a, const struct termios *t)
{
int res = -1;
@ -169,8 +165,7 @@ out:
}
/* tcgetattr: POSIX 7.2.1.1 */
extern "C"
int
extern "C" int
tcgetattr (int fd, struct termios *in_t)
{
int res = -1;
@ -197,8 +192,7 @@ tcgetattr (int fd, struct termios *in_t)
}
/* tcgetpgrp: POSIX 7.2.3.1 */
extern "C"
int
extern "C" int
tcgetpgrp (int fd)
{
int res = -1;
@ -215,8 +209,7 @@ tcgetpgrp (int fd)
}
/* tcsetpgrp: POSIX 7.2.4.1 */
extern "C"
int
extern "C" int
tcsetpgrp (int fd, pid_t pgid)
{
int res = -1;
@ -239,24 +232,21 @@ tcsetpgrp (int fd, pid_t pgid)
#undef cfsetispeed
/* cfgetospeed: POSIX96 7.1.3.1 */
extern "C"
speed_t
extern "C" speed_t
cfgetospeed (struct termios *tp)
{
return __tonew_termios(tp)->c_ospeed;
}
/* cfgetispeed: POSIX96 7.1.3.1 */
extern "C"
speed_t
extern "C" speed_t
cfgetispeed (struct termios *tp)
{
return __tonew_termios(tp)->c_ispeed;
}
/* cfsetospeed: POSIX96 7.1.3.1 */
extern "C"
int
extern "C" int
cfsetospeed (struct termios *in_tp, speed_t speed)
{
struct termios *tp = __tonew_termios (in_tp);
@ -266,8 +256,7 @@ cfsetospeed (struct termios *in_tp, speed_t speed)
}
/* cfsetispeed: POSIX96 7.1.3.1 */
extern "C"
int
extern "C" int
cfsetispeed (struct termios *in_tp, speed_t speed)
{
struct termios *tp = __tonew_termios (in_tp);

View File

@ -20,6 +20,8 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "tty.h"
#include "shared_info.h"
extern fhandler_tty_master *tty_master;

143
winsup/cygwin/tty.h Normal file
View File

@ -0,0 +1,143 @@
/* tty.h: shared info for cygwin
Copyright 2000 Cygnus Solutions.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
/* tty tables */
#define INP_BUFFER_SIZE 256
#define OUT_BUFFER_SIZE 256
#define NTTYS 128
#define TTY_CONSOLE 0x40000000
#define tty_attached(p) ((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
/* Input/Output/ioctl events */
#define OUTPUT_DONE_EVENT "cygtty%d.output.done"
#define IOCTL_REQUEST_EVENT "cygtty%d.ioctl.request"
#define IOCTL_DONE_EVENT "cygtty%d.ioctl.done"
#define RESTART_OUTPUT_EVENT "cygtty%d.output.restart"
#define OUTPUT_MUTEX "cygtty%d.output.mutex"
#define TTY_SLAVE_ALIVE "cygtty%x.slave_alive"
#define TTY_MASTER_ALIVE "cygtty%x.master_alive"
#include <sys/termios.h>
enum
{
TTY_INITIALIZED = 1, /* Set if tty is initialized */
TTY_RSTCONS = 2 /* Set if console needs to be set to "non-cooked" */
};
#define TTYISSETF(x) __ISSETF (tc, x, TTY)
#define TTYSETF(x) __SETF (tc, x, TTY)
#define TTYCLEARF(x) __CLEARF (tc, x, TTY)
#define TTYCONDSETF(n, x) __CONDSETF(n, tc, x, TTY)
#ifndef MIN_CTRL_C_SLOP
#define MIN_CTRL_C_SLOP 50
#endif
class tty_min
{
pid_t sid; /* Session ID of tty */
public:
DWORD status;
pid_t pgid;
int OutputStopped;
int ntty;
DWORD last_ctrl_c; // tick count of last ctrl-c
tty_min (int t = -1, pid_t s = -1) : sid (s), ntty (t) {}
void setntty (int n) {ntty = n;}
pid_t getpgid () {return pgid;}
void setpgid (int pid) {pgid = pid;}
int getsid () {return sid;}
void setsid (pid_t tsid) {sid = tsid;}
struct termios ti;
struct winsize winsize;
/* ioctl requests buffer */
int cmd;
union
{
struct termios termios;
struct winsize winsize;
int value;
pid_t pid;
} arg;
/* XXX_retval variables holds master's completion codes. Error are stored as
* -ERRNO
*/
int ioctl_retval;
int write_error;
};
class fhandler_pty_master;
class tty: public tty_min
{
HANDLE get_event (const char *fmt, BOOL inherit);
public:
HWND hwnd; /* Console window handle tty belongs to */
DWORD master_pid; /* Win32 PID of tty master process */
HANDLE from_master, to_slave;
HANDLE from_slave, to_master;
int read_retval;
BOOL was_opened; /* True if opened at least once. */
void init ();
HANDLE create_inuse (const char *);
BOOL common_init (fhandler_pty_master *);
BOOL alive (const char *fmt);
BOOL slave_alive ();
BOOL master_alive ();
HWND gethwnd () {return hwnd;}
void sethwnd (HWND wnd) {hwnd = wnd;}
int make_pipes (fhandler_pty_master *ptym);
HANDLE open_output_mutex (BOOL inherit = FALSE)
{
char buf[80];
__small_sprintf (buf, OUTPUT_MUTEX, ntty);
return OpenMutex (MUTEX_ALL_ACCESS, inherit, buf);
}
BOOL exists ()
{
HANDLE h = open_output_mutex ();
if (h)
{
CloseHandle (h);
return 1;
}
return slave_alive ();
}
};
class tty_list
{
tty ttys[NTTYS];
public:
tty * operator [](int n) {return ttys + n;}
int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */
int connect_tty (int);
void terminate ();
void init ();
tty_min *get_tty (int n);
};
void __stdcall tty_init ();
void __stdcall tty_terminate ();
int __stdcall attach_tty (int);
void __stdcall create_tty_master (int);
extern "C" int ttyslot (void);