1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
5*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
6*0Sstevel@tonic-gate  * are met:
7*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
8*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
9*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
10*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
11*0Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
12*0Sstevel@tonic-gate  *
13*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14*0Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15*0Sstevel@tonic-gate  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16*0Sstevel@tonic-gate  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17*0Sstevel@tonic-gate  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18*0Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19*0Sstevel@tonic-gate  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20*0Sstevel@tonic-gate  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21*0Sstevel@tonic-gate  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22*0Sstevel@tonic-gate  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23*0Sstevel@tonic-gate  */
24*0Sstevel@tonic-gate /*
25*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
26*0Sstevel@tonic-gate  * Use is subject to license terms.
27*0Sstevel@tonic-gate  */
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include "includes.h"
30*0Sstevel@tonic-gate RCSID("$OpenBSD: misc.c,v 1.19 2002/03/04 17:27:39 stevesk Exp $");
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate #include "misc.h"
35*0Sstevel@tonic-gate #include "log.h"
36*0Sstevel@tonic-gate #include "xmalloc.h"
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate /* remove newline at end of string */
39*0Sstevel@tonic-gate char *
40*0Sstevel@tonic-gate chop(char *s)
41*0Sstevel@tonic-gate {
42*0Sstevel@tonic-gate 	char *t = s;
43*0Sstevel@tonic-gate 	while (*t) {
44*0Sstevel@tonic-gate 		if (*t == '\n' || *t == '\r') {
45*0Sstevel@tonic-gate 			*t = '\0';
46*0Sstevel@tonic-gate 			return s;
47*0Sstevel@tonic-gate 		}
48*0Sstevel@tonic-gate 		t++;
49*0Sstevel@tonic-gate 	}
50*0Sstevel@tonic-gate 	return s;
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate }
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate /* set/unset filedescriptor to non-blocking */
55*0Sstevel@tonic-gate void
56*0Sstevel@tonic-gate set_nonblock(int fd)
57*0Sstevel@tonic-gate {
58*0Sstevel@tonic-gate 	int val;
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate 	val = fcntl(fd, F_GETFL, 0);
61*0Sstevel@tonic-gate 	if (val < 0) {
62*0Sstevel@tonic-gate 		error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
63*0Sstevel@tonic-gate 		return;
64*0Sstevel@tonic-gate 	}
65*0Sstevel@tonic-gate 	if (val & O_NONBLOCK) {
66*0Sstevel@tonic-gate 		debug2("fd %d is O_NONBLOCK", fd);
67*0Sstevel@tonic-gate 		return;
68*0Sstevel@tonic-gate 	}
69*0Sstevel@tonic-gate 	debug("fd %d setting O_NONBLOCK", fd);
70*0Sstevel@tonic-gate 	val |= O_NONBLOCK;
71*0Sstevel@tonic-gate 	if (fcntl(fd, F_SETFL, val) == -1)
72*0Sstevel@tonic-gate 		debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
73*0Sstevel@tonic-gate 		    fd, strerror(errno));
74*0Sstevel@tonic-gate }
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate void
77*0Sstevel@tonic-gate unset_nonblock(int fd)
78*0Sstevel@tonic-gate {
79*0Sstevel@tonic-gate 	int val;
80*0Sstevel@tonic-gate 
81*0Sstevel@tonic-gate 	val = fcntl(fd, F_GETFL, 0);
82*0Sstevel@tonic-gate 	if (val < 0) {
83*0Sstevel@tonic-gate 		error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
84*0Sstevel@tonic-gate 		return;
85*0Sstevel@tonic-gate 	}
86*0Sstevel@tonic-gate 	if (!(val & O_NONBLOCK)) {
87*0Sstevel@tonic-gate 		debug2("fd %d is not O_NONBLOCK", fd);
88*0Sstevel@tonic-gate 		return;
89*0Sstevel@tonic-gate 	}
90*0Sstevel@tonic-gate 	debug("fd %d clearing O_NONBLOCK", fd);
91*0Sstevel@tonic-gate 	val &= ~O_NONBLOCK;
92*0Sstevel@tonic-gate 	if (fcntl(fd, F_SETFL, val) == -1)
93*0Sstevel@tonic-gate 		debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
94*0Sstevel@tonic-gate 		    fd, strerror(errno));
95*0Sstevel@tonic-gate }
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate /* disable nagle on socket */
98*0Sstevel@tonic-gate void
99*0Sstevel@tonic-gate set_nodelay(int fd)
100*0Sstevel@tonic-gate {
101*0Sstevel@tonic-gate 	int opt;
102*0Sstevel@tonic-gate 	socklen_t optlen;
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	optlen = sizeof opt;
105*0Sstevel@tonic-gate 	if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
106*0Sstevel@tonic-gate 		error("getsockopt TCP_NODELAY: %.100s", strerror(errno));
107*0Sstevel@tonic-gate 		return;
108*0Sstevel@tonic-gate 	}
109*0Sstevel@tonic-gate 	if (opt == 1) {
110*0Sstevel@tonic-gate 		debug2("fd %d is TCP_NODELAY", fd);
111*0Sstevel@tonic-gate 		return;
112*0Sstevel@tonic-gate 	}
113*0Sstevel@tonic-gate 	opt = 1;
114*0Sstevel@tonic-gate 	debug("fd %d setting TCP_NODELAY", fd);
115*0Sstevel@tonic-gate 	if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
116*0Sstevel@tonic-gate 		error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
117*0Sstevel@tonic-gate }
118*0Sstevel@tonic-gate 
119*0Sstevel@tonic-gate /* Characters considered whitespace in strsep calls. */
120*0Sstevel@tonic-gate #define WHITESPACE " \t\r\n"
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate /* return next token in configuration line */
123*0Sstevel@tonic-gate char *
124*0Sstevel@tonic-gate strdelim(char **s)
125*0Sstevel@tonic-gate {
126*0Sstevel@tonic-gate 	char *old;
127*0Sstevel@tonic-gate 	int wspace = 0;
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 	if (*s == NULL)
130*0Sstevel@tonic-gate 		return NULL;
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 	old = *s;
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 	*s = strpbrk(*s, WHITESPACE "=");
135*0Sstevel@tonic-gate 	if (*s == NULL)
136*0Sstevel@tonic-gate 		return (old);
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate 	/* Allow only one '=' to be skipped */
139*0Sstevel@tonic-gate 	if (*s[0] == '=')
140*0Sstevel@tonic-gate 		wspace = 1;
141*0Sstevel@tonic-gate 	*s[0] = '\0';
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate 	*s += strspn(*s + 1, WHITESPACE) + 1;
144*0Sstevel@tonic-gate 	if (*s[0] == '=' && !wspace)
145*0Sstevel@tonic-gate 		*s += strspn(*s + 1, WHITESPACE) + 1;
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate 	return (old);
148*0Sstevel@tonic-gate }
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate struct passwd *
151*0Sstevel@tonic-gate pwcopy(struct passwd *pw)
152*0Sstevel@tonic-gate {
153*0Sstevel@tonic-gate 	struct passwd *copy = xmalloc(sizeof(*copy));
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 	memset(copy, 0, sizeof(*copy));
156*0Sstevel@tonic-gate 	copy->pw_name = xstrdup(pw->pw_name);
157*0Sstevel@tonic-gate 	copy->pw_passwd = xstrdup(pw->pw_passwd);
158*0Sstevel@tonic-gate 	copy->pw_gecos = xstrdup(pw->pw_gecos);
159*0Sstevel@tonic-gate 	copy->pw_uid = pw->pw_uid;
160*0Sstevel@tonic-gate 	copy->pw_gid = pw->pw_gid;
161*0Sstevel@tonic-gate #ifdef HAVE_PW_EXPIRE_IN_PASSWD
162*0Sstevel@tonic-gate 	copy->pw_expire = pw->pw_expire;
163*0Sstevel@tonic-gate #endif
164*0Sstevel@tonic-gate #ifdef HAVE_PW_CHANGE_IN_PASSWD
165*0Sstevel@tonic-gate 	copy->pw_change = pw->pw_change;
166*0Sstevel@tonic-gate #endif
167*0Sstevel@tonic-gate #ifdef HAVE_PW_CLASS_IN_PASSWD
168*0Sstevel@tonic-gate 	copy->pw_class = xstrdup(pw->pw_class);
169*0Sstevel@tonic-gate #endif
170*0Sstevel@tonic-gate 	copy->pw_dir = xstrdup(pw->pw_dir);
171*0Sstevel@tonic-gate 	copy->pw_shell = xstrdup(pw->pw_shell);
172*0Sstevel@tonic-gate 	return copy;
173*0Sstevel@tonic-gate }
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate void
176*0Sstevel@tonic-gate pwfree(struct passwd **pw)
177*0Sstevel@tonic-gate {
178*0Sstevel@tonic-gate 	struct passwd *p;
179*0Sstevel@tonic-gate 
180*0Sstevel@tonic-gate 	if (pw == NULL || *pw == NULL)
181*0Sstevel@tonic-gate 		return;
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	p = *pw;
184*0Sstevel@tonic-gate 	*pw = NULL;
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	xfree(p->pw_name);
187*0Sstevel@tonic-gate 	xfree(p->pw_passwd);
188*0Sstevel@tonic-gate 	xfree(p->pw_gecos);
189*0Sstevel@tonic-gate #ifdef HAVE_PW_CLASS_IN_PASSWD
190*0Sstevel@tonic-gate 	xfree(p->pw_class);
191*0Sstevel@tonic-gate #endif
192*0Sstevel@tonic-gate 	xfree(p->pw_dir);
193*0Sstevel@tonic-gate 	xfree(p->pw_shell);
194*0Sstevel@tonic-gate 	xfree(p);
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate /*
198*0Sstevel@tonic-gate  * Convert ASCII string to TCP/IP port number.
199*0Sstevel@tonic-gate  * Port must be >0 and <=65535.
200*0Sstevel@tonic-gate  * Return 0 if invalid.
201*0Sstevel@tonic-gate  */
202*0Sstevel@tonic-gate int
203*0Sstevel@tonic-gate a2port(const char *s)
204*0Sstevel@tonic-gate {
205*0Sstevel@tonic-gate 	long port;
206*0Sstevel@tonic-gate 	char *endp;
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	errno = 0;
209*0Sstevel@tonic-gate 	port = strtol(s, &endp, 0);
210*0Sstevel@tonic-gate 	if (s == endp || *endp != '\0' ||
211*0Sstevel@tonic-gate 	    (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) ||
212*0Sstevel@tonic-gate 	    port <= 0 || port > 65535)
213*0Sstevel@tonic-gate 		return 0;
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate 	return port;
216*0Sstevel@tonic-gate }
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate #define SECONDS		1
219*0Sstevel@tonic-gate #define MINUTES		(SECONDS * 60)
220*0Sstevel@tonic-gate #define HOURS		(MINUTES * 60)
221*0Sstevel@tonic-gate #define DAYS		(HOURS * 24)
222*0Sstevel@tonic-gate #define WEEKS		(DAYS * 7)
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate /*
225*0Sstevel@tonic-gate  * Convert a time string into seconds; format is
226*0Sstevel@tonic-gate  * a sequence of:
227*0Sstevel@tonic-gate  *      time[qualifier]
228*0Sstevel@tonic-gate  *
229*0Sstevel@tonic-gate  * Valid time qualifiers are:
230*0Sstevel@tonic-gate  *      <none>  seconds
231*0Sstevel@tonic-gate  *      s|S     seconds
232*0Sstevel@tonic-gate  *      m|M     minutes
233*0Sstevel@tonic-gate  *      h|H     hours
234*0Sstevel@tonic-gate  *      d|D     days
235*0Sstevel@tonic-gate  *      w|W     weeks
236*0Sstevel@tonic-gate  *
237*0Sstevel@tonic-gate  * Examples:
238*0Sstevel@tonic-gate  *      90m     90 minutes
239*0Sstevel@tonic-gate  *      1h30m   90 minutes
240*0Sstevel@tonic-gate  *      2d      2 days
241*0Sstevel@tonic-gate  *      1w      1 week
242*0Sstevel@tonic-gate  *
243*0Sstevel@tonic-gate  * Return -1 if time string is invalid.
244*0Sstevel@tonic-gate  */
245*0Sstevel@tonic-gate long
246*0Sstevel@tonic-gate convtime(const char *s)
247*0Sstevel@tonic-gate {
248*0Sstevel@tonic-gate 	long total, secs;
249*0Sstevel@tonic-gate 	const char *p;
250*0Sstevel@tonic-gate 	char *endp;
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	errno = 0;
253*0Sstevel@tonic-gate 	total = 0;
254*0Sstevel@tonic-gate 	p = s;
255*0Sstevel@tonic-gate 
256*0Sstevel@tonic-gate 	if (p == NULL || *p == '\0')
257*0Sstevel@tonic-gate 		return -1;
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate 	while (*p) {
260*0Sstevel@tonic-gate 		secs = strtol(p, &endp, 10);
261*0Sstevel@tonic-gate 		if (p == endp ||
262*0Sstevel@tonic-gate 		    (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
263*0Sstevel@tonic-gate 		    secs < 0)
264*0Sstevel@tonic-gate 			return -1;
265*0Sstevel@tonic-gate 
266*0Sstevel@tonic-gate 		switch (*endp++) {
267*0Sstevel@tonic-gate 		case '\0':
268*0Sstevel@tonic-gate 			endp--;
269*0Sstevel@tonic-gate 			break;
270*0Sstevel@tonic-gate 		case 's':
271*0Sstevel@tonic-gate 		case 'S':
272*0Sstevel@tonic-gate 			break;
273*0Sstevel@tonic-gate 		case 'm':
274*0Sstevel@tonic-gate 		case 'M':
275*0Sstevel@tonic-gate 			secs *= MINUTES;
276*0Sstevel@tonic-gate 			break;
277*0Sstevel@tonic-gate 		case 'h':
278*0Sstevel@tonic-gate 		case 'H':
279*0Sstevel@tonic-gate 			secs *= HOURS;
280*0Sstevel@tonic-gate 			break;
281*0Sstevel@tonic-gate 		case 'd':
282*0Sstevel@tonic-gate 		case 'D':
283*0Sstevel@tonic-gate 			secs *= DAYS;
284*0Sstevel@tonic-gate 			break;
285*0Sstevel@tonic-gate 		case 'w':
286*0Sstevel@tonic-gate 		case 'W':
287*0Sstevel@tonic-gate 			secs *= WEEKS;
288*0Sstevel@tonic-gate 			break;
289*0Sstevel@tonic-gate 		default:
290*0Sstevel@tonic-gate 			return -1;
291*0Sstevel@tonic-gate 		}
292*0Sstevel@tonic-gate 		total += secs;
293*0Sstevel@tonic-gate 		if (total < 0)
294*0Sstevel@tonic-gate 			return -1;
295*0Sstevel@tonic-gate 		p = endp;
296*0Sstevel@tonic-gate 	}
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 	return total;
299*0Sstevel@tonic-gate }
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate char *
302*0Sstevel@tonic-gate cleanhostname(char *host)
303*0Sstevel@tonic-gate {
304*0Sstevel@tonic-gate 	if (*host == '[' && host[strlen(host) - 1] == ']') {
305*0Sstevel@tonic-gate 		host[strlen(host) - 1] = '\0';
306*0Sstevel@tonic-gate 		return (host + 1);
307*0Sstevel@tonic-gate 	} else
308*0Sstevel@tonic-gate 		return host;
309*0Sstevel@tonic-gate }
310*0Sstevel@tonic-gate 
311*0Sstevel@tonic-gate char *
312*0Sstevel@tonic-gate colon(char *cp)
313*0Sstevel@tonic-gate {
314*0Sstevel@tonic-gate 	int flag = 0;
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate 	if (*cp == ':')		/* Leading colon is part of file name. */
317*0Sstevel@tonic-gate 		return (0);
318*0Sstevel@tonic-gate 	if (*cp == '[')
319*0Sstevel@tonic-gate 		flag = 1;
320*0Sstevel@tonic-gate 
321*0Sstevel@tonic-gate 	for (; *cp; ++cp) {
322*0Sstevel@tonic-gate 		if (*cp == '@' && *(cp+1) == '[')
323*0Sstevel@tonic-gate 			flag = 1;
324*0Sstevel@tonic-gate 		if (*cp == ']' && *(cp+1) == ':' && flag)
325*0Sstevel@tonic-gate 			return (cp+1);
326*0Sstevel@tonic-gate 		if (*cp == ':' && !flag)
327*0Sstevel@tonic-gate 			return (cp);
328*0Sstevel@tonic-gate 		if (*cp == '/')
329*0Sstevel@tonic-gate 			return (0);
330*0Sstevel@tonic-gate 	}
331*0Sstevel@tonic-gate 	return (0);
332*0Sstevel@tonic-gate }
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate /* function to assist building execv() arguments */
335*0Sstevel@tonic-gate /* PRINTFLIKE2 */
336*0Sstevel@tonic-gate void
337*0Sstevel@tonic-gate addargs(arglist *args, char *fmt, ...)
338*0Sstevel@tonic-gate {
339*0Sstevel@tonic-gate 	va_list ap;
340*0Sstevel@tonic-gate 	char buf[1024];
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 	va_start(ap, fmt);
343*0Sstevel@tonic-gate 	vsnprintf(buf, sizeof(buf), fmt, ap);
344*0Sstevel@tonic-gate 	va_end(ap);
345*0Sstevel@tonic-gate 
346*0Sstevel@tonic-gate 	if (args->list == NULL) {
347*0Sstevel@tonic-gate 		args->nalloc = 32;
348*0Sstevel@tonic-gate 		args->num = 0;
349*0Sstevel@tonic-gate 	} else if (args->num+2 >= args->nalloc)
350*0Sstevel@tonic-gate 		args->nalloc *= 2;
351*0Sstevel@tonic-gate 
352*0Sstevel@tonic-gate 	args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
353*0Sstevel@tonic-gate 	args->list[args->num++] = xstrdup(buf);
354*0Sstevel@tonic-gate 	args->list[args->num] = NULL;
355*0Sstevel@tonic-gate }
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate mysig_t
358*0Sstevel@tonic-gate mysignal(int sig, mysig_t act)
359*0Sstevel@tonic-gate {
360*0Sstevel@tonic-gate #ifdef HAVE_SIGACTION
361*0Sstevel@tonic-gate 	struct sigaction sa, osa;
362*0Sstevel@tonic-gate 
363*0Sstevel@tonic-gate 	if (sigaction(sig, NULL, &osa) == -1)
364*0Sstevel@tonic-gate 		return (mysig_t) -1;
365*0Sstevel@tonic-gate 	if (osa.sa_handler != act) {
366*0Sstevel@tonic-gate 		memset(&sa, 0, sizeof(sa));
367*0Sstevel@tonic-gate 		sigemptyset(&sa.sa_mask);
368*0Sstevel@tonic-gate 		sa.sa_flags = 0;
369*0Sstevel@tonic-gate #if defined(SA_INTERRUPT)
370*0Sstevel@tonic-gate 		if (sig == SIGALRM)
371*0Sstevel@tonic-gate 			sa.sa_flags |= SA_INTERRUPT;
372*0Sstevel@tonic-gate #endif
373*0Sstevel@tonic-gate 		sa.sa_handler = act;
374*0Sstevel@tonic-gate 		if (sigaction(sig, &sa, NULL) == -1)
375*0Sstevel@tonic-gate 			return (mysig_t) -1;
376*0Sstevel@tonic-gate 	}
377*0Sstevel@tonic-gate 	return (osa.sa_handler);
378*0Sstevel@tonic-gate #else
379*0Sstevel@tonic-gate 	return (signal(sig, act));
380*0Sstevel@tonic-gate #endif
381*0Sstevel@tonic-gate }
382