©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c9/slp.c

Go to the documentation of this file.
00001 /*
00002     sleep implementation using alarm
00003     AUP2, Sec. 9.07.2
00004 
00005     Thanks to Geoff Clare for correcting the original version.
00006 
00007     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00008     May be copied only for purposes and under conditions described
00009     on the Web page www.basepath.com/aup/copyright.htm.
00010 
00011     The Example Files are provided "as is," without any warranty;
00012     without even the implied warranty of merchantability or fitness
00013     for a particular purpose. The author and his publisher are not
00014     responsible for any damages, direct or incidental, resulting
00015     from the use or non-use of these Example Files.
00016 
00017     The Example Files may contain defects, and some contain deliberate
00018     coding mistakes that were included for educational reasons.
00019     You are responsible for determining if and how the Example Files
00020     are to be used.
00021 
00022 */
00023 #include "defs.h"
00024 /*[slp_handler]*/
00025 static void slp_handler(int signum)
00026 {
00027 }
00028 /*[pgm]*/
00029 unsigned aup_sleep(unsigned secs)
00030 {
00031     sigset_t set, oset;
00032     struct sigaction act, oact;
00033     unsigned prev_alarm, slept, unslept, effective_secs;
00034 
00035     ec_neg1( sigemptyset(&set) )
00036     ec_neg1( sigaddset(&set, SIGALRM) )
00037     ec_neg1( sigprocmask(SIG_BLOCK, &set, &oset) )
00038     prev_alarm = alarm(0);
00039     if (prev_alarm != 0 && prev_alarm <= secs)
00040         effective_secs = prev_alarm;
00041     else {
00042         memset(&act, 0, sizeof(act));
00043         act.sa_handler = slp_handler;
00044         ec_neg1( sigaction(SIGALRM, &act, &oact) )
00045         effective_secs = secs;
00046     }
00047     alarm(effective_secs);
00048     set = oset;
00049     ec_neg1( sigdelset(&set, SIGALRM) )
00050     if (sigsuspend(&set) == -1 && errno != EINTR)
00051         EC_FAIL
00052     unslept = alarm(0);
00053     slept = effective_secs - unslept;
00054     ec_neg1( sigaction(SIGALRM, &oact, NULL) )
00055     if (prev_alarm > slept)
00056         alarm(prev_alarm - slept);
00057     ec_neg1( sigprocmask(SIG_SETMASK, &oset, NULL) )
00058     return unslept;
00059 
00060 EC_CLEANUP_BGN
00061     EC_FLUSH("aup_sleep")
00062     return 0;
00063 EC_CLEANUP_END
00064 }
00065 /*[]*/
00066 static void alarm_handler(int signum)
00067 {
00068     write(STDOUT_FILENO, "SIGALRM handler\n", 16);
00069 }
00070 
00071 int main(void)
00072 {
00073     struct sigaction act;
00074     time_t tm;
00075 
00076     memset(&act, 0, sizeof(act));
00077     act.sa_handler = alarm_handler;
00078     ec_neg1( sigaction(SIGALRM, &act, NULL) )
00079     time(&tm);
00080     printf("Test 1 -- time %ld\n", (long)tm);
00081     aup_sleep(6);
00082     time(&tm);
00083     printf("Test 2 -- time %ld\n", (long)tm);
00084     alarm(3);
00085     aup_sleep(6);
00086     time(&tm);
00087     printf("Test 3 -- time %ld\n", (long)tm);;
00088     alarm(9);
00089     aup_sleep(6);
00090     time(&tm);
00091     printf("Sleep over; now pausing -- time %ld\n", (long)tm);
00092     pause();
00093     time(&tm);
00094     printf("Exiting  -- time %ld\n", (long)tm);
00095     exit(EXIT_SUCCESS);
00096 
00097 EC_CLEANUP_BGN
00098     exit(EXIT_FAILURE);
00099 EC_CLEANUP_END
00100 }

Generated on Fri Apr 23 10:57:03 2004 for AUP2 Example Source by doxygen 1.3.1