Bad Network SIGIO on Linux-2.4.19

Bad Network SIGIO on Linux-2.4.19

Post by Richard B. Johnso » Sun, 18 Aug 2002 04:30:05



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;

Quote:}

static void iotrap(int unused)
{
   enab = 0;
Quote:}

static void reaper(int unused)
{
    alive = 0;
    while(wait3(&unused, WNOHANG, NULL) > 0)
        ;

Quote:}

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;

Quote:}

Cheers,
* 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.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://www.veryComputer.com/
Please read the FAQ at  http://www.veryComputer.com/

 
 
 

Bad Network SIGIO on Linux-2.4.19

Post by li.. » Thu, 22 Aug 2002 23:30:13


This is a fix included since 2.4.19-pre5-aa1.

You're assuming that every SIGIO coming your way
1) is coming via fd 0
2) is a POLL_IN interrupt

You should either be polling the file descriptor (0) from the signal
handler, or using SA_SIGINFO (see sigaction(2)) to determine
which interrupt it is.

Regards,
Sapan


> 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,
>* 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.

> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

> More majordomo info at  http://www.veryComputer.com/
> Please read the FAQ at  http://www.veryComputer.com/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://www.veryComputer.com/
Please read the FAQ at  http://www.veryComputer.com/

 
 
 

Bad Network SIGIO on Linux-2.4.19

Post by Richard B. Johnso » Thu, 22 Aug 2002 23:40:10



Quote:> This is a fix included since 2.4.19-pre5-aa1.

Well if this is a 'fix' there is a lot of legacy software that
just got broken. It was discovered when the new kernel was booted
on some very reliable file-servers.

Quote:> You're assuming that every SIGIO coming your way
> 1) is coming via fd 0
> 2) is a POLL_IN interrupt

> You should either be polling the file descriptor (0) from the signal
> handler, or using SA_SIGINFO (see sigaction(2)) to determine
> which interrupt it is.

I wrote the software to demonstrate the problem, not as an example
of how to poll the keyboard.

Cheers,
* Johnson
Penguin : Linux version 2.4.18 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.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://www.veryComputer.com/
Please read the FAQ at  http://www.veryComputer.com/

 
 
 

Bad Network SIGIO on Linux-2.4.19

Post by Jeff Dik » Fri, 23 Aug 2002 00:10:08



Quote:> Well if this is a 'fix' there is a lot of legacy software that just
> got broken. It was discovered when the new kernel was booted on some
> very reliable file-servers.

Then your "very reliable" file-servers are broken and need fixing so they
no longer depend on this bug.

                                Jeff

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

1. linux-2.4.19-pre9-ac3: PnPBIOS crash

Hi,

I have a dual PIII machine with 1.25 GB of RAM, and I have just
installed a 2.4.19-pre9-ac3 kernel. (I also have ALSA CVS and lm
sensors 2.6.3 installed.)

Anyway, I decided to compile in the PNPBIOS feature and discovered
that:

# cat /proc/bus/pnp/escd

is a synonym for "cold reboot". Now I understand that *writing* to
random /proc files is a Bad Thing, but reading them??? I would have
thought that the worst I could have done would have been corrupting my
termininal. Is the escd file my actual ESCD area?

Is this a bug, or just a case of "don't do that!"?

Cheers,
Chris
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

2. Innovative winxp feature

3. linux-2.4.19-pre6aa1 sendfile problem

4. help:the O_LARGEFILE option of open()

5. ALI15X3 and linux-2.4.19-pre3-ac5 not cooperating

6. How does one see which shared libs are in memory?

7. Complete system freeze with "linux-2.4.19-ac4"

8. PIKT, Problem Informant/Killer Tool, v1.9.0 released

9. linux-2.4.19 on Nokia IP330

10. linux-2.4.19-pre10 - i8xx series chipsets patches (patch 1)

11. linux-2.4.19-ac[13] IDE chrash

12. linux-2.4.19-pre10 - i8xx series chipsets patches (patch 3)

13. linux-2.4.19-pre7-rmap13