Here is a testcase.
# gcc loop.c test19.c
# a.out
Wrote 8190 bytes
read 4222 bytes
after input queue filled to 4222 bytes, attempt, to read() STOP character(s) returned 0, expected >= 1
-- H.J. Lu (hjl@gnu.org) ---- #!/bin/sh # This is a shell archive (produced by GNU sharutils 4.2). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 1998-12-09 21:12 PST by <hjl@ocean.lucon.org>. # Source directory was `/home/hjl/bugs/glibc/termios'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 12926 -rw-r--r-- loop.c # 4666 -rw-r--r-- test19.c # save_IFS="${IFS}" IFS="${IFS}:" gettext_dir=FAILED locale_dir=FAILED first_param="$1" for dir in $PATH do if test "$gettext_dir" = FAILED && test -f $dir/gettext \ && ($dir/gettext --version >/dev/null 2>&1) then set `$dir/gettext --version 2>&1` if test "$3" = GNU then gettext_dir=$dir fi fi if test "$locale_dir" = FAILED && test -f $dir/shar \ && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) then locale_dir=`$dir/shar --print-text-domain-dir` fi done IFS="$save_IFS" if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED then echo=echo else TEXTDOMAINDIR=$locale_dir export TEXTDOMAINDIR TEXTDOMAIN=sharutils export TEXTDOMAIN echo="$gettext_dir/gettext -s" fi touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo $echo 'WARNING: not restoring timestamps. Consider getting and' $echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if mkdir _sh10858; then $echo 'x -' 'creating lock directory' else $echo 'failed to create lock directory' exit 1 fi # ============= loop.c ============== if test -f 'loop.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'loop.c' '(file already exists)' else $echo 'x -' extracting 'loop.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'loop.c' && #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <limits.h> #include <termios.h> #include <string.h> X #define WAITTIME (5 * SPEEDFACTOR) #define COMBITS 11 #define TTY_SIDE 1 #define LOOP_SIDE 2 X extern void setsigs (void (*func)()); X int sig_recvd; int sig_cont; int sig_errno; int sig_ret; X pid_t child1; pid_t child2; X int data_rate = 9600 / COMBITS; X cc_t PERASE = 0x7f; cc_t PKILL = 0x15; cc_t PINTR = 0x03; cc_t PQUIT = 0x1c; cc_t PSTART = 0x11; cc_t PSTOP = 0x13; cc_t PEOF = 0x04; cc_t PEOL = 0x0b; cc_t PSUSP = 0x1a; cc_t PMIN = 0; cc_t PTIME = 10; X static int tty_done = 0; static struct termios tty_termios; static int loop_done = 0; static struct termios loop_termios; static int tty_master_fd = -1; static int loop_master_fd = -1; X int openctl(spec, oflag) char *spec; int oflag; { X /* Note: setsid() will have been called before this routine */ X X int fd; X X /* allow for modem line delay if there has just been a close() */ X (void) sleep(1); X X fd = open(spec, oflag, 0); X X /* Make sure failure is not just because the device cannot X become the controlling terminal */ X X if (fd < 0 && errno != EINTR) X fd = open(spec, oflag|O_NOCTTY, 0); X X return fd; } X int openpty(master, slave, mfdp, sfdp, cntrl) char *master; char *slave; int *mfdp; int *sfdp; int cntrl; { X *mfdp = open(master, O_RDWR|O_NOCTTY); X if (*mfdp < 0 && errno != EBUSY) X return -1; X X if (*mfdp >= 0) X { X char *newslave; X size_t len; X static struct { char *ptr; size_t len; } slavelen[2]; X extern char *ptsname(); X X (void) grantpt(*mfdp); /* change permission of slave */ X (void) unlockpt(*mfdp); /* unlock slave */ X newslave=ptsname(*mfdp); /* get a slave */ X if (slavelen[0].ptr == NULL) X { X /* remember length of original dummy name X to be used if called again */ X slavelen[0].ptr = slave; X slavelen[0].len = strlen(slave); X } X else if (slave != slavelen[0].ptr && slavelen[1].ptr == NULL) X { X /* remember length of original dummy name X to be used if called again */ X slavelen[1].ptr = slave; X slavelen[1].len = strlen(slave); X } X if (slave == slavelen[0].ptr) X len = slavelen[0].len; X else X len = slavelen[1].len; X if (strlen(newslave) > len) X { X (void) fprintf(stderr, X "dummy slave name too short to take \"%s\" in openpty()\n", X newslave); X return -1; X } X (void) strcpy(slave, newslave); X } X X if (cntrl) X *sfdp = openctl(slave, O_RDWR); X else X *sfdp = open(slave, O_RDWR|O_NOCTTY); X X if (*sfdp < 0) X return -1; X X return 0; } X int ptygetattr(mfd, termios_p) int mfd; struct termios *termios_p; { X return tcgetattr(mfd, termios_p); } X static void rdwr(fdin, fdout) int fdin; int fdout; { X /* read from fdin and write to fdout - called in child process */ X X int n; X char buf[_POSIX_MAX_INPUT/2]; X X while ((n = read(fdin, buf, sizeof(buf))) >= 0) X { X /* On EOF write EOF character */ X if (n == 0) X { X if (ptygetattr(fdout, &tty_termios) == 0) X buf[n++] = tty_termios.c_cc[VEOF]; X else X buf[n++] = PEOF; X } X X errno = 0; X if (write(fdout, buf, (unsigned int)n) != n) X { X /* die quietly on EIO */ X if (errno != EIO) X perror ("write"); X _exit(1); X } X } X /* die quietly on EIO */ X if (errno != EIO) X perror ("read"); X _exit(1); } X static int ptycon(tty_fildes, loop_fildes) int tty_fildes; int loop_fildes; { X /* connect two master pty's so slaves can be used as loopback */ X X pid_t ppid; X X switch (child1 = fork()) X { X case -1: X perror ("fork"); X exit (1); X X case 0: X setsigs(SIG_IGN); X (void) close(tty_fildes); X (void) close(loop_fildes); X rdwr(tty_master_fd, loop_master_fd); X _exit(0); X } X X switch (child2 = fork()) X { X case -1: X perror ("fork"); X exit (1); X X case 0: X setsigs(SIG_IGN); X (void) close(tty_fildes); X (void) close(loop_fildes); X rdwr(loop_master_fd, tty_master_fd); X _exit(0); X } X X /* rdwr processes may not be killed by tests, so this process X checks for when the parent dies, and kills the rdwr's */ X X ppid = getpid(); X switch (fork()) X { X X case -1: X perror ("fork"); X exit (1); X X case 0: X setsigs(SIG_IGN); X (void) close(tty_fildes); X (void) close(loop_fildes); X X /* When parent PID changes, parent has died */ X while (ppid == getppid()) X (void) sleep(2); X X (void) kill(child1, SIGKILL); X (void) kill(child2, SIGKILL); X X _exit(0); X } X X return 0; } X char * xstrdup (const char *s) { X char *p = malloc (strlen (s) + 1); X strcpy (p, s); X return p; } X static int do_prep(side, oflags, fildes_p, termios_p) int side; int oflags; int *fildes_p; struct termios *termios_p; { X /* common function called by tty_prep() and loop_prep() */ X X char *termios_tty, *master_tty; X int flags, cntrl, *master_fdp; X X *fildes_p = -1; X X if (side == TTY_SIDE) X termios_tty = xstrdup ("/dev/pts/xxxxxxx"); X else X termios_tty = xstrdup ("/dev/pts/xxxxxxx"); X X if (side == TTY_SIDE) X { X master_tty = "/dev/ptmx"; X master_fdp = &tty_master_fd; X } X else X { X master_tty = "/dev/ptmx"; X master_fdp = &loop_master_fd; X } X X if (master_tty == NULL || *master_tty == '\0') X { X if (side == TTY_SIDE) X *fildes_p = openctl(termios_tty, oflags | O_NONBLOCK); X else X *fildes_p = open(termios_tty, X oflags | O_NONBLOCK | O_NOCTTY); X if(*fildes_p < 0) X return -1; X } X else X { X /* allow previous rdwr() processes to finish */ X (void) sleep(3); X X if (side == TTY_SIDE) X cntrl = (oflags & O_NOCTTY) == 0; X else X cntrl = 0; X X /* Implementation-supplied pseudo-terminal opener */ X if (openpty(master_tty, termios_tty, X master_fdp, fildes_p, cntrl) != 0) X { X fprintf (stderr, "openpty(\"%s\", \"%s\", mfdp, sfdp, %d) failed\n", X master_tty, termios_tty, cntrl); X if (*master_fdp >= 0) X { X (void) close(*master_fdp); X *master_fdp = -1; X } X return -1; X } X } X X /* Initialize fields */ X if (side == TTY_SIDE) X { X if (tty_init(*fildes_p, termios_p) != 0) X return -1; X } X else X { X if (loop_init(*fildes_p, termios_p) != 0) X return -1; X } X if (tcsetattr(*fildes_p, TCSANOW, termios_p) != 0) X return -1; X X if ((oflags & O_NONBLOCK) == 0) X { X /* Clear O_NONBLOCK flag after opening */ X if ((flags = fcntl (*fildes_p, F_GETFL)) == -1) X return -1; X if (fcntl (*fildes_p, F_SETFL, flags & ~O_NONBLOCK) == -1) X return -1; X } X X return 0; } X /******************************* * Prepare tty's ********************************/ int terms_prep(tty_flags, tty_fildes_p, tty_termios_p, X loop_flags, loop_fildes_p, loop_termios_p) int tty_flags; int *tty_fildes_p; struct termios *tty_termios_p; int loop_flags; int *loop_fildes_p; struct termios *loop_termios_p; { X int ret; X X *tty_fildes_p = *loop_fildes_p = -1; X X /* X * TERMIOS_TTY must be the next tty opened so that if the process X * is a session leader it will become the controlling terminal X */ X X ret = do_prep(TTY_SIDE, tty_flags, tty_fildes_p, tty_termios_p); X if (ret != 0) X return ret; X X ret = do_prep(LOOP_SIDE, loop_flags, loop_fildes_p, loop_termios_p); X if (ret != 0) X return ret; X X /* If pseudo-terminal looback required, connect master sides */ X if (tty_master_fd >= 0 && loop_master_fd >= 0) X ret = ptycon(*tty_fildes_p, *loop_fildes_p); X X if (tty_master_fd >= 0) X { X (void) close(tty_master_fd); X tty_master_fd = -1; X } X if (loop_master_fd >= 0) X { X (void) close(loop_master_fd); X loop_master_fd = -1; X } X X return ret; } X int termios_prep (tty_fildes_p, tty_termios_p, loop_fildes_p, loop_termios_p) int *tty_fildes_p; /* TERMIOS_TTY file descriptor */ struct termios *tty_termios_p; /* terminal attributes */ int *loop_fildes_p; /* TERMIOS_LOOP file descriptor */ struct termios *loop_termios_p; /* terminal attributes */ { X (void) setsid(); X X return terms_prep(O_RDWR, tty_fildes_p, tty_termios_p, X O_RDWR, loop_fildes_p, loop_termios_p); } X /************************* * TERMIOS_TTY *************************/ int tty_prep (tty_fildes_p, tty_termios_p) int *tty_fildes_p; /* TERMIOS_TTY file descriptor */ struct termios *tty_termios_p; /* terminal attributes */ { X return do_prep(TTY_SIDE, O_RDWR, tty_fildes_p, tty_termios_p); } X /************************* * TERMIOS_LOOP *************************/ int loop_prep (loop_fildes_p, loop_termios_p) int *loop_fildes_p; /* TERMIOS_LOOP file descriptor */ struct termios *loop_termios_p; /* terminal attributes */ { X return do_prep(LOOP_SIDE, O_RDWR, loop_fildes_p, loop_termios_p); } X /********************************************** * Save the initial termios state * Modify struct termios to VSX values * Modify struct termios for test values **********************************************/ int tty_init(fildes, termios_p) int fildes; struct termios *termios_p; { X /************************* X * save initial state X **************************/ X if (!tty_done) X { X if (tcgetattr(fildes, &tty_termios) != 0) X return -1; X } X tty_done = 1; X X *termios_p = tty_termios; /* ANSI C structure assignment */ X X /************************* X * set to VSX values X **************************/ X (termios_p)->c_iflag &= ~(PARMRK|INLCR|INPCK|IGNCR|IXOFF|BRKINT|IXON); X (termios_p)->c_iflag |= (IGNPAR|IGNBRK|ICRNL); X if ((termios_p->c_cflag & CSIZE) == CS8) X (termios_p)->c_iflag &= ~ISTRIP; #ifdef _XOPEN_SOURCE X (termios_p)->c_iflag &= ~(IUCLC|IXANY); #endif X (termios_p)->c_oflag &= ~OPOST; X X (termios_p)->c_cflag |= (CLOCAL|CREAD); X X (termios_p)->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|IEXTEN); X (termios_p)->c_lflag |= (ISIG|ICANON|NOFLSH); #ifdef _XOPEN_SOURCE X (termios_p)->c_lflag &= ~XCASE; #endif X (termios_p)->c_cc[VMIN] = PMIN; X (termios_p)->c_cc[VTIME] = PTIME; X (termios_p)->c_cc[VINTR] = PINTR; X (termios_p)->c_cc[VQUIT] = PQUIT; X (termios_p)->c_cc[VERASE] = PERASE; X (termios_p)->c_cc[VKILL] = PKILL; X (termios_p)->c_cc[VEOF] = PEOF; X (termios_p)->c_cc[VEOL] = PEOL; X (termios_p)->c_cc[VSUSP] = PSUSP; X (termios_p)->c_cc[VSTART] = PSTART; X (termios_p)->c_cc[VSTOP] = PSTOP; X X if (cfsetispeed(termios_p,B9600) != 0 || X cfsetospeed(termios_p,B9600) != 0) X return -1; X X return 0; } X /********************************** * Initialize LOOP to noncanonical ***********************************/ int loop_init(fildes, termios_p) X int fildes; struct termios *termios_p; { X static long NOTHING; /* "disable" character */ X X /************************* X * save initial state X **************************/ X if (!loop_done) X { X if (tcgetattr(fildes, &loop_termios) != 0) X return -1; X NOTHING = fpathconf(fildes, _PC_VDISABLE); X if (NOTHING == -1) X NOTHING = 0; X } X loop_done = 1; X X *termios_p = loop_termios; /* ANSI C structure assignment */ X X /************************* X * set VSX values X **************************/ X (termios_p)->c_iflag &= ~(PARMRK|ICRNL|INLCR|INPCK|IGNCR|IXOFF|BRKINT|IXON); X (termios_p)->c_iflag |= (IGNPAR|IGNBRK); #ifdef _XOPEN_SOURCE X (termios_p)->c_iflag &= ~(IUCLC|IXANY); #endif X (termios_p)->c_oflag &= ~OPOST; X X (termios_p)->c_cflag |= (CLOCAL|CREAD); X /* make sure LOOP has similar enough c_cflag values to TTY X so they can talk to each other */ X if (tty_done) X { X termios_p->c_cflag &= ~(CSIZE|CSTOPB|PARENB|PARODD); X termios_p->c_cflag |= X (tty_termios.c_cflag & (CSIZE|CSTOPB|PARENB|PARODD)); X } X X if ((termios_p->c_cflag & CSIZE) == CS8) X (termios_p)->c_iflag &= ~ISTRIP; X X (termios_p)->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ISIG|ICANON|TOSTOP|IEXTEN); X (termios_p)->c_lflag |= (NOFLSH); #ifdef _XOPEN_SOURCE X (termios_p)->c_lflag &= ~XCASE; #endif X (termios_p)->c_cc[VINTR] = NOTHING; X (termios_p)->c_cc[VQUIT] = NOTHING; X (termios_p)->c_cc[VERASE] = NOTHING; X (termios_p)->c_cc[VKILL] = NOTHING; X (termios_p)->c_cc[VEOF] = NOTHING; X (termios_p)->c_cc[VEOL] = NOTHING; X (termios_p)->c_cc[VSUSP] = NOTHING; X (termios_p)->c_cc[VMIN] = PMIN; X (termios_p)->c_cc[VTIME] = PTIME; X (termios_p)->c_cc[VSTART] = PSTART; X (termios_p)->c_cc[VSTOP] = PSTOP; X X if (cfsetispeed((termios_p),B9600) != 0 || X cfsetospeed((termios_p),B9600) != 0) X return -1; X X return 0; } X #ifdef __hpux #undef NSIG #define NSIG 31 #endif X int sig_init (int signum, sigset_t *sigmask, void (*sigfunc)(), X int sigflags) { X struct sigaction act; X act.sa_flags = sigflags; X act.sa_mask = *sigmask; X act.sa_handler = sigfunc; X return(sigaction(signum, &act, (struct sigaction *)NULL)); } X static sigset_t sig_empty; X void do_signal (signum, sigfunc) X int signum; X void (*sigfunc)(); { X struct sigaction act; X X act.sa_flags = 0; X act.sa_handler = sigfunc; X sigemptyset(&act.sa_mask); X if (sigaction(signum, &act, (struct sigaction *)NULL) < 0) X { X perror ("sigaction"); X abort (); X } } X void sig_catch (sig) X int sig; { X sig_recvd = sig; } X void sig_resume (sig) X int sig; { X sig_cont = sig; } X void setsigs (func) X void (*func)(); { X int i; X for (i = 1; i < NSIG; i++) X { X if (i == SIGKILL || i == SIGSTOP || i == SIGCHLD) X continue; X X do_signal (i, func); X } } X int alrm_flag; X void alrm (int sig) { X alrm_flag = 1; } SHAR_EOF $shar_touch -am 1207115798 'loop.c' && chmod 0644 'loop.c' || $echo 'restore of' 'loop.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'loop.c:' 'MD5 check failed' 9a85b08a341019e2ab49c64fad7f8d80 loop.c SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'loop.c'`" test 12926 -eq "$shar_count" || $echo 'loop.c:' 'original size' '12926,' 'current size' "$shar_count!" fi fi # ============= test19.c ============== if test -f 'test19.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'test19.c' '(file already exists)' else $echo 'x -' extracting 'test19.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'test19.c' && #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <limits.h> #include <termios.h> #include <string.h> X extern void alrm (int); X extern int data_rate; X #define Strlen (sizeof(string)-1) #define NAP 2 X static long max_input; static int tty_fildes, loop_fildes; static struct termios tty_termios, loop_termios, X *loop_termios_p = &loop_termios, X *tty_termios_p = &tty_termios; static char string[] = "And they thwam and they thwam all over the dam!"; static char inbuf[512]; static char Stop = '\023'; /* ASCII DC3 */ static char Start = '\021'; /* ASCII DC1 */ extern int alrm_flag; X void test19() { X int ret, err; X unsigned capacity, total, nbytes, wrote; X X errno = 0; X max_input = fpathconf(tty_fildes, _PC_MAX_INPUT); X if (max_input < 0) X { X perror ("fpathconf"); X return; X } X X if (loop_init(loop_fildes, loop_termios_p) != 0) X { X return; X } X X loop_termios_p->c_lflag &= ~ICANON; X loop_termios_p->c_iflag |= IXON; X loop_termios_p->c_cc[VMIN] = 0; X loop_termios_p->c_cc[VTIME] = 10; X if (tcsetattr(loop_fildes, TCSANOW, loop_termios_p) != 0) X { X perror ("tcsetattr"); X return; X } X X if (tty_init(tty_fildes, tty_termios_p) != 0) X { X return; X } X X tty_termios_p->c_lflag &= ~ICANON; X tty_termios_p->c_cc[VMIN] = 0; X tty_termios_p->c_cc[VTIME] = 10; X tty_termios_p->c_iflag |= IXOFF; X if (tcsetattr(tty_fildes, TCSANOW, tty_termios_p) != 0) X { X perror ("tcsetattr"); X return; X } X X alrm_flag = 0; X wrote = 0; X while (alrm_flag == 0) X { X do_signal (SIGALRM, alrm); X alarm (10); X ret = write(loop_fildes, string, Strlen); X alarm (0); X err = errno; X X if (ret < 0) X break; X wrote += ret; X } X X if (alrm_flag == 0) X { X fprintf (stderr, "no alarm\n"); X perror ("write"); X return; X } X X fprintf (stderr, "Wrote %d bytes\n", wrote); X X if (tcflush(loop_fildes, TCOFLUSH) != 0) X { X perror ("tcflush"); X return; X } X X capacity = 0; X while ((ret = read(tty_fildes, inbuf, sizeof(inbuf))) > 0) X capacity += ret; X if (ret < 0) X { X perror ("read"); X return; X } X X fprintf (stderr, "read %d bytes\n", capacity); X X /* X * Now switch off flow control and fill the input queue X */ X X loop_termios_p->c_iflag &= ~IXON; X if (tcsetattr(loop_fildes, TCSANOW, loop_termios_p) != 0) X { X perror ("tcsetattr"); X return; X } X X if (capacity < max_input) X capacity = max_input; X X total = 0; X do { X nbytes = capacity - total; X if (nbytes > Strlen) X nbytes = Strlen; X X errno = 0; X ret = write(loop_fildes, string, nbytes); X X if (ret != nbytes) X { X perror ("write"); X return; X } else { X total += ret; X } X X } while (total < capacity); X X (void) sleep((unsigned)(capacity/data_rate)+NAP); X X /* Read STOP character(s) */ X X ret = read(loop_fildes, inbuf, sizeof(inbuf)); X if (ret < 1) X { X err = errno; X fprintf (stderr, "after input queue filled to %u bytes, attempt, to read() STOP character(s) returned %d, expected >= 1\n", X capacity, ret); X if (ret < 0) X fprintf (stderr, "errno was set to %d\n", err); X return; X } X else if (memchr((void *)inbuf, Stop, (size_t)ret) == 0) X { X fprintf (stderr, "system did not transmit STOP when input queue filled to %u bytes\n", X capacity); X return; X } X X /* read input to cause START to be sent, and check no data was lost */ X X total = 0; X do { X ret = read(tty_fildes, inbuf, sizeof(inbuf)); X X } while (ret > 0 && (total += ret) < capacity); X X if (total != capacity) X { X err = errno; X fprintf (stderr, "second read() loop gave %u bytes, expected %u\n", X total, capacity); X if (ret < 0) X fprintf (stderr, "errno was set to %d\n", err); X } X X (void) sleep(NAP); X X ret = read(loop_fildes, inbuf, sizeof(inbuf)); X if (ret < 1) X { X err = errno; X fprintf (stderr, "attempt to read() START character returned %d, expected >= 1\n", ret); X if (ret < 0) X fprintf (stderr, "errno was set to %d\n", err); X } X else if (memchr((void *)inbuf, Start, (size_t)ret) == 0) X { X fprintf (stderr, "system did not transmit START after input queue emptied\n"); X } } X void prepare_tests() { X switch (termios_prep (&tty_fildes, tty_termios_p, X &loop_fildes, loop_termios_p) ) X { X case 0: X break; X case 1: X fprintf (stderr, "Unsupported\n"); X return; X break; X default: X fprintf (stderr, "Unsupported\n"); X return; X break; X } X X tty_termios_p->c_lflag &= ~ICANON; X tty_termios_p->c_cc[VMIN] = 0; X tty_termios_p->c_cc[VTIME] = 30; X X if (tcsetattr(tty_fildes, TCSANOW, tty_termios_p) != 0) X { X perror ("tcsetattr"); X return; X } } X void clean_tests() { X X (void) close(tty_fildes); X (void) close(loop_fildes); } main () { X prepare_tests(); X test19 (); X clean_tests (); } SHAR_EOF $shar_touch -am 1209211198 'test19.c' && chmod 0644 'test19.c' || $echo 'restore of' 'test19.c' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'test19.c:' 'MD5 check failed' 2e7db6dd2d7cd45a268dd40afad60486 test19.c SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'test19.c'`" test 4666 -eq "$shar_count" || $echo 'test19.c:' 'original size' '4666,' 'current size' "$shar_count!" fi fi rm -fr _sh10858 exit 0- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/