diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5ae608356..cb70e4adb 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,35 @@ +2011-10-11 Christopher Faylor + + * cygwin.din: Remove some _tc* exports. Add tcgetsid(). + * dtable.cc (fh_alloc): Revert ill-advised setting of major/minor. Use + new is_dev_tty to remember that this device was opened as /dev/tty. + * fhandler.cc (fhandler_base::fstat): Remove leftover debugging + statement. + (fhandler_base::tcgetsid): New function. + * fhandler.h ((fhandler_base::tcgetsid): Declare new function. + (fhandler_base::is_dev_tty): Ditto. + (fhandler_termios::opened_as_dev_tty): Declare new field. + (fhandler_termios::is_dev_tty): Declare new function. + (fhandler_termios::tcgetsid): Ditto. + (fhandler_pty_common::use_archetype): Move here from subclass. + (fhandler_pty_slave::use_archetype): Move up. + (fhandler_pty_master::use_archetype): Ditto. + * fhandler_console.cc (fhandler_console::ioctl): Rename second argument + from `buf' to `arg' for consistency. Call ioctl_termios for common + fhandler_termios ioctl handling. + * fhandler_tty.cc (fhandler_pty_slave::ioctl): Call ioctl_termios for + common fhandler_termios ioctl handling. + (fhandler_pty_master::ioctl): Ditto. + * fhandler_termios.cc (fhandler_termios::tcgetsid): Implement new + function. + (fhandler_termios::ioctl_termios): Ditto. Implements TIOCSCTTY + handling. + * syscalls.cc (stat_worker): Set /dev/tty device info when appropriate. + * termios.cc (tcgetpgrp): Avoid extraneous "isatty" check. + (tcgetsid): Implement new function. + * include/cygwin/version.h: Bump CYGWIN_VERSION_API_MINOR to 253. + * include/sys/termios.h (TIOCSCTTY): Define. + 2011-10-11 Christopher Faylor * dtable.cc (fh_alloc): Don't parse /dev/tty if ctty is < 0. Reset diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index cc544a32a..c8c66c48c 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -1712,21 +1712,14 @@ _tanh = tanh NOSIGFE tanhf NOSIGFE _tanhf = tanhf NOSIGFE tcdrain SIGFE -_tcdrain = tcdrain SIGFE tcflow SIGFE -_tcflow = tcflow SIGFE tcflush SIGFE -_tcflush = tcflush SIGFE tcgetattr SIGFE -_tcgetattr = tcgetattr SIGFE tcgetpgrp SIGFE -_tcgetpgrp = tcgetpgrp SIGFE +tcgetsid SIGFE tcsendbreak SIGFE -_tcsendbreak = tcsendbreak SIGFE tcsetattr SIGFE -_tcsetattr = tcsetattr SIGFE tcsetpgrp SIGFE -_tcsetpgrp = tcsetpgrp SIGFE tdelete SIGFE tdestroy NOSIGFE telldir SIGFE diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index a53596fa1..f1175e3ac 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -547,8 +547,8 @@ fh_alloc (device dev) fh = cnew (fhandler_console, dev); else fh = cnew (fhandler_pty_slave, myself->ctty); - fh->dev () = FH_TTY; } + ((fhandler_termios *) fh)->is_dev_tty (true); break; } case FH_KMSG: diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 23e631e0f..f53a12419 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1167,6 +1167,7 @@ fhandler_base::ioctl (unsigned int cmd, void *buf) res = 0; break; case FIONREAD: + case TIOCSCTTY: set_errno (ENOTTY); res = -1; break; @@ -1190,8 +1191,6 @@ fhandler_base::lock (int, struct __flock64 *) int __stdcall fhandler_base::fstat (struct __stat64 *buf) { - debug_printf ("here"); - if (is_fs_special ()) return fstat_fs (buf); @@ -1391,6 +1390,13 @@ fhandler_base::tcgetpgrp () return -1; } +int +fhandler_base::tcgetsid () +{ + set_errno (ENOTTY); + return -1; +} + void fhandler_base::operator delete (void *p) { diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index cc391ae78..c11d8c834 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -377,6 +377,7 @@ public: virtual int tcgetattr (struct termios *t); virtual int tcsetpgrp (const pid_t pid); virtual int tcgetpgrp (); + virtual int tcgetsid (); virtual bool is_tty () const { return false; } virtual bool ispipe () const { return false; } virtual pid_t get_popen_pid () const {return 0;} @@ -426,6 +427,7 @@ public: bool device_access_denied (int) __attribute__ ((regparm (2))); int fhaccess (int flags, bool) __attribute__ ((regparm (3))); virtual bool __stdcall has_ongoing_io () __attribute__ ((regparm (1))) {return false;} + virtual bool is_dev_tty () const { return false; } }; struct wsa_event @@ -934,15 +936,20 @@ class tty_min; class fhandler_termios: public fhandler_base { protected: + bool opened_as_dev_tty; HANDLE output_handle; virtual void doecho (const void *, DWORD) {}; virtual int accept_input () {return 1;}; + int ioctl_termios (int, int); public: + bool is_dev_tty () const { return opened_as_dev_tty; } + bool is_dev_tty (bool val) { return opened_as_dev_tty = val; } tty_min *_tc; virtual tty_min *tc () const {return _tc; } fhandler_termios () : fhandler_base () { + opened_as_dev_tty = false; need_fork_fixup (true); } HANDLE& get_output_handle () { return output_handle; } @@ -959,6 +966,7 @@ class fhandler_termios: public fhandler_base virtual void __release_output_mutex (const char *fn, int ln) {} void echo_erase (int force = 0); virtual _off64_t lseek (_off64_t, int); + int tcgetsid (); virtual size_t size () const { return sizeof (*this);} /* probably not needed */ }; @@ -1159,6 +1167,7 @@ class fhandler_pty_common: public fhandler_termios HANDLE output_mutex, input_mutex; HANDLE input_available_event; + bool use_archetype () const {return true;} DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms); void __release_output_mutex (const char *fn, int ln); @@ -1184,7 +1193,6 @@ class fhandler_pty_slave: public fhandler_pty_common /* Constructor */ fhandler_pty_slave (int); - bool use_archetype () const {return true;} int open (int flags, mode_t mode = 0); void open_setup (int flags); ssize_t __stdcall write (const void *ptr, size_t len); @@ -1224,7 +1232,6 @@ public: /* Constructor */ fhandler_pty_master (); - virtual bool use_archetype () const {return true;} DWORD pty_master_thread (); int process_slave_output (char *buf, size_t len, int pktmode_on); void doecho (const void *str, DWORD len); diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index b7e4e26e9..9a8ddf8dc 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -839,8 +839,11 @@ fhandler_console::close () } int -fhandler_console::ioctl (unsigned int cmd, void *buf) +fhandler_console::ioctl (unsigned int cmd, void *arg) { + int res = ioctl_termios (cmd, (int) arg); + if (res <= 0) + return res; switch (cmd) { case TIOCGWINSZ: @@ -851,11 +854,11 @@ fhandler_console::ioctl (unsigned int cmd, void *buf) { /* *not* the buffer size, the actual screen size... */ /* based on Left Top Right Bottom of srWindow */ - ((struct winsize *) buf)->ws_row = dev_state.info.dwWinSize.Y; - ((struct winsize *) buf)->ws_col = dev_state.info.dwWinSize.X; + ((struct winsize *) arg)->ws_row = dev_state.info.dwWinSize.Y; + ((struct winsize *) arg)->ws_col = dev_state.info.dwWinSize.X; syscall_printf ("WINSZ: (row=%d,col=%d)", - ((struct winsize *) buf)->ws_row, - ((struct winsize *) buf)->ws_col); + ((struct winsize *) arg)->ws_row, + ((struct winsize *) arg)->ws_col); return 0; } else @@ -869,12 +872,12 @@ fhandler_console::ioctl (unsigned int cmd, void *buf) bg_check (SIGTTOU); return 0; case KDGKBMETA: - *(int *) buf = (dev_state.metabit) ? K_METABIT : K_ESCPREFIX; + *(int *) arg = (dev_state.metabit) ? K_METABIT : K_ESCPREFIX; return 0; case KDSKBMETA: - if ((int) buf == K_METABIT) + if ((int) arg == K_METABIT) dev_state.metabit = TRUE; - else if ((int) buf == K_ESCPREFIX) + else if ((int) arg == K_ESCPREFIX) dev_state.metabit = FALSE; else { @@ -883,9 +886,9 @@ fhandler_console::ioctl (unsigned int cmd, void *buf) } return 0; case TIOCLINUX: - if (*(unsigned char *) buf == 6) + if (*(unsigned char *) arg == 6) { - *(unsigned char *) buf = (unsigned char) dev_state.nModifiers; + *(unsigned char *) arg = (unsigned char) dev_state.nModifiers; return 0; } set_errno (EINVAL); @@ -906,13 +909,13 @@ fhandler_console::ioctl (unsigned int cmd, void *buf) while (n-- > 0) if (inp[n].EventType == KEY_EVENT && inp[n].Event.KeyEvent.bKeyDown) ++ret; - *(int *) buf = ret; + *(int *) arg = ret; return 0; } break; } - return fhandler_base::ioctl (cmd, buf); + return fhandler_base::ioctl (cmd, arg); } int diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 9ea6ae9d8..4575ede94 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -400,3 +400,37 @@ fhandler_termios::sigflush () if (get_ttyp () && !(get_ttyp ()->ti.c_lflag & NOFLSH)) tcflush (TCIFLUSH); } + +int +fhandler_termios::tcgetsid () +{ + if (myself->ctty != -1 && myself->ctty == tc ()->ntty) + return tc ()->getsid (); + set_errno (ENOTTY); + return -1; +} + +int +fhandler_termios::ioctl_termios (int cmd, int arg) +{ + if (cmd != TIOCSCTTY) + return 1; /* Not handled by this function */ + + if (arg != 0 && arg != 1) + { + set_errno (EINVAL); + return -1; + } + + termios_printf ("myself->ctty %d, myself->sid %d, myself->pid %d, arg %d, tc()->getsid () %d\n", + myself->ctty, myself->sid, myself->pid, arg, tc ()->getsid ()); + if (myself->ctty > 0 || myself->sid != myself->pid || (!arg && tc ()->getsid () > 0)) + { + set_errno (EPERM); + return -1; + } + + myself->ctty = -1; + myself->set_ctty (tc (), 0, this); + return 0; +} diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 0d16130be..d5ebec94a 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -145,7 +145,7 @@ fhandler_pty_master::accept_input () rc = WriteFile (get_output_handle (), p, bytes_left, &written, NULL); if (!rc) { - debug_printf ("error writing to pipe %E"); + debug_printf ("error writing to pipe %p %E", get_output_handle ()); get_ttyp ()->read_retval = -1; ret = -1; } @@ -947,6 +947,9 @@ int fhandler_pty_slave::ioctl (unsigned int cmd, void *arg) { termios_printf ("ioctl (%x)", cmd); + int res = ioctl_termios (cmd, (int) arg); + if (res <= 0) + return res; if (myself->pgid && get_ttyp ()->getpgid () != myself->pgid && (unsigned) myself->ctty == FHDEV (DEV_TTYS_MAJOR, get_unit ()) @@ -1358,6 +1361,10 @@ fhandler_pty_master::tcflush (int queue) int fhandler_pty_master::ioctl (unsigned int cmd, void *arg) { + int res = ioctl_termios (cmd, (int) arg); + if (res <= 0) + return res; + switch (cmd) { case TIOCPKT: diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 1dcf53885..480b0ff47 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -421,12 +421,13 @@ details. */ 250: Export clock_nanosleep. 251: RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND added. 252: CW_CVT_ENV_TO_WINENV added. + 253: Export TIOCSCTTY, tcgetsid. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 252 +#define CYGWIN_VERSION_API_MINOR 253 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/include/sys/termios.h b/winsup/cygwin/include/sys/termios.h index a772555cf..a0d1b2445 100644 --- a/winsup/cygwin/include/sys/termios.h +++ b/winsup/cygwin/include/sys/termios.h @@ -19,6 +19,7 @@ details. */ #define TIOCMBIC 0x5417 #define TIOCMSET 0x5418 #define TIOCINQ 0x541B +#define TIOCSCTTY 0x540E /* TIOCINQ is utilized instead of FIONREAD which has been accupied for other purposes under CYGWIN. @@ -327,6 +328,7 @@ int tcsendbreak (int, int); int tcdrain (int); int tcflush (int, int); int tcflow (int, int); +int tcgetsid (int); void cfmakeraw (struct termios *); speed_t cfgetispeed(const struct termios *); speed_t cfgetospeed(const struct termios *); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 162825442..4ab14471f 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1134,7 +1134,7 @@ open (const char *unix_path, int flags, ...) a change in behavior that implements linux functionality: opening a tty should not automatically cause it to become the controlling tty for the process. */ - if (fd > 2) + if (0 && fd > 2) flags |= O_NOCTTY; if (!(fh = build_fh_name (unix_path, (flags & (O_NOFOLLOW | O_EXCL)) @@ -1600,9 +1600,10 @@ stat_worker (path_conv &pc, struct __stat64 *buf) if (!buf->st_ino) buf->st_ino = fh->get_ino (); if (!buf->st_dev) - buf->st_dev = fh->get_device (); + buf->st_dev = fh->is_dev_tty () ? FH_TTY : fh->get_device (); if (!buf->st_rdev) buf->st_rdev = buf->st_dev; +debug_printf ("is_dev_tty %d, st_dev %p\n", fh->is_dev_tty (), buf->st_dev); } delete fh; } diff --git a/winsup/cygwin/termios.cc b/winsup/cygwin/termios.cc index a59bbd2cc..b95dca035 100644 --- a/winsup/cygwin/termios.cc +++ b/winsup/cygwin/termios.cc @@ -195,13 +195,11 @@ tcgetattr (int fd, struct termios *in_t) extern "C" int tcgetpgrp (int fd) { - int res = -1; + int res; cygheap_fdget cfd (fd); if (cfd < 0) - /* saw an error */; - else if (!cfd->is_tty ()) - set_errno (ENOTTY); + res = -1; else res = cfd->tcgetpgrp (); @@ -209,6 +207,21 @@ tcgetpgrp (int fd) return res; } +extern "C" int +tcgetsid (int fd) +{ + int res; + + cygheap_fdget cfd (fd); + if (cfd < 0) + res = -1; + else + res = cfd->tcgetsid (); + + termios_printf ("%d = tcgetsid (%d)", res, fd); + return res; +} + /* tcsetpgrp: POSIX 7.2.4.1 */ extern "C" int tcsetpgrp (int fd, pid_t pgid)