linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Incorect signal handling ?
@ 2001-04-12 20:31 Daniel Podlejski
  2001-04-12 21:27 ` Richard B. Johnson
  2001-04-12 21:56 ` Doug McNaught
  0 siblings, 2 replies; 3+ messages in thread
From: Daniel Podlejski @ 2001-04-12 20:31 UTC (permalink / raw)
  To: Linux Kernel List

Hi,

there is litlle programm:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

static void empty(int sig)
{
	printf ("hello\n");
	return;
}

void main()
{
        int fd, a;
        char buf[512];

	if (fd = open("/tmp/nic", O_RDONLY) < 0)
	{
		perror ("open");
		exit(1);
	}

	signal (SIGALRM, empty);
	alarm (1);

        a = read(fd, buf, 511);

        while (a && a != -1) a = read(fd, buf, 511);

	if (a == -1)
	{
		perror ("read");
		exit(1);
	}
	else printf ("EOF\n");

        exit(0);
}

I open /tmp/nic and run compiled program.
There should be error EINTR in read, but isn't.
Why ?

-- 
Daniel Podlejski <underley@underley.eu.org>
   ... Here await the birth of the son
   The seventh, the heavenly, the chosen one ...

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

* Re: Incorect signal handling ?
  2001-04-12 20:31 Incorect signal handling ? Daniel Podlejski
@ 2001-04-12 21:27 ` Richard B. Johnson
  2001-04-12 21:56 ` Doug McNaught
  1 sibling, 0 replies; 3+ messages in thread
From: Richard B. Johnson @ 2001-04-12 21:27 UTC (permalink / raw)
  To: Daniel Podlejski; +Cc: Linux Kernel List

On Thu, 12 Apr 2001, Daniel Podlejski wrote:

> Hi,
> 
> there is litlle programm:
> 
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/types.h>
> #include <signal.h>
> #include <errno.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> 
> static void empty(int sig)
> {
> 	printf ("hello\n");
> 	return;
> }
> 
> void main()
> {
>         int fd, a;
>         char buf[512];
> 
> 	if (fd = open("/tmp/nic", O_RDONLY) < 0)
> 	{
> 		perror ("open");
> 		exit(1);
> 	}
> 
> 	signal (SIGALRM, empty);
> 	alarm (1);
> 
>         a = read(fd, buf, 511);
> 
>         while (a && a != -1) a = read(fd, buf, 511);
> 
> 	if (a == -1)
> 	{
> 		perror ("read");
> 		exit(1);
> 	}
> 	else printf ("EOF\n");
> 
>         exit(0);
> }
> 
> I open /tmp/nic and run compiled program.
> There should be error EINTR in read, but isn't.
> Why ?
> 

The test program contains several errors. Here is a 'fixed' version.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

static void empty(int sig)
{
	printf ("hello\n");
	return;
}

void main()
{
        int fd, a;
        struct sigaction sa;
        char buf[512];

	if (fd = open("/dev/zero", O_RDONLY) < 0)
	{
		perror ("open");
		exit(1);
	}
        sigaction(SIGALRM, NULL, &sa);
        sa.sa_handler = empty;
        sa.sa_flags   = SA_INTERRUPT;
        sigaction(SIGALRM, &sa, NULL);
	alarm (1);

        while ((a = read(fd, buf, 511)) > 0)
            ;

	if (a == -1)
	{
		perror ("read");
		exit(1);
	}
	else printf ("EOF\n");
        exit(0);
}


First, you need to read something that can be interrupted. A 511 byte
read from a small file will probably never be interrupted. The code
can be spending much more time in the 'while (funny stuff)' loop than
it takes to read that file.

I chose to read from an infinite-size 'file'.

Second, your 'C' runtime library probably defaults to non-BSD signals.
That is to say, the "SA_RESTART" bit is probably set in the flags.
To get the system call interrupted, you need to have that bit clear.
The way to do it is with sigaction(); signal() is just not capable
of doing what you want, now that 'C' runtime libraries default to
POSIX-signal behavior rather than BSD-signals.

FYI, main() can never be void. It must return an 'int'.
  while (a && a != -1) a = read(fd, buf, 511);
doesn't make much sense. (a && a) is either TRUE or FALSE. It
will, therefore NEVER be -1. Maybe you meant (a & a)? If so,
why not just (a != -1) or (a > 0) ?

Cheers,
Dick Johnson

Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).

"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.



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

* Re: Incorect signal handling ?
  2001-04-12 20:31 Incorect signal handling ? Daniel Podlejski
  2001-04-12 21:27 ` Richard B. Johnson
@ 2001-04-12 21:56 ` Doug McNaught
  1 sibling, 0 replies; 3+ messages in thread
From: Doug McNaught @ 2001-04-12 21:56 UTC (permalink / raw)
  To: Daniel Podlejski; +Cc: Linux Kernel List

Daniel Podlejski <underley@underley.eu.org> writes:

> Hi,
> 
> there is litlle programm:
> 
> 	signal (SIGALRM, empty);
> 	alarm (1);
> 
>         a = read(fd, buf, 511);
> 
>         while (a && a != -1) a = read(fd, buf, 511);

> I open /tmp/nic and run compiled program.
> There should be error EINTR in read, but isn't.

"Fast" system calls (eg reads from disk) are generally
uninterruptible; thus the signal will be deferred until the read()
returns.

-Doug

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

end of thread, other threads:[~2001-04-12 21:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-12 20:31 Incorect signal handling ? Daniel Podlejski
2001-04-12 21:27 ` Richard B. Johnson
2001-04-12 21:56 ` Doug McNaught

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).