All of lore.kernel.org
 help / color / mirror / Atom feed
* Bad Network SIGIO on Linux-2.4.19
@ 2002-08-16 19:27 Richard B. Johnson
  2002-08-21 14:24 ` lists
  0 siblings, 1 reply; 4+ messages in thread
From: Richard B. Johnson @ 2002-08-16 19:27 UTC (permalink / raw)
  To: Linux kernel


This stand-alone program demonstrates the problem previously
reported.

If you execute this locally, the program will wait for any
input from the terminal (STDIN_FILENO) and then it will
terminate. This is the expected behavior.

If you execute this while logged in using telnet, using linux-2.4.18,
this program will also execute as expected.

However, if you execute using linux-2.4.19, when logged in using
telnet, the program will exit as soon as the child writes the
first '.' to the terminal because a SIGIO signal is being incorrectly
generated for both output and input.


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/resource.h>

#define ERRORS(s) { \
    fprintf(stderr, "Error from line %d, file %s, call %s, (%s)\n", \
    __LINE__,__FILE__,(s), strerror(errno)); \
    }

#define FAIL -1
int enab = 0;
int alive = 0;
static void set_sig(int sig, sig_t funct, int flags)
{
    struct sigaction sa;
    if(sigaction(sig, NULL, &sa) == FAIL)
        ERRORS("sigaction");
    sa.sa_flags = flags;
    sa.sa_handler = funct;
    if(sigaction(sig, &sa, NULL) == FAIL)
        ERRORS("sigaction");
    return;
}
static void iotrap(int unused)
{
   enab = 0; 
}
static void reaper(int unused)
{
    alive = 0;
    while(wait3(&unused, WNOHANG, NULL) > 0)
        ;

}
int main(int args, char *argv[]);
int main(int args, char *argv[])
{
    int flags;
    size_t i;
    pid_t pid;
    struct termios term, save;
    set_sig(SIGCHLD, reaper, SA_INTERRUPT|SA_RESTART);
    set_sig(SIGIO,   iotrap, SA_INTERRUPT|SA_RESTART);
    alive = 1;
    switch((pid = fork()))
    {
    case 0:                 /*  Child */
        for(i=0; i < 0x10; i++)
        {
            (void)sleep(1);
            fprintf(stderr, ".");
            (void)sleep(1);
        }
        exit(EXIT_SUCCESS);
    default:
        break;
    }
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*
 *  Save terminal characteristics and then set the terminal for raw
 *  input generating a signal upon any received character.
 */ 
    if(tcgetattr(STDIN_FILENO, &term) == FAIL)
        ERRORS("tcgetattr");
    save = term;
    term.c_lflag = ISIG;
    term.c_iflag = 0;
    if(tcsetattr(STDIN_FILENO, TCSANOW, &term) == FAIL)
        ERRORS("tcsetattr");
    if((flags = fcntl(STDIN_FILENO, F_GETFL)) == FAIL)
        ERRORS("fcntl");
    flags |= (FNDELAY|FASYNC);
    if(fcntl(STDIN_FILENO, F_SETFL, flags) == FAIL)
        ERRORS("fcntl");
    if(fcntl(STDIN_FILENO, F_SETOWN, getpid()) == FAIL)
        ERRORS("fcntl");
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
    fprintf(stderr, "Waiting for input.......");
    enab = 1;
    while(enab)
    {
        pause();
        fprintf(stderr, "Got out of pause\n");

    }
    if(alive) kill(pid, SIGINT);
    fprintf(stderr, "Exit okay, cleaning up...\n");
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*
 *  Restore the terminal characteristics before we exit. Note, the
 *  terminal is shared. We can't just exit!
 */
    flags &= ~(FNDELAY|FASYNC);
    if(fcntl(STDIN_FILENO, F_SETFL, flags) == FAIL)
        ERRORS("fcntl");
    if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &save) == FAIL)
        ERRORS("tcsetattr");
    set_sig(SIGIO,  SIG_DFL, SA_INTERRUPT);
    fprintf(stderr, "Done!\n");
    return 0;
}



Cheers,
Dick Johnson
Penguin : Linux version 2.4.19 on an i686 machine (797.90 BogoMips).
The US military has given us many words, FUBAR, SNAFU, now ENRON.
Yes, top management were graduates of West Point and Annapolis.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-08-21 15:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-08-16 19:27 Bad Network SIGIO on Linux-2.4.19 Richard B. Johnson
2002-08-21 14:24 ` lists
2002-08-21 14:36   ` Richard B. Johnson
2002-08-21 15:06     ` Jeff Dike

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.