sleep( ) misbehaving

S

syed

I am trying to write a little program that goes to sleep for 5 seconds.
However, if the user presses Ctrl-C, it interrupts the sleep and prints the
unslept amount.

For example:

unix> ./sleeper
sleeping for 5 seconds
unslept amount is 2 (User hits Ctrl-C after 3 seconds)
unix>

What's wrong with the code below?
-------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

unsigned int unslept;

void handler (int sig)
{
printf("unslept amount is %d",unslept);
exit(0);
}

int main()
{
signal(SIGINT,handler);
printf("sleeping for 5 seconds\n");
unslept = sleep(5);
return 0;
}
 
J

jacob navia

syed a écrit :
I am trying to write a little program that goes to sleep for 5 seconds.
However, if the user presses Ctrl-C, it interrupts the sleep and prints the
unslept amount.

For example:

unix> ./sleeper
sleeping for 5 seconds
unslept amount is 2 (User hits Ctrl-C after 3 seconds)
unix>

What's wrong with the code below?
-------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

unsigned int unslept;

void handler (int sig)
{
printf("unslept amount is %d",unslept);
exit(0);
}

int main()
{
signal(SIGINT,handler);
printf("sleeping for 5 seconds\n");
unslept = sleep(5);
return 0;
}

After 3 seconds you sent the program a signal (SIGINT) with
the Ctrl+C keys. You got into your handler procedure
and exited.

What else do you want?

Signals are asynchronous in C.

Programs doing something can at any moment be redirected to a signal
handler.

This is normal behavior.

jacob
 
S

syed

jacob navia said:
After 3 seconds you sent the program a signal (SIGINT) with
the Ctrl+C keys. You got into your handler procedure
and exited.

What else do you want?

I want it to print the unslept time correctly. My code always prints ZERO
for unslept time.

unix> ./sleeper
sleeping for 5 seconds
unslept amount is 0 (This line prints when user
hits Ctrl-C, unslept amount is always zero)
unix>

I want it to print the acutal time left to sleep. For example if the user
hits Ctrl-C after three seconds, then it should print 2 for unslept time:

unix> ./sleeper
sleeping for 5 seconds
unslept amount is 2 (User hits Ctrl-C after 3
seconds)
unix>
 
M

Mark B

jacob navia said:
syed a écrit :

unslept variable won't be set until AFTER the sleep() returns.
Move the printf() out of the signal handler (shouldn't do i/o in
there anyway) and place it after the call where it is set.
shitcan the exit() from your handler and just return sig;
That should do what you want.
 
T

tedu

syed said:
I want it to print the unslept time correctly. My code always prints ZERO
for unslept time.

that's because you never let sleep finish.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void handler (int sig)
{
}

int main()
{
unsigned int unslept;
signal(SIGINT,handler);
printf("sleeping for 5 seconds\n");
unslept = sleep(5);
if (unslept)
printf("time not slept %d\n" unslept);
return 0;
}
 
K

Kenneth Brody

syed said:
I want it to print the unslept time correctly. My code always prints ZERO
for unslept time.

Well, it would have been nice if you said so in the first place, rather
than showing a sample of the "correct" output.

[...]

As has been pointed out, sleep() is not standard C, so is off-topic here.
While the man page on _my_ Unix system says:

If the sleep() function returns due to the delivery of a signal,
the value returned will be the unslept amount in seconds.

there is nothing as far as C itself is concerned that says that this must
be the return value. Check the man pages for your particular system, and
if it says it should "work" as you expect, then you need to ask a group
that is appropriate for your system-specific question.

On the other hand, note that the signal handler will be called _before_
the interrupted sleep() call returns.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

syed said:
I am trying to write a little program that goes to sleep for 5 seconds.
However, if the user presses Ctrl-C, it interrupts the sleep and prints the
unslept amount.

For example:

unix> ./sleeper
sleeping for 5 seconds
unslept amount is 2 (User hits Ctrl-C after 3 seconds)
unix>

What's wrong with the code below?
-------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

unsigned int unslept;

void handler (int sig)
{
printf("unslept amount is %d",unslept);
exit(0);
}

int main()
{
signal(SIGINT,handler);
printf("sleeping for 5 seconds\n");
unslept = sleep(5);
return 0;
}

sleep() is off-topic, but signals are part of the C standard.

Try this:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

unsigned int unslept = 42;

void handler (int sig)
{
printf("unslept amount is %d\n",unslept);
exit(0);
}

int main()
{
signal(SIGINT,handler);
printf("sleeping for 5 seconds\n");
unslept = sleep(5);
return 0;
}

(I've added a newline to the message printed by handler(), and I've
initialized unslept to 42.)

If the call to sleep() is interrupted by a SIGINT, it never returns,
so the assignment "unslept = sleep(5);" is never executed. The
variable retains its previous value, which is 0 in your original
program, 42 in my version.
 
K

Keith Thompson

Keith Thompson said:
sleep() is off-topic, but signals are part of the C standard.

Try this:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

unsigned int unslept = 42;

void handler (int sig)
{
printf("unslept amount is %d\n",unslept);
exit(0);
}

int main()
{
signal(SIGINT,handler);
printf("sleeping for 5 seconds\n");
unslept = sleep(5);
return 0;
}

(I've added a newline to the message printed by handler(), and I've
initialized unslept to 42.)

If the call to sleep() is interrupted by a SIGINT, it never returns,
so the assignment "unslept = sleep(5);" is never executed. The
variable retains its previous value, which is 0 in your original
program, 42 in my version.

One more thing: the reason sleep() never returns is that you do an
exit(0) in the signal handler. If you delete that line, you'll find
that the sleep() call does complete, and the variable unslept is set
to whatever value it returns.

What that value might be depends on what the sleep() function does,
something not covered by the C standard.

Also, you should use "%u", not "%d", to print an unsigned int value.
 
W

Walter Roberson

Keith Thompson said:
sleep() is off-topic, but signals are part of the C standard.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
unsigned int unslept = 42;
void handler (int sig)
{
printf("unslept amount is %d\n",unslept);
exit(0);
}

The C89 standard says that except for signals occuring from
abort() or raise(), you have UB if the signal handler calls
any library function other than signal() or refers to any static
variable that isn't volatile sig_atomic_t .

Your example code refers to a static variable that isn't sig_atomic_t
and calls two library functions other than signal...
 
K

Keith Thompson

The C89 standard says that except for signals occuring from
abort() or raise(), you have UB if the signal handler calls
any library function other than signal() or refers to any static
variable that isn't volatile sig_atomic_t .

Your example code refers to a static variable that isn't sig_atomic_t
and calls two library functions other than signal...

D'oh!

(It almost certainly happens to "work" in the environment the OP is
using, but of course that's beside the point.)

BTW, the OP posted to comp.unix.programmer and got some good answers
there.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top