xref: /minix3/external/bsd/nvi/dist/ex/ex_shell.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: ex_shell.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
284d9c625SLionel Sambuc /*-
384d9c625SLionel Sambuc  * Copyright (c) 1992, 1993, 1994
484d9c625SLionel Sambuc  *	The Regents of the University of California.  All rights reserved.
584d9c625SLionel Sambuc  * Copyright (c) 1992, 1993, 1994, 1995, 1996
684d9c625SLionel Sambuc  *	Keith Bostic.  All rights reserved.
784d9c625SLionel Sambuc  *
884d9c625SLionel Sambuc  * See the LICENSE file for redistribution information.
984d9c625SLionel Sambuc  */
1084d9c625SLionel Sambuc 
1184d9c625SLionel Sambuc #include "config.h"
1284d9c625SLionel Sambuc 
13*0a6a1f1dSLionel Sambuc #include <sys/cdefs.h>
14*0a6a1f1dSLionel Sambuc #if 0
1584d9c625SLionel Sambuc #ifndef lint
1684d9c625SLionel Sambuc static const char sccsid[] = "Id: ex_shell.c,v 10.42 2003/11/05 17:11:54 skimo Exp  (Berkeley) Date: 2003/11/05 17:11:54 ";
1784d9c625SLionel Sambuc #endif /* not lint */
18*0a6a1f1dSLionel Sambuc #else
19*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: ex_shell.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
20*0a6a1f1dSLionel Sambuc #endif
2184d9c625SLionel Sambuc 
2284d9c625SLionel Sambuc #include <sys/param.h>
2384d9c625SLionel Sambuc #include <sys/queue.h>
2484d9c625SLionel Sambuc #include <sys/wait.h>
2584d9c625SLionel Sambuc 
2684d9c625SLionel Sambuc #include <bitstring.h>
2784d9c625SLionel Sambuc #include <ctype.h>
2884d9c625SLionel Sambuc #include <errno.h>
2984d9c625SLionel Sambuc #include <limits.h>
3084d9c625SLionel Sambuc #include <signal.h>
3184d9c625SLionel Sambuc #include <stdio.h>
3284d9c625SLionel Sambuc #include <stdlib.h>
3384d9c625SLionel Sambuc #include <string.h>
3484d9c625SLionel Sambuc #include <unistd.h>
3584d9c625SLionel Sambuc 
3684d9c625SLionel Sambuc #include "../common/common.h"
3784d9c625SLionel Sambuc 
3884d9c625SLionel Sambuc static const char *sigmsg __P((int));
3984d9c625SLionel Sambuc 
4084d9c625SLionel Sambuc /*
4184d9c625SLionel Sambuc  * ex_shell -- :sh[ell]
4284d9c625SLionel Sambuc  *	Invoke the program named in the SHELL environment variable
4384d9c625SLionel Sambuc  *	with the argument -i.
4484d9c625SLionel Sambuc  *
4584d9c625SLionel Sambuc  * PUBLIC: int ex_shell __P((SCR *, EXCMD *));
4684d9c625SLionel Sambuc  */
4784d9c625SLionel Sambuc int
ex_shell(SCR * sp,EXCMD * cmdp)4884d9c625SLionel Sambuc ex_shell(SCR *sp, EXCMD *cmdp)
4984d9c625SLionel Sambuc {
5084d9c625SLionel Sambuc 	int rval;
5184d9c625SLionel Sambuc 	char buf[MAXPATHLEN];
5284d9c625SLionel Sambuc 
5384d9c625SLionel Sambuc 	/* We'll need a shell. */
5484d9c625SLionel Sambuc 	if (opts_empty(sp, O_SHELL, 0))
5584d9c625SLionel Sambuc 		return (1);
5684d9c625SLionel Sambuc 
5784d9c625SLionel Sambuc 	/*
5884d9c625SLionel Sambuc 	 * XXX
5984d9c625SLionel Sambuc 	 * Assumes all shells use -i.
6084d9c625SLionel Sambuc 	 */
6184d9c625SLionel Sambuc 	(void)snprintf(buf, sizeof(buf), "%s -i", O_STR(sp, O_SHELL));
6284d9c625SLionel Sambuc 
6384d9c625SLionel Sambuc 	/* Restore the window name. */
6484d9c625SLionel Sambuc 	(void)sp->gp->scr_rename(sp, NULL, 0);
6584d9c625SLionel Sambuc 
6684d9c625SLionel Sambuc 	/* If we're still in a vi screen, move out explicitly. */
6784d9c625SLionel Sambuc 	rval = ex_exec_proc(sp, cmdp, buf, NULL, !F_ISSET(sp, SC_SCR_EXWROTE));
6884d9c625SLionel Sambuc 
6984d9c625SLionel Sambuc 	/* Set the window name. */
7084d9c625SLionel Sambuc 	(void)sp->gp->scr_rename(sp, sp->frp->name, 1);
7184d9c625SLionel Sambuc 
7284d9c625SLionel Sambuc 	/*
7384d9c625SLionel Sambuc 	 * !!!
7484d9c625SLionel Sambuc 	 * Historically, vi didn't require a continue message after the
7584d9c625SLionel Sambuc 	 * return of the shell.  Match it.
7684d9c625SLionel Sambuc 	 */
7784d9c625SLionel Sambuc 	F_SET(sp, SC_EX_WAIT_NO);
7884d9c625SLionel Sambuc 
7984d9c625SLionel Sambuc 	return (rval);
8084d9c625SLionel Sambuc }
8184d9c625SLionel Sambuc 
8284d9c625SLionel Sambuc /*
8384d9c625SLionel Sambuc  * ex_exec_proc --
8484d9c625SLionel Sambuc  *	Run a separate process.
8584d9c625SLionel Sambuc  *
8684d9c625SLionel Sambuc  * PUBLIC: int ex_exec_proc __P((SCR *, EXCMD *, const char *, const char *, int));
8784d9c625SLionel Sambuc  */
8884d9c625SLionel Sambuc int
ex_exec_proc(SCR * sp,EXCMD * cmdp,const char * cmd,const char * msg,int need_newline)8984d9c625SLionel Sambuc ex_exec_proc(SCR *sp, EXCMD *cmdp, const char *cmd, const char *msg, int need_newline)
9084d9c625SLionel Sambuc {
9184d9c625SLionel Sambuc 	GS *gp;
9284d9c625SLionel Sambuc 	const char *name;
9384d9c625SLionel Sambuc 	pid_t pid;
9484d9c625SLionel Sambuc 
9584d9c625SLionel Sambuc 	gp = sp->gp;
9684d9c625SLionel Sambuc 
9784d9c625SLionel Sambuc 	/* We'll need a shell. */
9884d9c625SLionel Sambuc 	if (opts_empty(sp, O_SHELL, 0))
9984d9c625SLionel Sambuc 		return (1);
10084d9c625SLionel Sambuc 
10184d9c625SLionel Sambuc 	/* Enter ex mode. */
10284d9c625SLionel Sambuc 	if (F_ISSET(sp, SC_VI)) {
10384d9c625SLionel Sambuc 		if (gp->scr_screen(sp, SC_EX)) {
10484d9c625SLionel Sambuc 			ex_wemsg(sp, cmdp->cmd->name, EXM_NOCANON);
10584d9c625SLionel Sambuc 			return (1);
10684d9c625SLionel Sambuc 		}
10784d9c625SLionel Sambuc 		(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
10884d9c625SLionel Sambuc 		F_SET(sp, SC_SCR_EX | SC_SCR_EXWROTE);
10984d9c625SLionel Sambuc 	}
11084d9c625SLionel Sambuc 
11184d9c625SLionel Sambuc 	/* Put out additional newline, message. */
11284d9c625SLionel Sambuc 	if (need_newline)
11384d9c625SLionel Sambuc 		(void)ex_puts(sp, "\n");
11484d9c625SLionel Sambuc 	if (msg != NULL) {
11584d9c625SLionel Sambuc 		(void)ex_puts(sp, msg);
11684d9c625SLionel Sambuc 		(void)ex_puts(sp, "\n");
11784d9c625SLionel Sambuc 	}
11884d9c625SLionel Sambuc 	(void)ex_fflush(sp);
11984d9c625SLionel Sambuc 
12084d9c625SLionel Sambuc 	switch (pid = vfork()) {
12184d9c625SLionel Sambuc 	case -1:			/* Error. */
12284d9c625SLionel Sambuc 		msgq(sp, M_SYSERR, "vfork");
12384d9c625SLionel Sambuc 		return (1);
12484d9c625SLionel Sambuc 	case 0:				/* Utility. */
12584d9c625SLionel Sambuc 		if (gp->scr_child)
12684d9c625SLionel Sambuc 			gp->scr_child(sp);
12784d9c625SLionel Sambuc 		if ((name = strrchr(O_STR(sp, O_SHELL), '/')) == NULL)
12884d9c625SLionel Sambuc 			name = O_STR(sp, O_SHELL);
12984d9c625SLionel Sambuc 		else
13084d9c625SLionel Sambuc 			++name;
13184d9c625SLionel Sambuc 		execl(O_STR(sp, O_SHELL), name, "-c", cmd, (char *)NULL);
13284d9c625SLionel Sambuc 		msgq_str(sp, M_SYSERR, O_STR(sp, O_SHELL), "execl: %s");
13384d9c625SLionel Sambuc 		_exit(127);
13484d9c625SLionel Sambuc 		/* NOTREACHED */
13584d9c625SLionel Sambuc 	default:			/* Parent. */
13684d9c625SLionel Sambuc 		return (proc_wait(sp, (long)pid, cmd, 0, 0));
13784d9c625SLionel Sambuc 	}
13884d9c625SLionel Sambuc 	/* NOTREACHED */
13984d9c625SLionel Sambuc }
14084d9c625SLionel Sambuc 
14184d9c625SLionel Sambuc /*
14284d9c625SLionel Sambuc  * proc_wait --
14384d9c625SLionel Sambuc  *	Wait for one of the processes.
14484d9c625SLionel Sambuc  *
14584d9c625SLionel Sambuc  * !!!
14684d9c625SLionel Sambuc  * The pid_t type varies in size from a short to a long depending on the
14784d9c625SLionel Sambuc  * system.  It has to be cast into something or the standard promotion
14884d9c625SLionel Sambuc  * rules get you.  I'm using a long based on the belief that nobody is
14984d9c625SLionel Sambuc  * going to make it unsigned and it's unlikely to be a quad.
15084d9c625SLionel Sambuc  *
15184d9c625SLionel Sambuc  * PUBLIC: int proc_wait __P((SCR *, long, const char *, int, int));
15284d9c625SLionel Sambuc  */
15384d9c625SLionel Sambuc int
proc_wait(SCR * sp,long int pid,const char * cmd,int silent,int okpipe)15484d9c625SLionel Sambuc proc_wait(SCR *sp, long int pid, const char *cmd, int silent, int okpipe)
15584d9c625SLionel Sambuc {
15684d9c625SLionel Sambuc 	size_t len;
15784d9c625SLionel Sambuc 	int nf, pstat;
15884d9c625SLionel Sambuc 	char *p;
15984d9c625SLionel Sambuc 
16084d9c625SLionel Sambuc 	/* Wait for the utility, ignoring interruptions. */
16184d9c625SLionel Sambuc 	for (;;) {
16284d9c625SLionel Sambuc 		errno = 0;
16384d9c625SLionel Sambuc 		if (waitpid((pid_t)pid, &pstat, 0) != -1)
16484d9c625SLionel Sambuc 			break;
16584d9c625SLionel Sambuc 		if (errno != EINTR) {
16684d9c625SLionel Sambuc 			msgq(sp, M_SYSERR, "waitpid");
16784d9c625SLionel Sambuc 			return (1);
16884d9c625SLionel Sambuc 		}
16984d9c625SLionel Sambuc 	}
17084d9c625SLionel Sambuc 
17184d9c625SLionel Sambuc 	/*
17284d9c625SLionel Sambuc 	 * Display the utility's exit status.  Ignore SIGPIPE from the
17384d9c625SLionel Sambuc 	 * parent-writer, as that only means that the utility chose to
17484d9c625SLionel Sambuc 	 * exit before reading all of its input.
17584d9c625SLionel Sambuc 	 */
17684d9c625SLionel Sambuc 	if (WIFSIGNALED(pstat) && (!okpipe || WTERMSIG(pstat) != SIGPIPE)) {
17784d9c625SLionel Sambuc 		for (; isblank((unsigned char)*cmd); ++cmd);
17884d9c625SLionel Sambuc 		p = msg_print(sp, cmd, &nf);
17984d9c625SLionel Sambuc 		len = strlen(p);
18084d9c625SLionel Sambuc 		msgq(sp, M_ERR, "%.*s%s: received signal: %s%s",
18184d9c625SLionel Sambuc 		    (int)MIN(len, 20), p, len > 20 ? " ..." : "",
18284d9c625SLionel Sambuc 		    sigmsg(WTERMSIG(pstat)),
18384d9c625SLionel Sambuc 		    WCOREDUMP(pstat) ? "; core dumped" : "");
18484d9c625SLionel Sambuc 		if (nf)
18584d9c625SLionel Sambuc 			FREE_SPACE(sp, p, 0);
18684d9c625SLionel Sambuc 		return (1);
18784d9c625SLionel Sambuc 	}
18884d9c625SLionel Sambuc 
18984d9c625SLionel Sambuc 	if (WIFEXITED(pstat) && WEXITSTATUS(pstat)) {
19084d9c625SLionel Sambuc 		/*
19184d9c625SLionel Sambuc 		 * Remain silent for "normal" errors when doing shell file
19284d9c625SLionel Sambuc 		 * name expansions, they almost certainly indicate nothing
19384d9c625SLionel Sambuc 		 * more than a failure to match.
19484d9c625SLionel Sambuc 		 *
19584d9c625SLionel Sambuc 		 * Remain silent for vi read filter errors.  It's historic
19684d9c625SLionel Sambuc 		 * practice.
19784d9c625SLionel Sambuc 		 */
19884d9c625SLionel Sambuc 		if (!silent) {
19984d9c625SLionel Sambuc 			for (; isblank((unsigned char)*cmd); ++cmd);
20084d9c625SLionel Sambuc 			p = msg_print(sp, cmd, &nf);
20184d9c625SLionel Sambuc 			len = strlen(p);
20284d9c625SLionel Sambuc 			msgq(sp, M_ERR, "%.*s%s: exited with status %d",
20384d9c625SLionel Sambuc 			    (int)MIN(len, 20), p, len > 20 ? " ..." : "",
20484d9c625SLionel Sambuc 			    WEXITSTATUS(pstat));
20584d9c625SLionel Sambuc 			if (nf)
20684d9c625SLionel Sambuc 				FREE_SPACE(sp, p, 0);
20784d9c625SLionel Sambuc 		}
20884d9c625SLionel Sambuc 		return (1);
20984d9c625SLionel Sambuc 	}
21084d9c625SLionel Sambuc 	return (0);
21184d9c625SLionel Sambuc }
21284d9c625SLionel Sambuc 
21384d9c625SLionel Sambuc /*
21484d9c625SLionel Sambuc  * XXX
21584d9c625SLionel Sambuc  * The sys_siglist[] table in the C library has this information, but there's
21684d9c625SLionel Sambuc  * no portable way to get to it.  (Believe me, I tried.)
21784d9c625SLionel Sambuc  */
21884d9c625SLionel Sambuc typedef struct _sigs {
21984d9c625SLionel Sambuc 	int	 number;		/* signal number */
22084d9c625SLionel Sambuc 	const char *message;		/* related message */
22184d9c625SLionel Sambuc } SIGS;
22284d9c625SLionel Sambuc 
22384d9c625SLionel Sambuc SIGS const sigs[] = {
22484d9c625SLionel Sambuc #ifdef SIGABRT
22584d9c625SLionel Sambuc 	{ SIGABRT,	"Abort trap" },
22684d9c625SLionel Sambuc #endif
22784d9c625SLionel Sambuc #ifdef SIGALRM
22884d9c625SLionel Sambuc 	{ SIGALRM,	"Alarm clock" },
22984d9c625SLionel Sambuc #endif
23084d9c625SLionel Sambuc #ifdef SIGBUS
23184d9c625SLionel Sambuc 	{ SIGBUS,		"Bus error" },
23284d9c625SLionel Sambuc #endif
23384d9c625SLionel Sambuc #ifdef SIGCLD
23484d9c625SLionel Sambuc 	{ SIGCLD,		"Child exited or stopped" },
23584d9c625SLionel Sambuc #endif
23684d9c625SLionel Sambuc #ifdef SIGCHLD
23784d9c625SLionel Sambuc 	{ SIGCHLD,	"Child exited" },
23884d9c625SLionel Sambuc #endif
23984d9c625SLionel Sambuc #ifdef SIGCONT
24084d9c625SLionel Sambuc 	{ SIGCONT,	"Continued" },
24184d9c625SLionel Sambuc #endif
24284d9c625SLionel Sambuc #ifdef SIGDANGER
24384d9c625SLionel Sambuc 	{ SIGDANGER,	"System crash imminent" },
24484d9c625SLionel Sambuc #endif
24584d9c625SLionel Sambuc #ifdef SIGEMT
24684d9c625SLionel Sambuc 	{ SIGEMT,		"EMT trap" },
24784d9c625SLionel Sambuc #endif
24884d9c625SLionel Sambuc #ifdef SIGFPE
24984d9c625SLionel Sambuc 	{ SIGFPE,		"Floating point exception" },
25084d9c625SLionel Sambuc #endif
25184d9c625SLionel Sambuc #ifdef SIGGRANT
25284d9c625SLionel Sambuc 	{ SIGGRANT,	"HFT monitor mode granted" },
25384d9c625SLionel Sambuc #endif
25484d9c625SLionel Sambuc #ifdef SIGHUP
25584d9c625SLionel Sambuc 	{ SIGHUP,		"Hangup" },
25684d9c625SLionel Sambuc #endif
25784d9c625SLionel Sambuc #ifdef SIGILL
25884d9c625SLionel Sambuc 	{ SIGILL,		"Illegal instruction" },
25984d9c625SLionel Sambuc #endif
26084d9c625SLionel Sambuc #ifdef SIGINFO
26184d9c625SLionel Sambuc 	{ SIGINFO,	"Information request" },
26284d9c625SLionel Sambuc #endif
26384d9c625SLionel Sambuc #ifdef SIGINT
26484d9c625SLionel Sambuc 	{ SIGINT,		"Interrupt" },
26584d9c625SLionel Sambuc #endif
26684d9c625SLionel Sambuc #ifdef SIGIO
26784d9c625SLionel Sambuc 	{ SIGIO,		"I/O possible" },
26884d9c625SLionel Sambuc #endif
26984d9c625SLionel Sambuc #ifdef SIGIOT
27084d9c625SLionel Sambuc 	{ SIGIOT,		"IOT trap" },
27184d9c625SLionel Sambuc #endif
27284d9c625SLionel Sambuc #ifdef SIGKILL
27384d9c625SLionel Sambuc 	{ SIGKILL,	"Killed" },
27484d9c625SLionel Sambuc #endif
27584d9c625SLionel Sambuc #ifdef SIGLOST
27684d9c625SLionel Sambuc 	{ SIGLOST,	"Record lock" },
27784d9c625SLionel Sambuc #endif
27884d9c625SLionel Sambuc #ifdef SIGMIGRATE
27984d9c625SLionel Sambuc 	{ SIGMIGRATE,	"Migrate process to another CPU" },
28084d9c625SLionel Sambuc #endif
28184d9c625SLionel Sambuc #ifdef SIGMSG
28284d9c625SLionel Sambuc 	{ SIGMSG,		"HFT input data pending" },
28384d9c625SLionel Sambuc #endif
28484d9c625SLionel Sambuc #ifdef SIGPIPE
28584d9c625SLionel Sambuc 	{ SIGPIPE,	"Broken pipe" },
28684d9c625SLionel Sambuc #endif
28784d9c625SLionel Sambuc #ifdef SIGPOLL
28884d9c625SLionel Sambuc 	{ SIGPOLL,	"I/O possible" },
28984d9c625SLionel Sambuc #endif
29084d9c625SLionel Sambuc #ifdef SIGPRE
29184d9c625SLionel Sambuc 	{ SIGPRE,		"Programming error" },
29284d9c625SLionel Sambuc #endif
29384d9c625SLionel Sambuc #ifdef SIGPROF
29484d9c625SLionel Sambuc 	{ SIGPROF,	"Profiling timer expired" },
29584d9c625SLionel Sambuc #endif
29684d9c625SLionel Sambuc #ifdef SIGPWR
29784d9c625SLionel Sambuc 	{ SIGPWR,		"Power failure imminent" },
29884d9c625SLionel Sambuc #endif
29984d9c625SLionel Sambuc #ifdef SIGRETRACT
30084d9c625SLionel Sambuc 	{ SIGRETRACT,	"HFT monitor mode retracted" },
30184d9c625SLionel Sambuc #endif
30284d9c625SLionel Sambuc #ifdef SIGQUIT
30384d9c625SLionel Sambuc 	{ SIGQUIT,	"Quit" },
30484d9c625SLionel Sambuc #endif
30584d9c625SLionel Sambuc #ifdef SIGSAK
30684d9c625SLionel Sambuc 	{ SIGSAK,		"Secure Attention Key" },
30784d9c625SLionel Sambuc #endif
30884d9c625SLionel Sambuc #ifdef SIGSEGV
30984d9c625SLionel Sambuc 	{ SIGSEGV,	"Segmentation fault" },
31084d9c625SLionel Sambuc #endif
31184d9c625SLionel Sambuc #ifdef SIGSOUND
31284d9c625SLionel Sambuc 	{ SIGSOUND,	"HFT sound sequence completed" },
31384d9c625SLionel Sambuc #endif
31484d9c625SLionel Sambuc #ifdef SIGSTOP
31584d9c625SLionel Sambuc 	{ SIGSTOP,	"Suspended (signal)" },
31684d9c625SLionel Sambuc #endif
31784d9c625SLionel Sambuc #ifdef SIGSYS
31884d9c625SLionel Sambuc 	{ SIGSYS,		"Bad system call" },
31984d9c625SLionel Sambuc #endif
32084d9c625SLionel Sambuc #ifdef SIGTERM
32184d9c625SLionel Sambuc 	{ SIGTERM,	"Terminated" },
32284d9c625SLionel Sambuc #endif
32384d9c625SLionel Sambuc #ifdef SIGTRAP
32484d9c625SLionel Sambuc 	{ SIGTRAP,	"Trace/BPT trap" },
32584d9c625SLionel Sambuc #endif
32684d9c625SLionel Sambuc #ifdef SIGTSTP
32784d9c625SLionel Sambuc 	{ SIGTSTP,	"Suspended" },
32884d9c625SLionel Sambuc #endif
32984d9c625SLionel Sambuc #ifdef SIGTTIN
33084d9c625SLionel Sambuc 	{ SIGTTIN,	"Stopped (tty input)" },
33184d9c625SLionel Sambuc #endif
33284d9c625SLionel Sambuc #ifdef SIGTTOU
33384d9c625SLionel Sambuc 	{ SIGTTOU,	"Stopped (tty output)" },
33484d9c625SLionel Sambuc #endif
33584d9c625SLionel Sambuc #ifdef SIGURG
33684d9c625SLionel Sambuc 	{ SIGURG,		"Urgent I/O condition" },
33784d9c625SLionel Sambuc #endif
33884d9c625SLionel Sambuc #ifdef SIGUSR1
33984d9c625SLionel Sambuc 	{ SIGUSR1,	"User defined signal 1" },
34084d9c625SLionel Sambuc #endif
34184d9c625SLionel Sambuc #ifdef SIGUSR2
34284d9c625SLionel Sambuc 	{ SIGUSR2,	"User defined signal 2" },
34384d9c625SLionel Sambuc #endif
34484d9c625SLionel Sambuc #ifdef SIGVTALRM
34584d9c625SLionel Sambuc 	{ SIGVTALRM,	"Virtual timer expired" },
34684d9c625SLionel Sambuc #endif
34784d9c625SLionel Sambuc #ifdef SIGWINCH
34884d9c625SLionel Sambuc 	{ SIGWINCH,	"Window size changes" },
34984d9c625SLionel Sambuc #endif
35084d9c625SLionel Sambuc #ifdef SIGXCPU
35184d9c625SLionel Sambuc 	{ SIGXCPU,	"Cputime limit exceeded" },
35284d9c625SLionel Sambuc #endif
35384d9c625SLionel Sambuc #ifdef SIGXFSZ
35484d9c625SLionel Sambuc 	{ SIGXFSZ,	"Filesize limit exceeded" },
35584d9c625SLionel Sambuc #endif
35684d9c625SLionel Sambuc };
35784d9c625SLionel Sambuc 
35884d9c625SLionel Sambuc /*
35984d9c625SLionel Sambuc  * sigmsg --
36084d9c625SLionel Sambuc  * 	Return a pointer to a message describing a signal.
36184d9c625SLionel Sambuc  */
36284d9c625SLionel Sambuc static const char *
sigmsg(int signo)36384d9c625SLionel Sambuc sigmsg(int signo)
36484d9c625SLionel Sambuc {
36584d9c625SLionel Sambuc 	static char buf[40];
36684d9c625SLionel Sambuc 	const SIGS *sigp;
36784d9c625SLionel Sambuc 	size_t n;
36884d9c625SLionel Sambuc 
36984d9c625SLionel Sambuc 	for (n = 0,
37084d9c625SLionel Sambuc 	    sigp = &sigs[0]; n < sizeof(sigs) / sizeof(sigs[0]); ++n, ++sigp)
37184d9c625SLionel Sambuc 		if (sigp->number == signo)
37284d9c625SLionel Sambuc 			return (sigp->message);
37384d9c625SLionel Sambuc 	(void)snprintf(buf, sizeof(buf), "Unknown signal: %d", signo);
37484d9c625SLionel Sambuc 	return (buf);
37584d9c625SLionel Sambuc }
376