merge 64-bit fixes from Fernando Lucas Rodriguez <fernando_lr@terra.es>
[debian/gcpegg] / usleep.c
1 /*
2
3     Emulation of BSD usleep()
4
5     Note that this is not a complete emulation in that
6     it destroys any pre-existing setitimer(), but it's
7     good enough for programs which don't have interval
8     timers running across calls on usleep().  It does
9     save and restore an existing SIGALRM handler.
10
11 */
12
13 #ifdef USLEEP
14 #include <stdio.h>
15 #include <signal.h>
16 #include <unistd.h>
17 #include <sys/signal.h>
18 #include <sys/time.h>
19
20 #ifdef Solaris
21 typedef void (*signalFUNC)(int);
22 #define signal(a, b)    sigset(a, (signalFUNC) b)
23 #define signalFUNCreturn (signalFUNC)
24 #endif
25
26 #ifndef signalFUNCreturn
27 #define signalFUNCreturn
28 #endif
29
30 #ifdef FLUSH
31 #include <termios.h>
32 int flush_fd = -1;                    /* File descriptor for auto-flush */
33 #endif
34
35 volatile static int waiting;
36
37 static void getalrm(int i)
38 {
39     waiting = 0;
40 }
41
42 void sf_usleep(unsigned t)
43 {
44     static struct itimerval it;
45     void (*oldsig)();
46
47     oldsig = signalFUNCreturn signal(SIGALRM, getalrm);
48 #ifdef FLUSH
49 #define FLUSHTIME 100000              /* Flush interval in microseconds */
50     if (flush_fd != -1) {
51         while (t > FLUSHTIME) {
52             it.it_value.tv_sec = 0;
53             it.it_value.tv_usec = FLUSHTIME;
54             t -= FLUSHTIME;
55             tcflush(flush_fd, TCIFLUSH);
56             waiting = 1;
57             if (setitimer(ITIMER_REAL, &it, NULL))
58                 return /*error*/;
59             while (waiting) {
60                 pause();
61             }
62             (void) signal(SIGALRM, getalrm);
63         }
64     }
65 #endif
66
67     it.it_value.tv_sec = t / 1000000;
68     it.it_value.tv_usec = t % 1000000;
69     waiting = 1;    
70     if (setitimer(ITIMER_REAL, &it, NULL))
71         return /*error*/;
72     while (waiting) {
73         pause();
74     }
75     signal(SIGALRM, oldsig);
76 }
77 #endif