xref: /titanic_50/usr/src/lib/efcode/engine/alarm.c (revision 3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1999 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <signal.h>
33 #include <unistd.h>
34 #include <fcode/private.h>
35 
36 /*
37  * 'user-abort' Fcode
38  */
39 void
40 user_abort(fcode_env_t *env)
41 {
42 	forth_abort(env, "user-abort called");
43 }
44 
45 static fstack_t alarm_xt;
46 static fstack_t alarm_ms;
47 static fcode_env_t *alarm_env;
48 
49 static void
50 catch_alarm(int signo)
51 {
52 	fcode_env_t *env = alarm_env;
53 
54 	if (env && alarm_xt && alarm_ms) {
55 		PUSH(DS, alarm_xt);
56 		execute(env);
57 		signal(SIGALRM, catch_alarm);
58 		alarm((alarm_ms + 999)/1000);
59 	}
60 }
61 
62 /*
63  * 'alarm' Fcode
64  */
65 void
66 do_alarm(fcode_env_t *env)
67 {
68 	fstack_t ms, xt;
69 
70 	CHECK_DEPTH(env, 2, "alarm");
71 	ms = POP(DS);
72 	xt = POP(DS);
73 	if (ms == 0) {
74 		alarm(0);
75 		signal(SIGALRM, SIG_DFL);
76 		alarm_xt = 0;
77 		alarm_ms = 0;
78 		alarm_env = 0;
79 	} else {
80 		signal(SIGALRM, catch_alarm);
81 		alarm_xt = xt;
82 		alarm_ms = ms;
83 		alarm_env = env;
84 		alarm((ms + 999)/1000);
85 	}
86 }
87 
88 #pragma init(_init)
89 
90 static void
91 _init(void)
92 {
93 	fcode_env_t *env = initial_env;
94 
95 	ASSERT(env);
96 	NOTICE;
97 
98 	P1275(0x213, 0,		"alarm",		do_alarm);
99 
100 	P1275(0x219, 0,		"user-abort",		user_abort);
101 }
102