8 typedef struct Signal Signal
;
9 typedef struct Action Action
;
10 typedef struct Queue Queue
;
11 typedef struct Timers Timers
;
12 typedef struct Handlers Handlers
;
13 typedef struct Private Private
;
70 Urestart
*freerestart
;
86 SA_ONSTACK
= 0x08000000,
87 SA_RESTART
= 0x10000000,
88 SA_NODEFER
= 0x40000000,
89 SA_RESETHAND
= 0x80000000,
98 #define MASK(sig) (1LL << ((sig)-1))
101 nextsignal(uvlong rblock
, int wait
);
104 getsignal(Private
*p
, Usiginfo
*pinfo
, int wait
);
107 initrestart(Uproc
*proc
)
118 poprestart(Private
*p
)
123 r
= current
->restart
;
124 if(r
->link
==nil
|| r
->syscall
)
126 current
->restart
= r
->link
;
128 r
->link
= p
->freerestart
;
132 current
->syscall
= r
->syscall
;
141 q
= kmallocz(sizeof(Queue
), 1);
145 for(i
=0; i
<nelem(q
->a
); i
++)
146 q
->a
[i
].next
= (i
+1 == nelem(q
->a
)) ? nil
: &q
->a
[i
+1];
158 h
= kmallocz(sizeof(Handlers
), 1);
160 for(i
=1; i
<SIGMAX
; i
++)
161 h
->a
[i
-1].handler
= (void*)SIG_DFL
;
170 t
= kmallocz(sizeof(Timers
), 1);
176 extern int get_ds(void);
177 extern int get_cs(void);
178 static ulong user_cs
, user_ds
;
180 void initsignal(void)
184 if(user_ds
==0 && user_cs
==0){
189 p
= kmallocz(sizeof(*p
), 1);
197 initrestart(current
);
200 void exitsignal(void)
209 if((p
= current
->signal
) == nil
)
211 current
->signal
= nil
;
215 for(i
=&q
->head
; *i
; i
=&((*i
)->next
)){
218 if(!r
->group
&& (r
->topid
== current
->tid
)){
219 if((*i
= r
->next
) == nil
)
238 while(r
= current
->restart
){
241 current
->restart
= r
->link
;
242 r
->link
= p
->freerestart
;
245 current
->restart
= nil
;
246 while(r
= p
->freerestart
){
247 p
->freerestart
= r
->link
;
253 void clonesignal(Uproc
*new, int copyhand
, int newproc
)
257 if((p
= current
->signal
) == nil
)
260 n
= kmallocz(sizeof(*n
), 1);
265 memmove(n
->h
->a
, p
->h
->a
, sizeof(n
->h
->a
));
275 n
->q
->tty
= getfile(p
->q
->tty
);
277 n
->altstack
= p
->altstack
;
298 if((p
= current
->signal
) == nil
)
314 if((p
= current
->signal
) == nil
)
317 tty
= getfile(p
->q
->tty
);
322 int ignoressignal(Uproc
*proc
, int sig
)
327 if((p
= proc
->signal
) == nil
)
330 a
= (int)p
->h
->a
[sig
-1].handler
;
331 f
= p
->h
->a
[sig
-1].flags
;
346 return (a
== SIG_IGN
);
349 int wantssignal(Uproc
*proc
, int sig
)
354 if(p
== nil
|| p
->block
& MASK(sig
))
356 return !ignoressignal(proc
, sig
);
359 int sendsignal(Uproc
*proc
, Usiginfo
*info
, int group
)
364 trace("sendsignal(%S) to %d from %d",
365 info
->signo
, proc
->tid
, (current
!= nil
) ? current
->tid
: 0);
367 if(ignoressignal(proc
, info
->signo
)){
368 trace("sendsignal(): ignored signal %S", info
->signo
);
374 if(info
->signo
< SIGRT1
){
375 for(s
=p
->q
->head
; s
; s
=s
->next
){
376 if(!s
->group
&& (s
->topid
!= proc
->tid
))
378 if(s
->signo
== info
->signo
){
380 trace("sendsignal(): droping follow up signal %S", info
->signo
);
385 if((s
= p
->q
->free
) == nil
){
387 trace("sendsignal(): out of signal buffers");
390 p
->q
->free
= s
->next
;
392 memmove(s
, info
, sizeof(*info
));
394 s
->topid
= group
? proc
->pid
: proc
->tid
;
396 p
->q
->tailp
= &s
->next
;
402 signalspending(Uproc
*proc
)
409 if(p
== nil
|| p
->q
->head
== nil
)
414 for(s
=p
->q
->head
; s
; s
=s
->next
){
415 if(!s
->group
&& (s
->topid
!= current
->tid
))
417 if(MASK(s
->signo
) & p
->block
)
428 getsignal(Private
*p
, Usiginfo
*pinfo
, int wait
)
434 if(!wait
&& p
->q
->head
== nil
)
440 for(i
=&p
->q
->head
; *i
; i
=&((*i
)->next
)){
443 if(!r
->group
&& (r
->topid
!= current
->tid
))
446 if(p
->block
& MASK(r
->signo
)){
453 /* dequeue nonblocked signal */
454 memmove(pinfo
, r
, sizeof(*pinfo
));
455 if((*i
= r
->next
) == nil
)
457 r
->next
= p
->q
->free
;
461 if(wait
&& sig
<= 0){
462 if(sleepproc(p
->q
, 0) == 0)
473 sigset2uvlong(uchar
*set
, int setsize
)
479 if(setsize
> sizeof(uvlong
))
480 setsize
= sizeof(uvlong
);
481 for(i
=0; i
<setsize
; i
++)
482 r
|= (uvlong
)set
[i
] << (i
* 8);
487 uvlong2sigset(uchar
*set
, int setsize
, uvlong mask
)
491 for(i
=0; i
<setsize
; i
++){
492 if(i
< sizeof(uvlong
)){
493 set
[i
] = ((mask
>> (i
*8)) & 0xff);
500 struct linux_siginfo
{
510 int pid
; /* sender's pid */
511 int uid
; /* sender's uid */
514 /* POSIX.1b timers */
516 int tid
; /* timer id */
517 int overrun
; /* overrun count */
518 int val
; /* same as below */
521 /* POSIX.1b signals */
523 int pid
; /* sender's pid */
524 int uid
; /* sender's uid */
530 int pid
; /* which child */
531 int uid
; /* sender's uid */
532 int status
; /* exit code */
537 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
539 void *addr
; /* faulting insn/memory ref. */
540 int trapno
; /* TRAP # which caused the signal */
545 long band
; /* POLL_IN, POLL_OUT, POLL_MSG */
552 siginfo2linux(Usiginfo
*info
, void *p
)
554 struct linux_siginfo
*li
= p
;
560 li
->errno
= info
->errno
;
561 li
->code
= info
->code
;
565 li
->timer
.tid
= info
->timer
.tid
;
566 li
->timer
.overrun
= info
->timer
.overrun
;
567 li
->timer
.val
= info
->timer
.val
;
570 li
->chld
.pid
= info
->chld
.pid
;
571 li
->chld
.uid
= info
->chld
.uid
;
572 li
->chld
.status
= info
->chld
.status
;
573 li
->chld
.utime
= info
->chld
.utime
;
574 li
->chld
.stime
= info
->chld
.stime
;
580 li
->fault
.addr
= info
->fault
.addr
;
581 li
->fault
.trapno
= info
->fault
.trapno
;
584 li
->poll
.fd
= info
->poll
.fd
;
585 li
->poll
.band
= info
->poll
.band
;
595 li
->rt
.pid
= info
->rt
.pid
;
596 li
->rt
.uid
= info
->rt
.uid
;
597 li
->rt
.val
= info
->rt
.val
;
600 li
->kill
.pid
= info
->kill
.pid
;
601 li
->kill
.uid
= info
->kill
.uid
;
606 linux2siginfo(void *p
, Usiginfo
*info
)
608 struct linux_siginfo
*li
= p
;
614 info
->errno
= li
->errno
;
615 info
->code
= li
->code
;
619 info
->timer
.tid
= li
->timer
.tid
;
620 info
->timer
.overrun
= li
->timer
.overrun
;
621 info
->timer
.val
= li
->timer
.val
;
624 info
->chld
.pid
= li
->chld
.pid
;
625 info
->chld
.uid
= li
->chld
.uid
;
626 info
->chld
.status
= li
->chld
.status
;
627 info
->chld
.utime
= li
->chld
.utime
;
628 info
->chld
.stime
= li
->chld
.stime
;
634 info
->fault
.addr
= li
->fault
.addr
;
635 info
->fault
.trapno
= li
->fault
.trapno
;
638 info
->poll
.fd
= li
->poll
.fd
;
639 info
->poll
.band
= li
->poll
.band
;
649 info
->rt
.pid
= li
->rt
.pid
;
650 info
->rt
.uid
= li
->rt
.uid
;
651 info
->rt
.val
= li
->rt
.val
;
654 info
->kill
.pid
= li
->kill
.pid
;
655 info
->kill
.uid
= li
->kill
.uid
;
659 struct linux_sigcontext
{
685 ureg2linuxsigcontext(Ureg
*u
, struct linux_sigcontext
*sc
)
699 sc
->trapno
= u
->trap
;
703 sc
->flags
= u
->flags
;
704 sc
->sp_at_signal
= u
->sp
;
709 struct linux_sigset
{
713 struct linux_signalstack
{
719 struct linux_ucontext
{
721 struct linux_ucontext
*link
;
722 struct linux_signalstack stack
;
723 struct linux_sigcontext context
;
724 struct linux_sigset sigmask
;
728 linuxsigcontext2ureg(struct linux_sigcontext
*sc
, Ureg
*u
)
748 struct linux_sigframe
{
753 struct linux_sigcontext sc
;
756 struct linux_siginfo
*pinfo
;
757 struct linux_ucontext
*puc
;
759 struct linux_siginfo info
;
760 struct linux_ucontext uc
;
768 linuxstackflags(Private
*p
, ulong sp
)
770 if(p
->altstack
.size
== 0 || p
->altstack
.sp
== 0)
772 if(sp
- p
->altstack
.sp
< p
->altstack
.size
)
778 linuxsignal(Private
*p
, Action
*a
, Usiginfo
*i
, uvlong rblock
)
780 struct linux_sigframe _frame
;
781 struct linux_sigframe
*f
;
787 stackflags
= linuxstackflags(p
, u
->sp
);
788 if((a
->flags
& SA_ONSTACK
) && (stackflags
== 0)){
789 trace("linuxsignal: altstack %lux %lux", p
->altstack
.sp
, p
->altstack
.size
);
790 f
= (struct linux_sigframe
*)(p
->altstack
.sp
+ p
->altstack
.size
);
796 trace("linuxsignal(): frame %p", f
);
797 memset(f
, 0, sizeof(*f
));
801 if(a
->flags
& SA_SIGINFO
){
802 f
->ret
= linux_rtsigreturn
;
803 siginfo2linux(i
, &f
->rt
.info
);
804 f
->rt
.pinfo
= &f
->rt
.info
;
806 f
->rt
.uc
.stack
.sp
= p
->altstack
.sp
;
807 f
->rt
.uc
.stack
.size
= p
->altstack
.size
;
808 f
->rt
.uc
.stack
.flags
= stackflags
;
810 ureg2linuxsigcontext(u
, &f
->rt
.uc
.context
);
811 f
->rt
.uc
.context
.oldmask
= rblock
& 0xFFFFFFFF;
812 f
->rt
.uc
.sigmask
.sig
[0] = rblock
& 0xFFFFFFFF;
813 f
->rt
.uc
.sigmask
.sig
[1] = (rblock
>> 32) & 0xFFFFFFFF;
814 f
->rt
.puc
= &f
->rt
.uc
;
815 u
->cx
= (ulong
)f
->rt
.puc
;
816 u
->dx
= (ulong
)f
->rt
.pinfo
;
818 f
->ret
= linux_sigreturn
;
819 ureg2linuxsigcontext(u
, &f
->sc
);
820 f
->sc
.oldmask
= rblock
& 0xFFFFFFFF;
830 u
->ax
= (ulong
)i
->signo
;
833 u
->pc
= (ulong
)a
->handler
;
840 p
->block
|= a
->block
;
842 trace("linuxsignal(): retuser pc=%lux sp=%lux", u
->pc
, u
->sp
);
849 struct linux_sigframe
*f
;
853 trace("sys_sigreturn()");
858 f
= (struct linux_sigframe
*)(u
->sp
- 4);
860 trace("sys_sigreturn(): frame %p", f
);
862 linuxsigcontext2ureg(&f
->sc
, u
);
863 p
->block
&= ~0xFFFFFFFF;
864 p
->block
|= f
->sc
.oldmask
;
865 nextsignal(p
->block
, 0);
868 trace("sys_sigreturn(): retuser pc=%lux sp=%lux", u
->pc
, u
->sp
);
875 sys_rt_sigreturn(void)
877 struct linux_sigframe
*f
;
881 trace("sys_rt_sigreturn()");
886 f
= (struct linux_sigframe
*)(u
->sp
- 4);
887 trace("sys_rt_sigreturn(): frame %p", f
);
889 linuxsigcontext2ureg(&f
->rt
.uc
.context
, u
);
890 p
->block
= (uvlong
)f
->rt
.uc
.sigmask
.sig
[0] | (uvlong
)f
->rt
.uc
.sigmask
.sig
[1]<<32;
891 nextsignal(p
->block
, 0);
894 trace("sys_rt_sigreturn(): pc=%lux sp=%lux", u
->pc
, u
->sp
);
901 * nextsignal transfers execution to the next pending
902 * signal or just returns. after the signal got executed,
903 * the block mask is restored to rblock. if heres no
904 * pending signal and wait is non zero the current
905 * process is suspended until here is a signal available.
909 nextsignal(uvlong rblock
, int wait
)
918 if((p
= current
->signal
) == nil
)
921 if(current
->wstate
& WSTOPPED
){
922 p
->block
= ~(MASK(SIGCONT
) | MASK(SIGKILL
));
923 sig
= getsignal(p
, &info
, 1);
928 contproc(current
, sig
, info
.group
);
932 if((sig
= getsignal(p
, &info
, wait
)) <= 0)
937 stopproc(current
, sig
, info
.group
);
944 trace("nextsignal(): signal %S", sig
);
948 if(a
.flags
& SA_RESETHAND
)
949 p
->h
->a
[sig
-1].handler
= (void*)SIG_DFL
;
950 if(a
.flags
& SA_NODEFER
== 0)
951 a
.block
|= MASK(sig
);
954 switch((int)a
.handler
){
964 trace("nextsignal(): signal %S causes exit", sig
);
965 exitproc(current
, sig
, 1);
969 trace("nextsignal(): signal %S ignored", sig
);
973 if(current
->restart
->syscall
){
974 if(a
.flags
& SA_RESTART
){
975 if(r
= p
->freerestart
)
976 p
->freerestart
= r
->link
;
978 r
= kmalloc(sizeof(*r
));
980 r
->link
= current
->restart
;
981 current
->restart
= r
;
983 trace("nextsignal(): interrupting syscall %s", current
->syscall
);
984 current
->sysret(-EINTR
);
988 linuxsignal(p
, &a
, &info
, rblock
);
991 void handlesignals(void)
995 if(p
= current
->signal
)
996 nextsignal(p
->block
, 0);
1000 sys_rt_sigsuspend(uchar
*set
, int setsize
)
1005 trace("sys_rt_sigsuspend(%p, %d)", set
, setsize
);
1007 p
= current
->signal
;
1008 b
= sigset2uvlong(set
, setsize
);
1009 b
&= ~(MASK(SIGKILL
) | MASK(SIGSTOP
));
1015 * if a signal got handled, it will pop out after the the
1016 * sigsuspend syscall with return value set to -EINTR
1018 current
->sysret(-EINTR
);
1021 nextsignal(rblock
, 1);
1026 struct linux_altstack
1033 int sys_sigaltstack(void *stk
, void *ostk
)
1036 struct linux_altstack
*a
= stk
, *oa
= ostk
;
1040 trace("sys_sigaltstack(%lux, %lux)", (ulong
)stk
, (ulong
)ostk
);
1042 p
= current
->signal
;
1043 sp
= p
->altstack
.sp
;
1044 size
= p
->altstack
.size
;
1045 flags
= linuxstackflags(p
, current
->ureg
->sp
);
1048 if(flags
== SS_ONSTACK
)
1051 if(a
->flags
== SS_DISABLE
){
1053 p
->altstack
.size
= 0;
1055 p
->altstack
.sp
= a
->sp
;
1056 p
->altstack
.size
= a
->size
;
1059 trace("sys_signalstack(): new altstack %lux-%lux",
1060 p
->altstack
.sp
, p
->altstack
.sp
+ p
->altstack
.size
);
1071 struct linux_sigaction
1079 int sys_rt_sigaction(int sig
, void *pact
, void *poact
, int setsize
)
1083 struct linux_sigaction
*act
;
1084 struct linux_sigaction
*oact
;
1089 trace("sys_rt_sigaction(%S, %p, %p, %d)", sig
, pact
, poact
, setsize
);
1091 p
= current
->signal
;
1092 act
= (struct linux_sigaction
*)pact
;
1093 oact
= (struct linux_sigaction
*)poact
;
1095 if((sig
< 1) || (sig
>= SIGMAX
))
1099 a
= &p
->h
->a
[sig
-1];
1100 handler
= a
->handler
;
1104 trace("flags = %x", a
->flags
);
1105 a
->handler
= act
->handler
;
1106 a
->flags
= act
->flags
;
1107 a
->block
= sigset2uvlong(act
->mask
, setsize
);
1110 oact
->handler
= handler
;
1111 oact
->flags
= flags
;
1113 uvlong2sigset(oact
->mask
, setsize
, block
);
1120 int sys_rt_sigpending(uchar
*set
, int setsize
)
1126 trace("sys_rt_sigpending(%p, %d)", set
, setsize
);
1128 p
= current
->signal
;
1131 for(s
=p
->q
->head
; s
; s
=s
->next
){
1132 if(!s
->group
&& (s
->topid
!= current
->tid
))
1134 m
|= MASK(s
->signo
);
1138 uvlong2sigset(set
, setsize
, m
);
1149 int sys_rt_sigprocmask(int how
, uchar
*act
, uchar
*oact
, int setsize
)
1154 trace("sys_rt_sigprocmask(%d, %p, %p, %d)", how
, act
, oact
, setsize
);
1156 p
= current
->signal
;
1159 m
= sigset2uvlong(act
, setsize
);
1160 m
&= ~(MASK(SIGKILL
) | MASK(SIGSTOP
));
1176 uvlong2sigset(oact
, setsize
, block
);
1182 struct linux_timeval it_interval
;
1183 struct linux_timeval it_value
;
1189 vlong q
= 1000000000LL/HZ
;
1190 return (t
+ q
-1) / q
;
1193 int sys_setitimer(int which
, void *value
, void *ovalue
)
1197 vlong now
, rem
, delta
;
1198 struct linux_itimer
*nv
= value
, *ov
= ovalue
;
1200 trace("sys_setitimer(%d, %p, %p)", which
, value
, ovalue
);
1202 p
= current
->signal
;
1205 if(which
< 0 || which
>= nelem(t
->itimer
))
1209 delta
= t
->itimer
[which
].interval
;
1210 rem
= t
->itimer
[which
].expire
- now
;
1214 trace("nv->{interval->{%ld, %ld}, value->{%ld, %ld}}",
1215 nv
->it_interval
.tv_sec
, nv
->it_interval
.tv_usec
,
1216 nv
->it_value
.tv_sec
, nv
->it_value
.tv_usec
);
1217 t
->itimer
[which
].interval
= hzround(nv
->it_interval
.tv_sec
*1000000000LL +
1218 nv
->it_interval
.tv_usec
*1000);
1219 t
->itimer
[which
].expire
= (now
+ nv
->it_value
.tv_sec
*1000000000LL +
1220 nv
->it_value
.tv_usec
*1000);
1221 setalarm(t
->itimer
[which
].expire
);
1225 ov
->it_interval
.tv_sec
= delta
/ 1000000000LL;
1226 ov
->it_interval
.tv_usec
= (delta
% 1000000000LL)/1000;
1227 ov
->it_value
.tv_sec
= rem
/ 1000000000LL;
1228 ov
->it_value
.tv_usec
= (rem
% 1000000000LL)/1000;
1229 trace("ov->{interval->{%ld, %ld}, value->{%ld, %ld}}",
1230 ov
->it_interval
.tv_sec
, ov
->it_interval
.tv_usec
,
1231 ov
->it_value
.tv_sec
, ov
->it_value
.tv_usec
);
1237 int sys_getitimer(int which
, void *value
)
1242 struct linux_itimer
*v
= value
;
1244 trace("sys_getitimer(%d, %p)", which
, value
);
1246 p
= current
->signal
;
1251 if(which
< 0 || which
>= nelem(t
->itimer
))
1254 delta
=t
->itimer
[which
].interval
;
1255 rem
= t
->itimer
[which
].expire
- nsec();
1259 v
->it_interval
.tv_sec
= delta
/ 1000000000LL;
1260 v
->it_interval
.tv_usec
= (delta
% 1000000000LL)/1000;
1261 v
->it_value
.tv_sec
= rem
/ 1000000000LL;
1262 v
->it_value
.tv_usec
= (rem
% 1000000000LL)/1000;
1267 int sys_alarm(long seconds
)
1273 trace("sys_alarm(%ld)", seconds
);
1274 p
= current
->signal
;
1277 old
= t
->itimer
[0].expire
- now
;
1280 t
->itimer
[0].interval
= 0;
1282 t
->itimer
[0].expire
= now
+ (vlong
)seconds
* 1000000000LL;
1283 setalarm(t
->itimer
[0].expire
);
1285 t
->itimer
[0].expire
= 0;
1287 return old
/ 1000000000LL;
1293 static char *t
[] = {
1294 [SIGHUP
] = "SIGHUP",
1295 [SIGINT
] = "SIGINT",
1296 [SIGQUIT
] = "SIGQUIT",
1297 [SIGILL
] = "SIGILL",
1298 [SIGTRAP
] = "SIGTRAP",
1299 [SIGABRT
] = "SIGABRT",
1300 [SIGBUS
] = "SIGBUS",
1301 [SIGFPE
] = "SIGFPE",
1302 [SIGKILL
] = "SIGKILL",
1303 [SIGUSR1
] = "SIGUSR1",
1304 [SIGSEGV
] = "SIGSEGV",
1305 [SIGUSR2
] = "SIGUSR2",
1306 [SIGPIPE
] = "SIGPIPE",
1307 [SIGALRM
] = "SIGALRM",
1308 [SIGTERM
] = "SIGTERM",
1309 [SIGSTKFLT
] = "SIGSTKFLT",
1310 [SIGCHLD
] = "SIGCHLD",
1311 [SIGCONT
] = "SIGCONT",
1312 [SIGSTOP
] = "SIGSTOP",
1313 [SIGTSTP
] = "SIGTSTP",
1314 [SIGTTIN
] = "SIGTTIN",
1315 [SIGTTOU
] = "SIGTTOU",
1316 [SIGURG
] = "SIGURG",
1317 [SIGXCPU
] = "SIGXCPU",
1318 [SIGXFSZ
] = "SIGXFSZ",
1319 [SIGVTALRM
] = "SIGVTALRM",
1320 [SIGPROF
] = "SIGPROF",
1321 [SIGWINCH
] = "SIGWINCH",
1323 [SIGPWR
] = "SIGPWR",
1324 [SIGSYS
] = "SIGSYS",
1325 [SIGRT1
] = "SIGRT1",
1326 [SIGRT2
] = "SIGRT2",
1327 [SIGRT3
] = "SIGRT3",
1328 [SIGRT4
] = "SIGRT4",
1329 [SIGRT5
] = "SIGRT5",
1330 [SIGRT6
] = "SIGRT6",
1331 [SIGRT7
] = "SIGRT7",
1332 [SIGRT8
] = "SIGRT8",
1337 sig
= va_arg(f
->args
, int);
1338 if(sig
< 1 || sig
>= SIGMAX
)
1339 return fmtprint(f
, "%d", sig
);
1340 return fmtprint(f
, "%d [%s]", sig
, t
[sig
]);
1344 extern int procsetalarm(Uproc
*proc
, vlong t
);
1347 alarmtimer(Uproc
*proc
, vlong now
)
1351 vlong expire
, delta
;
1355 if((p
= proc
->signal
) == nil
)
1358 for(i
=0; i
< nelem(t
->itimer
); i
++){
1359 expire
= t
->itimer
[i
].expire
;
1363 procsetalarm(proc
, expire
);
1367 delta
= (t
->itimer
[i
].interval
);
1370 while(expire
<= now
){
1374 procsetalarm(proc
, expire
);
1378 t
->itimer
[i
].expire
= expire
;
1380 memset(&si
, 0, sizeof(si
));
1384 si
.timer
.overrun
= overrun
;
1385 killproc(proc
, &si
, 1);