Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-07-29 07:18:41 +0400
committerChristopher Faylor <me@cgf.cx>2002-07-29 07:18:41 +0400
commiteb5720f25501cd7e9b8115bb0220bef058bb5afd (patch)
tree958e311a9e81265e3f16c62f24ebefd39cb12e74 /winsup/cygwin/termios.cc
parentefd34df5a512a754690c75ac74d75929f7f6fd2d (diff)
* fhandler_console.cc (fhandler_console::read): Use appropriate kill_pgrp
method. * select.cc (peek_console): Ditto. * fhandler_termios.cc (fhandler_termios::bg_check): Send "stopped" signal to entire process group as dictated by SUSv3. * termios.cc (tcsetattr): Detect when stopped signal sent and force a stop before setting anything.
Diffstat (limited to 'winsup/cygwin/termios.cc')
-rw-r--r--winsup/cygwin/termios.cc63
1 files changed, 49 insertions, 14 deletions
diff --git a/winsup/cygwin/termios.cc b/winsup/cygwin/termios.cc
index c44ccbdc3..706a31a87 100644
--- a/winsup/cygwin/termios.cc
+++ b/winsup/cygwin/termios.cc
@@ -23,6 +23,7 @@ details. */
#include "cygheap.h"
#include "cygwin/version.h"
#include "perprocess.h"
+#include "sigproc.h"
#include <sys/termios.h>
/* tcsendbreak: POSIX 7.2.2.1 */
@@ -111,21 +112,55 @@ out:
extern "C" int
tcsetattr (int fd, int a, const struct termios *t)
{
- int res = -1;
-
- cygheap_fdget cfd (fd);
- if (cfd < 0)
- goto out;
-
+ int res;
t = __tonew_termios (t);
-
- if (!cfd->is_tty ())
- set_errno (ENOTTY);
- else if ((res = cfd->bg_check (-SIGTTOU)) > bg_eof)
- res = cfd->tcsetattr (a, t);
-
-out:
- termios_printf ("iflag %x, oflag %x, cflag %x, lflag %x, VMIN %d, VTIME %d",
+ int e = get_errno ();
+
+ while (1)
+ {
+ sigframe thisframe (mainthread);
+
+ res = -1;
+ cygheap_fdget cfd (fd);
+ if (cfd < 0)
+ {
+ e = get_errno ();
+ break;
+ }
+
+ if (!cfd->is_tty ())
+ {
+ e = ENOTTY;
+ break;
+ }
+
+ res = cfd->bg_check (-SIGTTOU);
+
+ switch (res)
+ {
+ case bg_eof:
+ e = get_errno ();
+ break;
+ case bg_ok:
+ if (cfd.isopen ())
+ res = cfd->tcsetattr (a, t);
+ else
+ e = get_errno ();
+ break;
+ case bg_signalled:
+ if (thisframe.call_signal_handler ())
+ continue;
+ res = -1;
+ /* fall through intentionally */
+ default:
+ e = get_errno ();
+ break;
+ }
+ break;
+ }
+
+ set_errno (e);
+ termios_printf ("iflag %p, oflag %p, cflag %p, lflag %p, VMIN %d, VTIME %d",
t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag, t->c_cc[VMIN],
t->c_cc[VTIME]);
termios_printf ("%d = tcsetattr (%d, %d, %x)", res, fd, a, t);