Mail Archives: cygwin-developers/1998/02/16/07:44:38
From: Sergey Okhapkin <sos AT prospect DOT com DOT ru>
Date: Mon, 16 Feb 1998 10:20:01 +0300
Ian Lance Taylor wrote:
> From: Sergey Okhapkin <sos AT buggy DOT prospect DOT com DOT ru>
> Date: Sun, 15 Feb 1998 19:35:16 +0300
>
> tty.cc (fhandler_tty_slave::open): call DuplicateHandle() instead of
copying.
>
> This patch looks wrong. It looks like it will break the EOF handling.
> You have to remember that the whole point of the handle manipulation
> in tty.cc is so that when the slave is closed, the pipe is closed. If
> there is somewhere I need to add comments, please let me know.
The code in fhandler_tty_slave::close() closes _both_ fhandler's internal
handles and ttyp pointed. I see no difference in expect's behavior with and
without this patch, but with this patch it's safe to open/close tty slave
in pty_master owner process.
I guess I don't understand this. I thought it was already safe for
the master to open and close the tty slave, particularly with the
patch I checked in a few days ago. Can you give an example of a
program which fails without this patch?
I've appended one simple pty testing program I use. It works on Unix,
and needs to continue to work on cygwin32. When it works, it should
print the output of stty.
Ian
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#if ! defined (__CYGWIN32__) && ! defined (__linux__)
#include <stropts.h>
#endif
extern char *ptsname (int);
static void
die (const char *s, int status)
{
perror (s);
exit (status);
}
static void
do_once ()
{
int om;
const char *slave;
struct stat sb;
pid_t child;
char b;
int c;
int status;
#ifndef __linux__
om = open ("/dev/ptmx", O_RDWR);
if (om < 0)
die ("/dev/ptmx", 1);
if (grantpt (om) < 0)
die ("grantpt", 2);
if (unlockpt (om) < 0)
die ("unlockpt", 3);
slave = ptsname (om);
if (slave == NULL)
die ("ptsname", 4);
#else /* __linux__ */
int i;
char ab[20];
for (i = 0; i < 16; i++)
{
struct stat st;
sprintf (ab, "/dev/ptyp%x", i);
if (stat (ab, &st) < 0)
die ("pty stat", 30);
om = open (ab, O_RDWR);
if (om >= 0)
{
printf ("Using %s\n", ab);
sprintf (ab, "/dev/ttyp%x", i);
slave = ab;
break;
}
}
#endif /* __linux__ */
if (stat (slave, &sb) < 0)
die ("stat", 31);
child = fork ();
if (child < 0)
die ("fork", 5);
if (child == 0)
{
int os;
if (close (0) < 0 || close (1) < 0 || close (2) < 0 || close (om) < 0)
die ("close", 6);
if (setsid () < 0)
die ("setsid", 13);
os = open (slave, O_RDWR);
if (os < 0)
die (slave, 7);
if (os != 0)
die ("unexpected os", 8);
#if ! defined (__CYGWIN32__) && ! defined (__linux__)
if (ioctl (os, I_PUSH, "ptem") < 0)
die ("ptem", 90);
if (ioctl (os, I_PUSH, "ldterm") < 0)
die ("ldterm", 91);
#if 0
if (ioctl (os, I_PUSH, "ttcompat") < 0)
die ("ttcompat", 92);
#endif
#endif
#ifdef TIOCSCTTY
if (ioctl (os, TIOCSCTTY, NULL) < 0)
die ("TIOCSCTTY", 12);
#endif
if (dup2 (os, 1) < 0
|| dup2 (os, 2) < 0)
die ("dup2", 10);
printf ("About to execlp\n");
fflush (stdout);
execlp ("stty", "stty", "-a", NULL);
die ("execlp", 11);
}
printf ("child pid is %d\n", (int) child);
fflush (stdout);
while ((c = read (om, &b, 1)) == 1)
putchar (b);
fflush (stdout);
if (c < 0)
{
#ifdef __linux__
if (errno != EIO)
#endif
die ("read", 20);
}
if (waitpid (child, &status, 0) < 0)
die ("waitpid", 21);
if (WIFEXITED (status))
printf ("child exited with status %d\n", WEXITSTATUS (status));
else if (WIFSIGNALED (status))
printf ("child died with signal %d%s\n", WTERMSIG (status),
(status & 0200) != 0 ? " (core dumped)" : "");
else
printf ("unrecognized status %d\n", status);
}
int
main ()
{
do_once ();
#if 0
printf ("\n");
do_once ();
#endif
exit (0);
}
- Raw text -