*** empty log message ***
[arla.git] / lwp / iomgr.c
blob080aa676c05ed94a93247cb5f11f9b7823b996c4
1 /*
2 ****************************************************************************
3 * Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
4 * *
5 * Permission to use, copy, modify, and distribute this software and its *
6 * documentation for any purpose and without fee is hereby granted, *
7 * provided that the above copyright notice appear in all copies and *
8 * that both that copyright notice and this permission notice appear in *
9 * supporting documentation, and that the name of IBM not be used in *
10 * advertising or publicity pertaining to distribution of the software *
11 * without specific, written prior permission. *
12 * *
13 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
15 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
16 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
17 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
18 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
19 ****************************************************************************
22 /*******************************************************************\
23 * *
24 * Information Technology Center *
25 * Carnegie-Mellon University *
26 * *
27 * *
28 * *
29 \*******************************************************************/
33 * IO Manager routines & server process for VICE server.
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 RCSID("$Id$");
39 #endif
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include "lwp.h"
44 #include <sys/time.h>
45 #include "timer.h"
46 #include <signal.h>
47 #include <errno.h>
48 #include <fcntl.h>
49 #include <sys/file.h>
50 #include "q.h"
51 #include <unistd.h>
52 #include <string.h>
53 #include <roken.h>
55 /* Prototypes */
56 static void SignalIO(int, fd_set *, fd_set *, fd_set *) ;
57 static void SignalTimeout(int fds, struct timeval *timeout) ;
58 static int SignalSignals (void);
60 int FT_GetTimeOfDay(struct timeval *, struct timezone *);
62 /********************************\
63 * *
64 * Stuff for managing IoRequests *
65 * *
66 \********************************/
68 struct IoRequest {
70 /* Pid of process making request (for use in IOMGR_Cancel) */
71 PROCESS pid;
73 /* Descriptor masks for requests */
74 fd_set readfds;
75 fd_set writefds;
76 fd_set exceptfds;
78 fd_set *rfds;
79 fd_set *wfds;
80 fd_set *efds;
82 int nfds;
84 struct TM_Elem timeout;
86 /* Result of select call */
87 int result;
88 struct IoRequest *next;
91 /********************************\
92 * *
93 * Stuff for managing signals *
94 * *
95 \********************************/
97 #define badsig(signo) (((signo) <= 0) || ((signo) >= NSIG))
98 #define mysigmask(signo) (1 << ((signo)-1))
100 static long openMask; /* mask of open files on an IOMGR abort */
101 static long sigsHandled; /* sigmask(signo) is on if we handle signo */
102 static int anySigsDelivered; /* true if any have been delivered. */
103 #ifdef AFS_POSIX_SIGNALS
104 static struct sigaction oldVecs[NSIG]; /* the old signal vectors */
105 #else
106 static struct sigvec oldVecs[NSIG]; /* the old signal vectors */
107 #endif
108 static char *sigEvents[NSIG]; /* the event to do an LWP signal on */
109 static int sigDelivered[NSIG]; /*
110 * True for signals delivered so far.
111 * This is an int array to make sure
112 * there are no conflicts when trying
113 * to write it
115 /* software 'signals' */
116 #define NSOFTSIG 4
117 static void (*sigProc[NSOFTSIG])();
118 static char *sigRock[NSOFTSIG];
121 static struct IoRequest *iorFreeList = 0;
123 static struct TM_Elem *Requests; /* List of requests */
124 static struct timeval iomgr_timeout; /* global so signal handler can zap it */
126 /* stuff for debugging */
127 static int iomgr_errno;
128 static struct timeval iomgr_badtv;
129 static PROCESS iomgr_badpid;
131 static void
132 FreeRequest(struct IoRequest *req)
134 req->next = iorFreeList;
135 iorFreeList = req;
138 /* stuff for handling select fd_sets */
140 #ifndef FD_COPY
141 #define FD_COPY(f, t) memcpy((t), (f), sizeof(*(f)))
142 #endif
145 * FD_OR - bitwise or of two fd_sets
146 * The result goes into set1
148 static void
149 FD_OR(fd_set *set1, fd_set *set2)
151 int i;
153 #ifdef FD_SPEED_HACK
154 unsigned long *s1 = (unsigned long *)set1;
155 unsigned long *s2 = (unsigned long *)set2;
157 for (i = 0; i < sizeof(fd_set)/sizeof(unsigned long); i++)
158 s1[i] |= s2[i];
159 #else
160 for (i = 0; i < FD_SETSIZE; i++)
161 if (FD_ISSET(i, set1) || FD_ISSET(i, set2))
162 FD_SET(i, set1);
163 #endif
167 * FD_AND - bitwise and of two fd_sets
168 * The result goes into set1
170 static void
171 FD_AND(fd_set *set1, fd_set *set2)
173 int i;
175 #ifdef FD_SPEED_HACK
176 unsigned long *s1 = (unsigned long *)set1;
177 unsigned long *s2 = (unsigned long *)set2;
179 for(i = 0; i < sizeof(fd_set)/sizeof(unsigned long); i++)
180 s1[i] &= s2[i];
181 #else
182 for(i = 0; i < FD_SETSIZE; i++)
183 if (FD_ISSET(i, set1) && FD_ISSET(i, set2))
184 FD_SET(i, set1);
185 #endif
189 * FD_LOGAND - "logical" and of two fd_sets
190 * returns 0 if there are no fds that are the same in both fd_sets
191 * otherwise it returns 1
193 static int
194 FD_LOGAND(fd_set *set1, fd_set *set2)
196 #ifdef FD_SPEED_HACK
197 int i;
199 unsigned long *s1 = (unsigned long *)set1;
200 unsigned long *s2 = (unsigned long *)set2;
202 for(i = 0; i < sizeof(fd_set)/sizeof(unsigned long); i++)
203 if ((s1[i] & s2[i]) != 0)
204 return 1;
205 return 0;
206 #else
207 fd_set tmp;
209 FD_COPY(set1, &tmp);
210 FD_AND(&tmp, set2);
212 return !FD_ISZERO(&tmp);
213 #endif
216 static struct IoRequest *
217 NewRequest(void)
219 struct IoRequest *request;
221 if ((request = iorFreeList) != NULL)
222 iorFreeList = request->next;
223 else
224 request = (struct IoRequest *) malloc(sizeof(struct IoRequest));
226 return request;
229 #define Purge(list) FOR_ALL_ELTS(req, list, { free(req->BackPointer); })
230 #define MAX_FDS 32
232 /* The IOMGR process */
235 * Important invariant: process->iomgrRequest is null iff request not in
236 * timer queue also, request->pid is valid while request is in queue, also,
237 * don't signal selector while request in queue, since selector free's request.
240 static void
241 IOMGR(char *dummy)
243 for (;;) {
244 int fds;
245 int nfds;
246 fd_set readfds, writefds, exceptfds;
247 fd_set *rfds, *wfds, *efds;
248 struct TM_Elem *earliest;
249 struct timeval timeout, junk;
250 bool woke_someone;
253 * Wake up anyone who has expired or who has received a
254 * Unix signal between executions. Keep going until we
255 * run out.
257 do {
258 woke_someone = FALSE;
259 /* Wake up anyone waiting on signals. */
260 /* Note: SignalSignals() may yield! */
261 if (anySigsDelivered && SignalSignals ())
262 woke_someone = TRUE;
263 TM_Rescan(Requests);
264 for (;;) {
265 struct IoRequest *req;
266 struct TM_Elem *expired;
267 expired = TM_GetExpired(Requests);
268 if (expired == NULL) break;
269 woke_someone = TRUE;
270 req = (struct IoRequest *) expired -> BackPointer;
271 #ifdef DEBUG
272 if (lwp_debug != 0) puts("[Polling SELECT]");
273 #endif /* DEBUG */
274 FD_ZERO(&req->readfds);
275 FD_ZERO(&req->writefds);
276 FD_ZERO(&req->exceptfds);
277 /* no data ready */
278 req->nfds = 0;
279 req->rfds = req->wfds = req->efds = NULL;
281 req->result = 0;
282 /* no fds ready */
284 TM_Remove(Requests, &req->timeout);
285 #ifdef DEBUG
286 req -> timeout.Next = (struct TM_Elem *) 2;
287 req -> timeout.Prev = (struct TM_Elem *) 2;
288 #endif /* DEBUG */
289 LWP_QSignal(req->pid);
290 req->pid->iomgrRequest = 0;
292 if (woke_someone) LWP_DispatchProcess();
293 } while (woke_someone);
296 /* Collect requests & update times */
297 FD_ZERO(&readfds); /* XXX - should not be needed */
298 FD_ZERO(&writefds);
299 FD_ZERO(&exceptfds);
300 nfds = 0;
301 rfds = wfds = efds = NULL;
302 FOR_ALL_ELTS(r, Requests, {
303 struct IoRequest *req;
304 req = (struct IoRequest *) r -> BackPointer;
305 if (req->rfds) {
306 if (rfds)
307 FD_OR(rfds, req->rfds);
308 else {
309 rfds = &readfds;
310 FD_COPY(req->rfds, rfds);
314 if (req->wfds) {
315 if (wfds)
316 FD_OR(wfds, req->wfds);
317 else {
318 wfds = &writefds;
319 FD_COPY(req->wfds, wfds);
323 if (req->efds) {
324 if (efds)
325 FD_OR(efds, req->efds);
326 else {
327 efds = &exceptfds;
328 FD_COPY(req->efds, efds);
331 nfds = max(nfds, req->nfds);
333 earliest = TM_GetEarliest(Requests);
334 if (earliest != NULL) {
335 timeout = earliest -> TimeLeft;
337 /* Do select */
338 #ifdef DEBUG
339 if (lwp_debug != 0) {
340 printf("[select(%d, %p, %p, %p, ", nfds,
341 rfds, wfds, efds);
342 if (timeout.tv_sec == -1 && timeout.tv_usec == -1)
343 puts("INFINITE)]");
344 else
345 printf("<%ld, %lu>)]\n",
346 (long)timeout.tv_sec,
347 (unsigned long)timeout.tv_usec);
349 #endif /* DEBUG */
350 iomgr_timeout = timeout;
351 if (timeout.tv_sec == -1 && timeout.tv_usec == -1) {
352 /* infinite, sort of */
353 iomgr_timeout.tv_sec = 100000000;
354 iomgr_timeout.tv_usec = 0;
357 * Check one last time for a signal delivery. If one comes after
358 * this, the signal handler will set iomgr_timeout to zero,
359 * causing the select to return immediately. The timer package
360 * won't return a zero timeval because all of those guys were
361 * handled above.
363 * I'm assuming that the kernel masks signals while it's picking up
364 * the parameters to select. This may a bad assumption. -DN
366 if (anySigsDelivered)
367 continue; /* go to the top and handle them. */
370 * select runs much faster if NULL's are passed instead of &0s
373 fds = select(nfds, rfds, wfds, efds, &iomgr_timeout);
376 * For SGI and SVR4 - poll & select can return EAGAIN ...
378 if (fds < 0
379 && errno != EINTR && errno != EAGAIN && errno != ENOMEM) {
380 iomgr_errno = errno;
381 for(fds = 0; fds < FD_SETSIZE; fds++) {
382 if (fcntl(fds, F_GETFD, 0) < 0 && errno == EBADF)
383 openMask |= (1<<fds);
385 abort();
388 /* force a new gettimeofday call so FT_AGetTimeOfDay calls work */
389 FT_GetTimeOfDay(&junk, 0);
391 /* See what happened */
392 if (fds > 0)
393 /* Action -- wake up everyone involved */
394 SignalIO(fds, rfds, wfds, efds);
395 else if (fds == 0
396 && (iomgr_timeout.tv_sec != 0 || iomgr_timeout.tv_usec != 0))
397 /* Real timeout only if signal handler hasn't set
398 iomgr_timeout to zero. */
399 SignalTimeout(fds, &timeout);
402 LWP_DispatchProcess();
406 /************************\
408 * Signalling routines *
410 \************************/
412 static void
413 SignalIO(int fds, fd_set *rfds, fd_set *wfds, fd_set *efds)
415 /* Look at everyone who's bit mask was affected */
416 FOR_ALL_ELTS(r, Requests, {
417 struct IoRequest *req;
418 PROCESS pid;
419 int doit = 0;
420 req = (struct IoRequest *) r -> BackPointer;
422 if (rfds && req->rfds && FD_LOGAND(req->rfds, rfds)) {
423 FD_AND(req->rfds, rfds);
424 doit = 1;
426 if (wfds && req->wfds && FD_LOGAND(req->wfds, wfds)) {
427 FD_AND(req->wfds, wfds);
428 doit = 1;
430 if (efds && req->efds && FD_LOGAND(req->efds, efds)) {
431 FD_AND(req->efds, efds);
432 doit = 1;
435 if (doit) {
436 req -> result = fds;
437 TM_Remove(Requests, &req->timeout);
438 LWP_QSignal(pid=req->pid);
439 pid->iomgrRequest = 0;
445 static void
446 SignalTimeout(int fds, struct timeval *timeout)
448 /* Find everyone who has specified timeout */
449 FOR_ALL_ELTS(r, Requests, {
450 struct IoRequest *req;
451 PROCESS pid;
452 req = (struct IoRequest *) r -> BackPointer;
453 if (TM_eql(&r->TimeLeft, timeout)) {
454 req -> result = fds;
455 TM_Remove(Requests, &req->timeout);
456 LWP_QSignal(pid=req->pid);
457 pid->iomgrRequest = 0;
458 } else
459 return;
463 /*****************************************************\
465 * Signal handling routine (not to be confused with *
466 * signalling routines, above). *
468 \*****************************************************/
469 static RETSIGTYPE
470 SigHandler (int signo)
472 if (badsig(signo) || (sigsHandled & mysigmask(signo)) == 0)
473 return; /* can't happen. */
474 sigDelivered[signo] = TRUE;
475 anySigsDelivered = TRUE;
476 /* Make sure that the IOMGR process doesn't pause on the select. */
477 iomgr_timeout.tv_sec = 0;
478 iomgr_timeout.tv_usec = 0;
481 /* Alright, this is the signal signalling routine. It delivers LWP signals
482 to LWPs waiting on Unix signals. NOW ALSO CAN YIELD!! */
483 static int
484 SignalSignals (void)
486 bool gotone = FALSE;
487 int i;
488 void (*p)();
489 long stackSize;
491 anySigsDelivered = FALSE;
493 /* handle software signals */
494 stackSize = (AFS_LWP_MINSTACKSIZE < lwp_MaxStackSeen?
495 lwp_MaxStackSeen : AFS_LWP_MINSTACKSIZE);
496 for (i=0; i < NSOFTSIG; i++) {
497 PROCESS pid;
498 if ((p = sigProc[i]) != NULL) /* This yields!!! */
499 LWP_CreateProcess(p, stackSize, LWP_NORMAL_PRIORITY, sigRock[i],
500 "SignalHandler", &pid);
501 sigProc[i] = 0;
504 for (i = 1; i <= NSIG; ++i) /* forall !badsig(i) */
505 if ((sigsHandled & mysigmask(i)) && sigDelivered[i] == TRUE) {
506 sigDelivered[i] = FALSE;
507 LWP_NoYieldSignal (sigEvents[i]);
508 gotone = TRUE;
510 return gotone;
514 /***************************\
516 * User-callable routines *
518 \***************************/
521 /* Keep IOMGR process id */
522 static PROCESS IOMGR_Id = NULL;
525 IOMGR_SoftSig(void (*aproc)(), char *arock)
527 int i;
528 for (i=0;i<NSOFTSIG;i++) {
529 if (sigProc[i] == 0) {
530 /* a free entry */
531 sigProc[i] = aproc;
532 sigRock[i] = arock;
533 anySigsDelivered = TRUE;
534 iomgr_timeout.tv_sec = 0;
535 iomgr_timeout.tv_usec = 0;
536 return 0;
539 return -1;
544 IOMGR_Initialize(void)
546 PROCESS pid;
548 /* If lready initialized, just return */
549 if (IOMGR_Id != NULL) return LWP_SUCCESS;
551 /* Init LWP if someone hasn't yet. */
552 if (LWP_InitializeProcessSupport (LWP_NORMAL_PRIORITY, &pid)
553 != LWP_SUCCESS)
554 return -1;
556 /* Initialize request lists */
557 if (TM_Init(&Requests) < 0) return -1;
559 /* Initialize signal handling stuff. */
560 sigsHandled = 0;
561 anySigsDelivered = TRUE; /*
562 * A soft signal may have happened before
563 * IOMGR_Initialize: so force a check for
564 * signals regardless
567 return LWP_CreateProcess(IOMGR, AFS_LWP_MINSTACKSIZE, 0, 0,
568 "IO MANAGER", &IOMGR_Id);
572 IOMGR_Finalize(void)
574 int status;
576 Purge(Requests)
577 TM_Final(&Requests);
578 status = LWP_DestroyProcess(IOMGR_Id);
579 IOMGR_Id = NULL;
580 return status;
584 * signal I/O for anyone who is waiting for a FD or a timeout;
585 * not too cheap, since forces select and timeofday check
587 long
588 IOMGR_Poll(void)
590 fd_set readfds, writefds, exceptfds;
591 fd_set *rfds, *wfds, *efds;
592 long code;
593 struct timeval tv;
594 int nfds;
596 FT_GetTimeOfDay(&tv, 0); /* force accurate time check */
597 TM_Rescan(Requests);
598 for (;;) {
599 struct IoRequest *req;
600 struct TM_Elem *expired;
601 expired = TM_GetExpired(Requests);
602 if (expired == NULL) break;
603 req = (struct IoRequest *) expired -> BackPointer;
604 #ifdef DEBUG
605 if (lwp_debug != 0) puts("[Polling SELECT]");
606 #endif /* DEBUG */
607 /* no data ready */
609 FD_ZERO(&req->readfds);
610 FD_ZERO(&req->writefds);
611 FD_ZERO(&req->exceptfds);
613 req->nfds = 0;
614 req->rfds = req->wfds = req->efds = NULL;
616 req->result = 0; /* no fds ready */
617 TM_Remove(Requests, &req->timeout);
618 #ifdef DEBUG
619 req -> timeout.Next = (struct TM_Elem *) 2;
620 req -> timeout.Prev = (struct TM_Elem *) 2;
621 #endif /* DEBUG */
622 LWP_QSignal(req->pid);
623 req->pid->iomgrRequest = 0;
626 /* Collect requests & update times */
627 FD_ZERO(&readfds); /* XXX - should not be needed */
628 FD_ZERO(&writefds);
629 FD_ZERO(&exceptfds);
630 rfds = wfds = efds = NULL;
631 nfds = 0;
632 FOR_ALL_ELTS(r, Requests, {
633 struct IoRequest *req;
634 req = (struct IoRequest *) r -> BackPointer;
636 if (req->rfds) {
637 if (rfds)
638 FD_OR(rfds, req->rfds);
639 else {
640 rfds = &readfds;
641 FD_COPY(req->rfds, rfds);
645 if (req->wfds) {
646 if (wfds)
647 FD_OR(wfds, req->wfds);
648 else {
649 wfds = &writefds;
650 FD_COPY(req->wfds, wfds);
654 if (req->efds) {
655 if (efds)
656 FD_OR(efds, req->efds);
657 else {
658 efds = &exceptfds;
659 FD_COPY(req->efds, efds);
662 nfds = max(nfds, req->nfds);
665 tv.tv_sec = 0;
666 tv.tv_usec = 0;
667 code = select(nfds, rfds, wfds, efds, &tv);
669 if (code > 0) {
670 SignalIO(code, rfds, wfds, efds);
673 LWP_DispatchProcess(); /* make sure others run */
674 LWP_DispatchProcess();
675 return 0;
679 IOMGR_Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
680 struct timeval *timeout)
682 struct IoRequest *request;
683 int result;
685 /* See if polling request. If so, handle right here */
686 if (timeout != NULL) {
687 if (timeout->tv_sec == 0 && timeout->tv_usec == 0) {
688 int fds;
689 #ifdef DEBUG
690 if (lwp_debug != 0) puts("[Polling SELECT]");
691 #endif /* DEBUG */
693 do {
694 timeout->tv_sec = 0;
695 timeout->tv_usec = 0;
696 fds = select(nfds, readfds, writefds, exceptfds,
697 timeout);
698 } while (fds < 0 && errno == EAGAIN);
700 return (fds > 1 ? 1 : fds);
704 /* Construct request block & insert */
705 request = NewRequest();
706 if (readfds == NULL)
707 request->rfds = NULL;
708 else {
709 request->rfds = &request->readfds;
710 FD_COPY(readfds, request->rfds);
713 if (writefds == NULL)
714 request->wfds = NULL;
715 else {
716 request->wfds = &request->writefds;
717 FD_COPY(writefds, request->wfds);
720 if (exceptfds == NULL)
721 request->efds = NULL;
722 else {
723 request->efds = &request->exceptfds;
724 FD_COPY(exceptfds, request->efds);
727 request->nfds = nfds;
729 if (timeout == NULL) {
730 request -> timeout.TotalTime.tv_sec = -1;
731 request -> timeout.TotalTime.tv_usec = -1;
732 } else {
733 request -> timeout.TotalTime = *timeout;
734 /* check for bad request */
735 if (timeout->tv_sec < 0 ||
736 timeout->tv_usec < 0 ||
737 timeout->tv_usec > 999999) {
738 /* invalid arg */
739 iomgr_badtv = *timeout;
740 iomgr_badpid = LWP_ActiveProcess;
741 /* now fixup request */
742 if(request->timeout.TotalTime.tv_sec < 0)
743 request->timeout.TotalTime.tv_sec = 1;
744 request->timeout.TotalTime.tv_usec = 100000;
748 request -> timeout.BackPointer = (char *) request;
750 /* Insert my PID in case of IOMGR_Cancel */
751 request -> pid = LWP_ActiveProcess;
752 LWP_ActiveProcess -> iomgrRequest = request;
754 #ifdef DEBUG
755 request -> timeout.Next = (struct TM_Elem *) 1;
756 request -> timeout.Prev = (struct TM_Elem *) 1;
757 #endif /* DEBUG */
758 TM_Insert(Requests, &request->timeout);
760 /* Wait for action */
761 LWP_QWait();
763 /* Update parameters & return */
764 if (readfds != NULL) FD_COPY(&request->readfds, readfds);
765 if (writefds != NULL) FD_COPY(&request->writefds, writefds);
766 if (exceptfds != NULL) FD_COPY(&request->exceptfds, exceptfds);
767 result = request -> result;
768 FreeRequest(request);
769 return (result > 1 ? 1 : result);
773 IOMGR_Cancel(PROCESS pid)
775 struct IoRequest *request;
777 if ((request = pid->iomgrRequest) == 0) return -1; /* Pid not found */
779 FD_ZERO(&request->readfds);
780 FD_ZERO(&request->writefds);
781 FD_ZERO(&request->exceptfds);
782 request->rfds = request->wfds = request->efds = NULL;
783 request->nfds = 0;
785 request -> result = -2;
786 TM_Remove(Requests, &request->timeout);
787 #ifdef DEBUG
788 request -> timeout.Next = (struct TM_Elem *) 5;
789 request -> timeout.Prev = (struct TM_Elem *) 5;
790 #endif /* DEBUG */
791 LWP_QSignal(request->pid);
792 pid->iomgrRequest = 0;
794 return 0;
798 * Cause delivery of signal signo to result in a LWP_SignalProcess of
799 * event.
802 IOMGR_Signal (int signo, char *event)
804 #ifdef AFS_POSIX_SIGNALS
805 struct sigaction sa;
806 #else
807 struct sigvec sv;
808 #endif
810 if (badsig(signo))
811 return LWP_EBADSIG;
812 if (event == NULL)
813 return LWP_EBADEVENT;
814 #ifdef AFS_POSIX_SIGNALS
815 sa.sa_handler = SigHandler;
816 sigfillset(&sa.sa_mask);
817 sa.sa_flags=0;
818 #else
819 sv.sv_handler = SigHandler;
820 sv.sv_mask = ~0; /* mask all signals */
821 sv.sv_onstack = 0;
822 #endif
823 sigsHandled |= mysigmask(signo);
824 sigEvents[signo] = event;
825 sigDelivered[signo] = FALSE;
826 #ifdef AFS_POSIX_SIGNALS
827 if (sigaction (signo, &sa, &oldVecs[signo]) == -1)
828 return LWP_ESYSTEM;
829 #else
830 if (sigvec (signo, &sv, &oldVecs[signo]) == -1)
831 return LWP_ESYSTEM;
832 #endif
833 return LWP_SUCCESS;
836 /* Stop handling occurances of signo. */
838 IOMGR_CancelSignal (int signo)
840 if (badsig(signo) || (sigsHandled & mysigmask(signo)) == 0)
841 return LWP_EBADSIG;
842 #ifdef AFS_POSIX_SIGNALS
843 sigaction (signo, &oldVecs[signo], (struct sigaction *)0);
844 #else
845 sigvec (signo, &oldVecs[signo], (struct sigvec *)0);
846 #endif
847 sigsHandled &= ~mysigmask(signo);
848 return LWP_SUCCESS;
852 * This routine calls select is a fashion that simulates the standard
853 * sleep routine
855 void
856 IOMGR_Sleep (unsigned int seconds)
858 struct timeval timeout;
860 timeout.tv_sec = seconds;
861 timeout.tv_usec = 0;
862 IOMGR_Select(0, NULL, NULL, NULL, &timeout);