head	1.14;
access;
symbols
	perseant-exfatfs-base-20250801:1.14
	perseant-exfatfs-base-20240630:1.14
	perseant-exfatfs:1.14.0.36
	perseant-exfatfs-base:1.14
	cjep_sun2x:1.14.0.34
	cjep_sun2x-base:1.14
	cjep_staticlib_x-base1:1.14
	cjep_staticlib_x:1.14.0.32
	cjep_staticlib_x-base:1.14
	phil-wifi-20200421:1.14
	phil-wifi-20200411:1.14
	phil-wifi-20200406:1.14
	pgoyette-compat-merge-20190127:1.14
	pgoyette-compat-20190127:1.14
	pgoyette-compat-20190118:1.14
	pgoyette-compat-1226:1.14
	pgoyette-compat-1126:1.14
	pgoyette-compat-1020:1.14
	pgoyette-compat-0930:1.14
	pgoyette-compat-0906:1.14
	pgoyette-compat-0728:1.14
	pgoyette-compat-0625:1.14
	pgoyette-compat-0521:1.14
	pgoyette-compat-0502:1.14
	pgoyette-compat-0422:1.14
	pgoyette-compat-0415:1.14
	pgoyette-compat-0407:1.14
	pgoyette-compat-0330:1.14
	pgoyette-compat-0322:1.14
	pgoyette-compat-0315:1.14
	pgoyette-compat:1.14.0.30
	pgoyette-compat-base:1.14
	perseant-stdc-iso10646:1.14.0.28
	perseant-stdc-iso10646-base:1.14
	prg-localcount2-base3:1.14
	prg-localcount2-base2:1.14
	prg-localcount2-base1:1.14
	prg-localcount2:1.14.0.26
	prg-localcount2-base:1.14
	pgoyette-localcount-20170426:1.14
	bouyer-socketcan-base1:1.14
	pgoyette-localcount-20170320:1.14
	bouyer-socketcan:1.14.0.24
	bouyer-socketcan-base:1.14
	pgoyette-localcount-20170107:1.14
	pgoyette-localcount-20161104:1.14
	localcount-20160914:1.14
	pgoyette-localcount-20160806:1.14
	pgoyette-localcount-20160726:1.14
	pgoyette-localcount:1.14.0.22
	pgoyette-localcount-base:1.14
	netbsd-5-2-3-RELEASE:1.14
	netbsd-5-1-5-RELEASE:1.14
	yamt-pagecache-base9:1.14
	yamt-pagecache-tag8:1.14
	tls-earlyentropy:1.14.0.18
	tls-earlyentropy-base:1.14
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.14
	riastradh-drm2-base3:1.14
	netbsd-5-2-2-RELEASE:1.14
	netbsd-5-1-4-RELEASE:1.14
	netbsd-5-2-1-RELEASE:1.14
	netbsd-5-1-3-RELEASE:1.14
	agc-symver:1.14.0.20
	agc-symver-base:1.14
	tls-maxphys-base:1.14
	yamt-pagecache-base8:1.14
	netbsd-5-2:1.14.0.16
	yamt-pagecache-base7:1.14
	netbsd-5-2-RELEASE:1.14
	netbsd-5-2-RC1:1.14
	yamt-pagecache-base6:1.14
	yamt-pagecache-base5:1.14
	yamt-pagecache-base4:1.14
	netbsd-5-1-2-RELEASE:1.14
	netbsd-5-1-1-RELEASE:1.14
	yamt-pagecache-base3:1.14
	yamt-pagecache-base2:1.14
	yamt-pagecache:1.14.0.14
	yamt-pagecache-base:1.14
	bouyer-quota2-nbase:1.14
	bouyer-quota2:1.14.0.12
	bouyer-quota2-base:1.14
	matt-nb5-pq3:1.14.0.10
	matt-nb5-pq3-base:1.14
	netbsd-5-1:1.14.0.8
	netbsd-5-1-RELEASE:1.14
	netbsd-5-1-RC4:1.14
	netbsd-5-1-RC3:1.14
	netbsd-5-1-RC2:1.14
	netbsd-5-1-RC1:1.14
	netbsd-5-0-2-RELEASE:1.14
	netbsd-5-0-1-RELEASE:1.14
	jym-xensuspend-nbase:1.14
	netbsd-5-0:1.14.0.6
	netbsd-5-0-RELEASE:1.14
	netbsd-5-0-RC4:1.14
	netbsd-5-0-RC3:1.14
	netbsd-5-0-RC2:1.14
	jym-xensuspend:1.14.0.4
	jym-xensuspend-base:1.14
	netbsd-5-0-RC1:1.14
	netbsd-5:1.14.0.2
	netbsd-5-base:1.14
	matt-mips64-base2:1.13
	matt-mips64:1.13.0.32
	mjf-devfs2:1.13.0.30
	mjf-devfs2-base:1.13
	netbsd-4-0-1-RELEASE:1.13
	wrstuden-revivesa-base-3:1.13
	wrstuden-revivesa-base-2:1.13
	wrstuden-fixsa-newbase:1.13
	wrstuden-revivesa-base-1:1.13
	yamt-pf42-base4:1.13
	yamt-pf42-base3:1.13
	hpcarm-cleanup-nbase:1.13
	yamt-pf42-baseX:1.13
	yamt-pf42-base2:1.13
	wrstuden-revivesa:1.13.0.28
	wrstuden-revivesa-base:1.13
	yamt-pf42:1.13.0.26
	yamt-pf42-base:1.13
	keiichi-mipv6-nbase:1.13
	keiichi-mipv6:1.13.0.24
	keiichi-mipv6-base:1.13
	matt-armv6-nbase:1.13
	matt-armv6-prevmlocking:1.13
	wrstuden-fixsa-base-1:1.13
	netbsd-4-0:1.13.0.22
	netbsd-4-0-RELEASE:1.13
	cube-autoconf:1.13.0.20
	cube-autoconf-base:1.13
	netbsd-4-0-RC5:1.13
	netbsd-4-0-RC4:1.13
	netbsd-4-0-RC3:1.13
	netbsd-4-0-RC2:1.13
	netbsd-4-0-RC1:1.13
	matt-armv6:1.13.0.18
	matt-armv6-base:1.13
	matt-mips64-base:1.13
	hpcarm-cleanup:1.13.0.16
	hpcarm-cleanup-base:1.13
	netbsd-3-1-1-RELEASE:1.13
	netbsd-3-0-3-RELEASE:1.13
	wrstuden-fixsa:1.13.0.14
	wrstuden-fixsa-base:1.13
	abandoned-netbsd-4-base:1.13
	abandoned-netbsd-4:1.13.0.8
	netbsd-3-1:1.13.0.10
	netbsd-3-1-RELEASE:1.13
	netbsd-3-0-2-RELEASE:1.13
	netbsd-3-1-RC4:1.13
	netbsd-3-1-RC3:1.13
	netbsd-3-1-RC2:1.13
	netbsd-3-1-RC1:1.13
	netbsd-4:1.13.0.12
	netbsd-4-base:1.13
	chap-midi-nbase:1.13
	netbsd-3-0-1-RELEASE:1.13
	chap-midi:1.13.0.6
	chap-midi-base:1.13
	netbsd-3-0:1.13.0.4
	netbsd-3-0-RELEASE:1.13
	netbsd-3-0-RC6:1.13
	netbsd-3-0-RC5:1.13
	netbsd-3-0-RC4:1.13
	netbsd-3-0-RC3:1.13
	netbsd-3-0-RC2:1.13
	netbsd-3-0-RC1:1.13
	netbsd-2-0-3-RELEASE:1.12.4.2
	netbsd-2-1:1.12.6.1.0.2
	netbsd-2-1-RELEASE:1.12.6.1
	netbsd-2-1-RC6:1.12.6.1
	netbsd-2-1-RC5:1.12.6.1
	netbsd-2-1-RC4:1.12.6.1
	netbsd-2-1-RC3:1.12.6.1
	netbsd-2-1-RC2:1.12.6.1
	netbsd-2-1-RC1:1.12.6.1
	netbsd-2-0-2-RELEASE:1.12.4.2
	netbsd-3:1.13.0.2
	netbsd-3-base:1.13
	netbsd-2-0-1-RELEASE:1.12
	netbsd-2:1.12.0.6
	netbsd-2-base:1.12
	netbsd-2-0-RELEASE:1.12
	netbsd-2-0-RC5:1.12
	netbsd-2-0-RC4:1.12
	netbsd-2-0-RC3:1.12
	netbsd-2-0-RC2:1.12
	netbsd-2-0-RC1:1.12
	netbsd-2-0:1.12.0.4
	netbsd-2-0-base:1.12
	netbsd-1-6-PATCH002-RELEASE:1.12
	netbsd-1-6-PATCH002:1.12
	netbsd-1-6-PATCH002-RC4:1.12
	netbsd-1-6-PATCH002-RC3:1.12
	netbsd-1-6-PATCH002-RC2:1.12
	netbsd-1-6-PATCH002-RC1:1.12
	netbsd-1-6-PATCH001:1.12
	netbsd-1-6-PATCH001-RELEASE:1.12
	netbsd-1-6-PATCH001-RC3:1.12
	netbsd-1-6-PATCH001-RC2:1.12
	netbsd-1-6-PATCH001-RC1:1.12
	fvdl_fs64_base:1.12
	netbsd-1-6-RELEASE:1.12
	netbsd-1-6-RC3:1.12
	netbsd-1-6-RC2:1.12
	netbsd-1-6-RC1:1.12
	netbsd-1-6:1.12.0.2
	netbsd-1-6-base:1.12
	netbsd-1-5-PATCH003:1.8.2.1
	netbsd-1-5-PATCH002:1.8.2.1
	netbsd-1-5-PATCH001:1.8.2.1
	nvi_1_79:1.1.1.6
	netbsd-1-5-RELEASE:1.8.2.1
	netbsd-1-5-BETA2:1.8.2.1
	netbsd-1-5-BETA:1.8.2.1
	netbsd-1-4-PATCH003:1.7
	netbsd-1-5-ALPHA2:1.8
	netbsd-1-5:1.8.0.2
	netbsd-1-5-base:1.8
	minoura-xpg4dl-base:1.7
	minoura-xpg4dl:1.7.0.8
	netbsd-1-4-PATCH002:1.7
	wrstuden-devbsize-19991221:1.7
	wrstuden-devbsize:1.7.0.6
	wrstuden-devbsize-base:1.7
	comdex-fall-1999:1.7.0.4
	comdex-fall-1999-base:1.7
	netbsd-1-4-PATCH001:1.7
	netbsd-1-4-RELEASE:1.7
	netbsd-1-4:1.7.0.2
	netbsd-1-4-base:1.7
	netbsd-1-3-PATCH003:1.6
	netbsd-1-3-PATCH003-CANDIDATE2:1.6
	netbsd-1-3-PATCH003-CANDIDATE1:1.6
	netbsd-1-3-PATCH003-CANDIDATE0:1.6
	netbsd-1-3-PATCH002:1.6
	netbsd-1-3-PATCH001:1.6
	netbsd-1-3-RELEASE:1.6
	netbsd-1-3-BETA:1.6
	netbsd-1-3:1.6.0.2
	netbsd-1-3-base:1.6
	netbsd-1-2-PATCH001:1.6
	netbsd-1-2-RELEASE:1.6
	netbsd-1-2-BETA:1.6
	netbsd-1-2:1.6.0.4
	netbsd-1-2-base:1.6
	nvi_1_66:1.1.1.5
	BOSTIC:1.1.1
	netbsd-1-1-PATCH001:1.5
	netbsd-1-1-RELEASE:1.5
	netbsd-1-1:1.5.0.4
	netbsd-1-1-base:1.5
	netbsd-1-0-PATCH06:1.5
	netbsd-1-0-PATCH05:1.5
	netbsd-1-0-PATCH04:1.5
	netbsd-1-0-PATCH03:1.5
	netbsd-1-0-PATCH02:1.5
	netbsd-1-0-PATCH1:1.5
	netbsd-1-0-PATCH0:1.5
	netbsd-1-0-RELEASE:1.5
	netbsd-1-0:1.5.0.2
	nvi-1-34b:1.1.1.4
	nvi-1-33b:1.1.1.3
	netbsd-1-0-base:1.3
	nvi-1-11b:1.1.1.2
	nvi-1-03:1.1.1.1
	bostic-nvi:1.1.1;
locks; strict;
comment	@ * @;


1.14
date	2008.10.29.16.49.37;	author christos;	state dead;
branches;
next	1.13;

1.13
date	2005.02.12.12.53.23;	author aymeric;	state Exp;
branches;
next	1.12;

1.12
date	2002.04.09.01.47.34;	author thorpej;	state Exp;
branches
	1.12.4.1
	1.12.6.1;
next	1.11;

1.11
date	2001.05.01.16.46.12;	author aymeric;	state Exp;
branches;
next	1.10;

1.10
date	2001.03.31.11.37.50;	author aymeric;	state Exp;
branches;
next	1.9;

1.9
date	2000.10.18.01.42.10;	author tv;	state Exp;
branches;
next	1.8;

1.8
date	2000.05.31.19.49.25;	author jdc;	state Exp;
branches
	1.8.2.1;
next	1.7;

1.7
date	98.01.09.08.08.02;	author perry;	state Exp;
branches
	1.7.8.1;
next	1.6;

1.6
date	96.05.20.03.47.56;	author mrg;	state Exp;
branches;
next	1.5;

1.5
date	94.08.17.20.12.54;	author cgd;	state Exp;
branches
	1.5.2.1;
next	1.4;

1.4
date	94.08.17.16.36.12;	author cgd;	state Exp;
branches;
next	1.3;

1.3
date	94.03.28.04.29.41;	author cgd;	state Exp;
branches;
next	1.2;

1.2
date	94.01.24.06.40.37;	author cgd;	state Exp;
branches;
next	1.1;

1.1
date	94.01.24.05.53.04;	author cgd;	state Exp;
branches
	1.1.1.1;
next	;

1.12.4.1
date	2005.02.12.12.24.13;	author aymeric;	state Exp;
branches;
next	1.12.4.2;

1.12.4.2
date	2005.02.12.12.46.26;	author aymeric;	state Exp;
branches;
next	;

1.12.6.1
date	2005.05.06.14.42.08;	author riz;	state Exp;
branches;
next	;

1.8.2.1
date	2000.10.18.01.45.26;	author tv;	state Exp;
branches;
next	;

1.7.8.1
date	2000.06.23.16.40.10;	author minoura;	state Exp;
branches;
next	;

1.5.2.1
date	94.08.17.20.12.54;	author cgd;	state dead;
branches;
next	1.5.2.2;

1.5.2.2
date	94.08.17.20.12.55;	author cgd;	state Exp;
branches;
next	;

1.1.1.1
date	94.01.24.05.53.05;	author cgd;	state Exp;
branches;
next	1.1.1.2;

1.1.1.2
date	94.03.28.02.55.43;	author cgd;	state Exp;
branches;
next	1.1.1.3;

1.1.1.3
date	94.08.17.16.16.57;	author cgd;	state Exp;
branches;
next	1.1.1.4;

1.1.1.4
date	94.08.17.19.18.38;	author cgd;	state Exp;
branches;
next	1.1.1.5;

1.1.1.5
date	96.05.20.01.56.34;	author mrg;	state Exp;
branches;
next	1.1.1.6;

1.1.1.6
date	2001.03.31.11.29.46;	author aymeric;	state Exp;
branches;
next	;


desc
@@


1.14
log
@bye old vi!
@
text
@/*	$NetBSD: ex_shell.c,v 1.13 2005/02/12 12:53:23 aymeric Exp $	*/

/*-
 * Copyright (c) 1992, 1993, 1994
 *	The Regents of the University of California.  All rights reserved.
 * Copyright (c) 1992, 1993, 1994, 1995, 1996
 *	Keith Bostic.  All rights reserved.
 *
 * See the LICENSE file for redistribution information.
 */

#include "config.h"

#include <sys/cdefs.h>
#ifndef lint
#if 0
static const char sccsid[] = "@@(#)ex_shell.c	10.38 (Berkeley) 8/19/96";
#else
__RCSID("$NetBSD: ex_shell.c,v 1.13 2005/02/12 12:53:23 aymeric Exp $");
#endif
#endif /* not lint */

#include <sys/param.h>
#include <sys/queue.h>
#include <sys/wait.h>

#include <bitstring.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "../common/common.h"

static const char *sigmsg __P((int));

/*
 * ex_shell -- :sh[ell]
 *	Invoke the program named in the SHELL environment variable
 *	with the argument -i.
 *
 * PUBLIC: int ex_shell __P((SCR *, EXCMD *));
 */
int
ex_shell(sp, cmdp)
	SCR *sp;
	EXCMD *cmdp;
{
	int rval;
	char buf[MAXPATHLEN];

	/* We'll need a shell. */
	if (opts_empty(sp, O_SHELL, 0))
		return (1);

	/*
	 * XXX
	 * Assumes all shells use -i.
	 */
	(void)snprintf(buf, sizeof(buf), "%s -i", O_STR(sp, O_SHELL));

	/* Restore the window name. */
	(void)sp->gp->scr_rename(sp, NULL, 0);

	/* If we're still in a vi screen, move out explicitly. */
	rval = ex_exec_proc(sp, cmdp, buf, NULL, !F_ISSET(sp, SC_SCR_EXWROTE));

	/* Set the window name. */
	(void)sp->gp->scr_rename(sp, sp->frp->name, 1);

	/*
	 * !!!
	 * Historically, vi didn't require a continue message after the
	 * return of the shell.  Match it.
	 */
	F_SET(sp, SC_EX_WAIT_NO);

	return (rval);
}

/*
 * ex_exec_proc --
 *	Run a separate process.
 *
 * PUBLIC: int ex_exec_proc __P((SCR *, EXCMD *, char *, const char *, int));
 */
int
ex_exec_proc(sp, cmdp, cmd, msg, need_newline)
	SCR *sp;
	EXCMD *cmdp;
	char *cmd;
	const char *msg;
	int need_newline;
{
	GS *gp;
	const char *name;
	pid_t pid;

	gp = sp->gp;

	/* We'll need a shell. */
	if (opts_empty(sp, O_SHELL, 0))
		return (1);

	/* Enter ex mode. */
	if (F_ISSET(sp, SC_VI)) {
		if (gp->scr_screen(sp, SC_EX)) {
			ex_emsg(sp, cmdp->cmd->name, EXM_NOCANON);
			return (1);
		}
		(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
		F_SET(sp, SC_SCR_EX | SC_SCR_EXWROTE);
	}

	/* Put out additional newline, message. */
	if (need_newline)
		(void)ex_puts(sp, "\n");
	if (msg != NULL) {
		(void)ex_puts(sp, msg);
		(void)ex_puts(sp, "\n");
	}
	(void)ex_fflush(sp);

	switch (pid = vfork()) {
	case -1:			/* Error. */
		msgq(sp, M_SYSERR, "vfork");
		return (1);
	case 0:				/* Utility. */
		if ((name = strrchr(O_STR(sp, O_SHELL), '/')) == NULL)
			name = O_STR(sp, O_SHELL);
		else
			++name;
		execl(O_STR(sp, O_SHELL), name, "-c", cmd, NULL);
		msgq_str(sp, M_SYSERR, O_STR(sp, O_SHELL), "execl: %s");
		_exit(127);
		/* NOTREACHED */
	default:			/* Parent. */
		return (proc_wait(sp, (long)pid, cmd, 0, 0));
	}
	/* NOTREACHED */
}

/*
 * proc_wait --
 *	Wait for one of the processes.
 *
 * !!!
 * The pid_t type varies in size from a short to a long depending on the
 * system.  It has to be cast into something or the standard promotion
 * rules get you.  I'm using a long based on the belief that nobody is
 * going to make it unsigned and it's unlikely to be a quad.
 *
 * PUBLIC: int proc_wait __P((SCR *, long, const char *, int, int));
 */
int
proc_wait(sp, pid, cmd, silent, okpipe)
	SCR *sp;
	long pid;
	const char *cmd;
	int silent, okpipe;
{
	size_t len;
	int nf, pstat;
	char *p;

	/* Wait for the utility, ignoring interruptions. */
	for (;;) {
		errno = 0;
		if (waitpid((pid_t)pid, &pstat, 0) != -1)
			break;
		if (errno != EINTR) {
			msgq(sp, M_SYSERR, "waitpid");
			return (1);
		}
	}

	/*
	 * Display the utility's exit status.  Ignore SIGPIPE from the
	 * parent-writer, as that only means that the utility chose to
	 * exit before reading all of its input.
	 */
	if (WIFSIGNALED(pstat) && (!okpipe || WTERMSIG(pstat) != SIGPIPE)) {
		for (; isblank(*cmd); ++cmd);
		p = msg_print(sp, cmd, &nf);
		len = strlen(p);
		msgq(sp, M_ERR, "%.*s%s: received signal: %s%s",
		    (int) MIN(len, 20), p, len > 20 ? " ..." : "",
		    sigmsg(WTERMSIG(pstat)),
		    WCOREDUMP(pstat) ? "; core dumped" : "");
		if (nf)
			FREE_SPACE(sp, p, 0);
		return (1);
	}

	if (WIFEXITED(pstat) && WEXITSTATUS(pstat)) {
		/*
		 * Remain silent for "normal" errors when doing shell file
		 * name expansions, they almost certainly indicate nothing
		 * more than a failure to match.
		 *
		 * Remain silent for vi read filter errors.  It's historic
		 * practice.
		 */
		if (!silent) {
			for (; isblank(*cmd); ++cmd);
			p = msg_print(sp, cmd, &nf);
			len = strlen(p);
			msgq(sp, M_ERR, "%.*s%s: exited with status %d",
			    (int) MIN(len, 20), p, len > 20 ? " ..." : "",
			    WEXITSTATUS(pstat));
			if (nf)
				FREE_SPACE(sp, p, 0);
		}
		return (1);
	}
	return (0);
}

/*
 * XXX
 * The sys_siglist[] table in the C library has this information, but there's
 * no portable way to get to it.  (Believe me, I tried.)
 */
typedef struct _sigs {
	int	 number;		/* signal number */
	char	*message;		/* related message */
} SIGS;

SIGS const sigs[] = {
#ifdef SIGABRT
	{ SIGABRT,	"Abort trap" },
#endif
#ifdef SIGALRM
	{ SIGALRM,	"Alarm clock" },
#endif
#ifdef SIGBUS
	{ SIGBUS,	"Bus error" },
#endif
#ifdef SIGCLD
	{ SIGCLD,	"Child exited or stopped" },
#endif
#ifdef SIGCHLD
	{ SIGCHLD,	"Child exited" },
#endif
#ifdef SIGCONT
	{ SIGCONT,	"Continued" },
#endif
#ifdef SIGDANGER
	{ SIGDANGER,	"System crash imminent" },
#endif
#ifdef SIGEMT
	{ SIGEMT,	"EMT trap" },
#endif
#ifdef SIGFPE
	{ SIGFPE,	"Floating point exception" },
#endif
#ifdef SIGGRANT
	{ SIGGRANT,	"HFT monitor mode granted" },
#endif
#ifdef SIGHUP
	{ SIGHUP,	"Hangup" },
#endif
#ifdef SIGILL
	{ SIGILL,	"Illegal instruction" },
#endif
#ifdef SIGINFO
	{ SIGINFO,	"Information request" },
#endif
#ifdef SIGINT
	{ SIGINT,	"Interrupt" },
#endif
#ifdef SIGIO
	{ SIGIO,	"I/O possible" },
#endif
#ifdef SIGIOT
	{ SIGIOT,	"IOT trap" },
#endif
#ifdef SIGKILL
	{ SIGKILL,	"Killed" },
#endif
#ifdef SIGLOST
	{ SIGLOST,	"Record lock" },
#endif
#ifdef SIGMIGRATE
	{ SIGMIGRATE,	"Migrate process to another CPU" },
#endif
#ifdef SIGMSG
	{ SIGMSG,	"HFT input data pending" },
#endif
#ifdef SIGPIPE
	{ SIGPIPE,	"Broken pipe" },
#endif
#ifdef SIGPOLL
	{ SIGPOLL,	"I/O possible" },
#endif
#ifdef SIGPRE
	{ SIGPRE,	"Programming error" },
#endif
#ifdef SIGPROF
	{ SIGPROF,	"Profiling timer expired" },
#endif
#ifdef SIGPWR
	{ SIGPWR,	"Power failure imminent" },
#endif
#ifdef SIGRETRACT
	{ SIGRETRACT,	"HFT monitor mode retracted" },
#endif
#ifdef SIGQUIT
	{ SIGQUIT,	"Quit" },
#endif
#ifdef SIGSAK
	{ SIGSAK,	"Secure Attention Key" },
#endif
#ifdef SIGSEGV
	{ SIGSEGV,	"Segmentation fault" },
#endif
#ifdef SIGSOUND
	{ SIGSOUND,	"HFT sound sequence completed" },
#endif
#ifdef SIGSTOP
	{ SIGSTOP,	"Suspended (signal)" },
#endif
#ifdef SIGSYS
	{ SIGSYS,	"Bad system call" },
#endif
#ifdef SIGTERM
	{ SIGTERM,	"Terminated" },
#endif
#ifdef SIGTRAP
	{ SIGTRAP,	"Trace/BPT trap" },
#endif
#ifdef SIGTSTP
	{ SIGTSTP,	"Suspended" },
#endif
#ifdef SIGTTIN
	{ SIGTTIN,	"Stopped (tty input)" },
#endif
#ifdef SIGTTOU
	{ SIGTTOU,	"Stopped (tty output)" },
#endif
#ifdef SIGURG
	{ SIGURG,	"Urgent I/O condition" },
#endif
#ifdef SIGUSR1
	{ SIGUSR1,	"User defined signal 1" },
#endif
#ifdef SIGUSR2
	{ SIGUSR2,	"User defined signal 2" },
#endif
#ifdef SIGVTALRM
	{ SIGVTALRM,	"Virtual timer expired" },
#endif
#ifdef SIGWINCH
	{ SIGWINCH,	"Window size changes" },
#endif
#ifdef SIGXCPU
	{ SIGXCPU,	"Cputime limit exceeded" },
#endif
#ifdef SIGXFSZ
	{ SIGXFSZ,	"Filesize limit exceeded" },
#endif
};

/*
 * sigmsg --
 * 	Return a pointer to a message describing a signal.
 */
static const char *
sigmsg(signo)
	int signo;
{
	static char buf[40];
	const SIGS *sigp;
	int n;

	for (n = 0,
	    sigp = &sigs[0]; n < sizeof(sigs) / sizeof(sigs[0]); ++n, ++sigp)
		if (sigp->number == signo)
			return (sigp->message);
	(void)snprintf(buf, sizeof(buf), "Unknown signal: %d", signo);
	return (buf);
}
@


1.13
log
@Fix the RCSID's to be $NetBSD$ instead of $NetBSD
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.12 2002/04/09 01:47:34 thorpej Exp $	*/
d19 1
a19 1
__RCSID("$NetBSD$");
@


1.12
log
@Use __RCSID() and __COPYRIGHT().
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.11 2001/05/01 16:46:12 aymeric Exp $	*/
d19 1
a19 1
__RCSID("$NetBSD");
@


1.12.6.1
log
@Pull up revision 1.13 (requested by aymeric in ticket #1195):
Fix the RCSID's to be $NetBSD$ instead of $NetBSD
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.12 2002/04/09 01:47:34 thorpej Exp $	*/
d19 1
a19 1
__RCSID("$NetBSD$");
@


1.12.4.1
log
@Fix the RCSID's to be $NetBSD$ instead of $NetBSD
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.12 2002/04/09 01:47:34 thorpej Exp $	*/
d19 1
a19 1
__RCSID("$NetBSD$");
@


1.12.4.2
log
@Backout previous. Sorry.
@
text
@d19 1
a19 1
__RCSID("$NetBSD");
@


1.11
log
@shutup most (non-intrusive) gcc warnings
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.10 2001/03/31 11:37:50 aymeric Exp $	*/
d14 1
d16 1
d18 3
@


1.10
log
@merge changes after import of nvi 1.79
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.9 2000/10/18 01:42:10 tv Exp $	*/
d185 1
a185 1
		    MIN(len, 20), p, len > 20 ? " ..." : "",
d207 1
a207 1
			    MIN(len, 20), p, len > 20 ? " ..." : "",
d229 1
a229 1
	SIGABRT,	"Abort trap",
d232 1
a232 1
	SIGALRM,	"Alarm clock",
d235 1
a235 1
	SIGBUS,		"Bus error",
d238 1
a238 1
	SIGCLD,		"Child exited or stopped",
d241 1
a241 1
	SIGCHLD,	"Child exited",
d244 1
a244 1
	SIGCONT,	"Continued",
d247 1
a247 1
	SIGDANGER,	"System crash imminent",
d250 1
a250 1
	SIGEMT,		"EMT trap",
d253 1
a253 1
	SIGFPE,		"Floating point exception",
d256 1
a256 1
	SIGGRANT,	"HFT monitor mode granted",
d259 1
a259 1
	SIGHUP,		"Hangup",
d262 1
a262 1
	SIGILL,		"Illegal instruction",
d265 1
a265 1
	SIGINFO,	"Information request",
d268 1
a268 1
	SIGINT,		"Interrupt",
d271 1
a271 1
	SIGIO,		"I/O possible",
d274 1
a274 1
	SIGIOT,		"IOT trap",
d277 1
a277 1
	SIGKILL,	"Killed",
d280 1
a280 1
	SIGLOST,	"Record lock",
d283 1
a283 1
	SIGMIGRATE,	"Migrate process to another CPU",
d286 1
a286 1
	SIGMSG,		"HFT input data pending",
d289 1
a289 1
	SIGPIPE,	"Broken pipe",
d292 1
a292 1
	SIGPOLL,	"I/O possible",
d295 1
a295 1
	SIGPRE,		"Programming error",
d298 1
a298 1
	SIGPROF,	"Profiling timer expired",
d301 1
a301 1
	SIGPWR,		"Power failure imminent",
d304 1
a304 1
	SIGRETRACT,	"HFT monitor mode retracted",
d307 1
a307 1
	SIGQUIT,	"Quit",
d310 1
a310 1
	SIGSAK,		"Secure Attention Key",
d313 1
a313 1
	SIGSEGV,	"Segmentation fault",
d316 1
a316 1
	SIGSOUND,	"HFT sound sequence completed",
d319 1
a319 1
	SIGSTOP,	"Suspended (signal)",
d322 1
a322 1
	SIGSYS,		"Bad system call",
d325 1
a325 1
	SIGTERM,	"Terminated",
d328 1
a328 1
	SIGTRAP,	"Trace/BPT trap",
d331 1
a331 1
	SIGTSTP,	"Suspended",
d334 1
a334 1
	SIGTTIN,	"Stopped (tty input)",
d337 1
a337 1
	SIGTTOU,	"Stopped (tty output)",
d340 1
a340 1
	SIGURG,		"Urgent I/O condition",
d343 1
a343 1
	SIGUSR1,	"User defined signal 1",
d346 1
a346 1
	SIGUSR2,	"User defined signal 2",
d349 1
a349 1
	SIGVTALRM,	"Virtual timer expired",
d352 1
a352 1
	SIGWINCH,	"Window size changes",
d355 1
a355 1
	SIGXCPU,	"Cputime limit exceeded",
d358 1
a358 1
	SIGXFSZ,	"Filesize limit exceeded",
@


1.9
log
@Fix %l[du] formats that have int arguments on ILP32; might break LP64.
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.8 2000/05/31 19:49:25 jdc Exp $	*/
d15 1
a15 1
static const char sccsid[] = "@@(#)ex_shell.c	10.33 (Berkeley) 4/27/96";
d60 4
a63 1
	/* If we're stil in a vi screen, move out explicitly. */
d66 3
d74 1
a74 1
	F_SET(sp, SC_EX_DONTWAIT);
d105 1
a105 1
		if (sp->gp->scr_screen(sp, SC_EX)) {
d185 1
a185 1
		    (int)MIN(len, 20), p, len > 20 ? " ..." : "",
d207 1
a207 1
			    (int)MIN(len, 20), p, len > 20 ? " ..." : "",
@


1.8
log
@Handle xterm's alternate screen when entering or leaving ex mode, e.g.
":!ls", so that the screen is not changed before the "Press any key"
message.  Taken from v1.79.
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.7 1998/01/09 08:08:02 perry Exp $	*/
d179 1
a179 1
		    MIN(len, 20), p, len > 20 ? " ..." : "",
d201 1
a201 1
			    MIN(len, 20), p, len > 20 ? " ..." : "",
@


1.8.2.1
log
@Pullup 1.9 [releng]:
Fix %l[du] formats that have int arguments on ILP32; might break LP64.
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.9 2000/10/18 01:42:10 tv Exp $	*/
d179 1
a179 1
		    (int)MIN(len, 20), p, len > 20 ? " ..." : "",
d201 1
a201 1
			    (int)MIN(len, 20), p, len > 20 ? " ..." : "",
@


1.7
log
@RCS Id Police.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d87 1
d91 2
d103 1
@


1.7.8.1
log
@Sync w/ netbsd-1-5-base.
@
text
@d1 1
a1 1
/*	$NetBSD: ex_shell.c,v 1.8 2000/05/31 19:49:25 jdc Exp $	*/
a86 1
	GS *gp;
a89 2
	gp = sp->gp;

a99 1
		(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
@


1.6
log
@merge in nvi 1.66
@
text
@d1 2
@


1.5
log
@clean up import.
@
text
@d4 2
d7 1
a7 27
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
d10 2
d13 1
a13 1
static char sccsid[] = "@@(#)ex_shell.c	8.26 (Berkeley) 8/17/94";
d18 1
a18 1
#include <sys/time.h>
d25 1
a26 1
#include <termios.h>
d29 3
a31 7
#include "compat.h"
#include <db.h>
#include <regex.h>

#include "vi.h"
#include "excmd.h"
#include "../svi/svi_screen.h"
d37 2
d41 1
a41 1
ex_shell(sp, ep, cmdp)
d43 1
a43 2
	EXF *ep;
	EXCMDARG *cmdp;
d45 1
d48 8
d57 12
a68 1
	return (ex_exec_proc(sp, buf, "\n", NULL));
d74 2
d78 1
a78 1
ex_exec_proc(sp, cmd, p1, p2)
d80 4
a83 1
	char *cmd, *p1, *p2;
a86 1
	int rval, teardown;
d88 2
a89 2
	/* Clear the rest of the screen. */
	if (sp->s_clear(sp))
d92 8
a99 2
	/* Save ex/vi terminal settings, and restore the original ones. */
	teardown = !ex_sleave(sp);
d101 8
a108 11
	/*
	 * Flush waiting messages (autowrite, for example) so the output
	 * matches historic practice.
	 */
	(void)sex_refresh(sp, sp->ep);

	/* Put out various messages. */
	if (p1 != NULL)
		(void)write(STDOUT_FILENO, p1, strlen(p1));
	if (p2 != NULL)
		(void)write(STDOUT_FILENO, p2, strlen(p2));
a109 1
	SIGBLOCK(sp->gp);
a111 2
		SIGUNBLOCK(sp->gp);

d113 1
a113 2
		rval = 1;
		break;
a114 3
		/* The utility has default signal behavior. */
		sig_end();

d120 1
a120 2
		msgq(sp, M_ERR, "Error: execl: %s: %s",
		    O_STR(sp, O_SHELL), strerror(errno));
d124 4
a127 1
		SIGUNBLOCK(sp->gp);
d129 32
a160 2
		rval = proc_wait(sp, (long)pid, cmd, 0);
		break;
a162 4
	/* Restore ex/vi terminal settings. */
	if (teardown)
		ex_rleave(sp);

d164 3
a166 5
	 * XXX
	 * Stat of the tty structures (see ex_sleave, ex_rleave) only give
	 * us 1-second resolution on the tty changes.  A fast '!' command,
	 * e.g. ":!pwd" can beat us to the refresh.  When there's better
	 * resolution from the stat(2) timers, this can go away.
d168 181
a348 1
	F_SET(sp, S_REFRESH);
d350 18
a367 1
	return (rval);
@


1.5.2.1
log
@file ex_shell.c was added on branch netbsd-1-0 on 1994-08-17 20:12:55 +0000
@
text
@d1 150
@


1.5.2.2
log
@clean up import.
@
text
@a0 150
/*-
 * Copyright (c) 1992, 1993, 1994
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef lint
static char sccsid[] = "@@(#)ex_shell.c	8.26 (Berkeley) 8/17/94";
#endif /* not lint */

#include <sys/param.h>
#include <sys/queue.h>
#include <sys/time.h>

#include <bitstring.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#include "compat.h"
#include <db.h>
#include <regex.h>

#include "vi.h"
#include "excmd.h"
#include "../svi/svi_screen.h"

/*
 * ex_shell -- :sh[ell]
 *	Invoke the program named in the SHELL environment variable
 *	with the argument -i.
 */
int
ex_shell(sp, ep, cmdp)
	SCR *sp;
	EXF *ep;
	EXCMDARG *cmdp;
{
	char buf[MAXPATHLEN];

	(void)snprintf(buf, sizeof(buf), "%s -i", O_STR(sp, O_SHELL));
	return (ex_exec_proc(sp, buf, "\n", NULL));
}

/*
 * ex_exec_proc --
 *	Run a separate process.
 */
int
ex_exec_proc(sp, cmd, p1, p2)
	SCR *sp;
	char *cmd, *p1, *p2;
{
	const char *name;
	pid_t pid;
	int rval, teardown;

	/* Clear the rest of the screen. */
	if (sp->s_clear(sp))
		return (1);

	/* Save ex/vi terminal settings, and restore the original ones. */
	teardown = !ex_sleave(sp);

	/*
	 * Flush waiting messages (autowrite, for example) so the output
	 * matches historic practice.
	 */
	(void)sex_refresh(sp, sp->ep);

	/* Put out various messages. */
	if (p1 != NULL)
		(void)write(STDOUT_FILENO, p1, strlen(p1));
	if (p2 != NULL)
		(void)write(STDOUT_FILENO, p2, strlen(p2));

	SIGBLOCK(sp->gp);
	switch (pid = vfork()) {
	case -1:			/* Error. */
		SIGUNBLOCK(sp->gp);

		msgq(sp, M_SYSERR, "vfork");
		rval = 1;
		break;
	case 0:				/* Utility. */
		/* The utility has default signal behavior. */
		sig_end();

		if ((name = strrchr(O_STR(sp, O_SHELL), '/')) == NULL)
			name = O_STR(sp, O_SHELL);
		else
			++name;
		execl(O_STR(sp, O_SHELL), name, "-c", cmd, NULL);
		msgq(sp, M_ERR, "Error: execl: %s: %s",
		    O_STR(sp, O_SHELL), strerror(errno));
		_exit(127);
		/* NOTREACHED */
	default:			/* Parent. */
		SIGUNBLOCK(sp->gp);

		rval = proc_wait(sp, (long)pid, cmd, 0);
		break;
	}

	/* Restore ex/vi terminal settings. */
	if (teardown)
		ex_rleave(sp);

	/*
	 * XXX
	 * Stat of the tty structures (see ex_sleave, ex_rleave) only give
	 * us 1-second resolution on the tty changes.  A fast '!' command,
	 * e.g. ":!pwd" can beat us to the refresh.  When there's better
	 * resolution from the stat(2) timers, this can go away.
	 */
	F_SET(sp, S_REFRESH);

	return (rval);
}
@


1.4
log
@clean up import.  still have to hack some things.
@
text
@d35 1
a35 1
static const char sccsid[] = "@@(#)ex_shell.c	8.25 (Berkeley) 8/17/94";
@


1.3
log
@nvi 1.11(beta) from bostic.  reconcile conflicts/kill rcsids.
@
text
@d35 1
a35 1
static char sccsid[] = "@@(#)ex_shell.c	8.21 (Berkeley) 3/23/94";
d96 6
d108 1
a108 1

d111 2
d115 1
a115 1
		goto err;
d117 2
a118 6
		/*
		 * The utility has default signal behavior.  Don't bother
		 * using sigaction(2) 'cause we want the default behavior.
		 */
		(void)signal(SIGINT, SIG_DFL);
		(void)signal(SIGQUIT, SIG_DFL);
d129 5
a135 2
	rval = proc_wait(sp, (long)pid, cmd, 0);

d137 1
a137 1
err:	if (teardown)
@


1.2
log
@more Ids than you'll ever want.
@
text
@d2 1
a2 1
 * Copyright (c) 1992, 1993
d35 1
a35 2
/* from: static char sccsid[] = "@@(#)ex_shell.c	8.17 (Berkeley) 12/23/93"; */
static char *rcsid = "$Id$";
d39 2
a40 1
#include <sys/stat.h>
d42 1
a42 1
#include <curses.h>
d44 3
d48 1
d51 4
a84 3
	struct sigaction act, oact;
	struct stat osb, sb;
	struct termios term;
d87 1
a87 1
	int isig, rval;
d94 1
a94 1
	EX_LEAVE(sp, isig, act, oact, sb, osb, term);
d130 2
a131 1
err:	EX_RETURN(sp, isig, act, oact, sb, osb, term);
d135 4
a138 4
	 * EX_LEAVE/EX_RETURN only give us 1-second resolution on the tty
	 * changes.  A fast '!' command, e.g. ":!pwd" can beat us to the
	 * refresh.  When there's better resolution from the stat(2) timers,
	 * this can go away.
@


1.1
log
@Initial revision
@
text
@d35 2
a36 1
static char sccsid[] = "@@(#)ex_shell.c	8.17 (Berkeley) 12/23/93";
@


1.1.1.1
log
@nvi 1.03, from ftp.cs.berkeley.edu, per keith bostic's permission.
@
text
@@


1.1.1.2
log
@nvi/nex 1.11beta from bostic.
@
text
@d2 1
a2 1
 * Copyright (c) 1992, 1993, 1994
d35 1
a35 1
static char sccsid[] = "@@(#)ex_shell.c	8.21 (Berkeley) 3/23/94";
d39 1
a39 2
#include <sys/queue.h>
#include <sys/time.h>
d41 1
a41 1
#include <bitstring.h>
a42 3
#include <limits.h>
#include <signal.h>
#include <stdio.h>
a43 1
#include <termios.h>
a45 4
#include "compat.h"
#include <db.h>
#include <regex.h>

d76 3
d81 1
a81 1
	int rval, teardown;
d88 1
a88 1
	teardown = !ex_sleave(sp);
d124 1
a124 2
err:	if (teardown)
		ex_rleave(sp);
d128 4
a131 4
	 * Stat of the tty structures (see ex_sleave, ex_rleave) only give
	 * us 1-second resolution on the tty changes.  A fast '!' command,
	 * e.g. ":!pwd" can beat us to the refresh.  When there's better
	 * resolution from the stat(2) timers, this can go away.
@


1.1.1.3
log
@new public version of nvi
@
text
@d35 1
a35 1
static const char sccsid[] = "@@(#)ex_shell.c	8.25 (Berkeley) 8/17/94";
a95 6
	/*
	 * Flush waiting messages (autowrite, for example) so the output
	 * matches historic practice.
	 */
	(void)sex_refresh(sp, sp->ep);

d102 1
a102 1
	SIGBLOCK(sp->gp);
a104 2
		SIGUNBLOCK(sp->gp);

d107 1
a107 1
		break;
d109 6
a114 2
		/* The utility has default signal behavior. */
		sig_end();
d125 1
a125 2
	default:			/* Parent. */
		SIGUNBLOCK(sp->gp);
d127 1
a127 3
		rval = proc_wait(sp, (long)pid, cmd, 0);
		break;
	}
d130 1
a130 1
	if (teardown)
@


1.1.1.4
log
@new public version of nvi
@
text
@d35 1
a35 1
static char sccsid[] = "@@(#)ex_shell.c	8.26 (Berkeley) 8/17/94";
@


1.1.1.5
log
@import of nvi 1.66
@
text
@a3 2
 * Copyright (c) 1992, 1993, 1994, 1995, 1996
 *	Keith Bostic.  All rights reserved.
d5 27
a31 1
 * See the LICENSE file for redistribution information.
a33 2
#include "config.h"

d35 1
a35 1
static const char sccsid[] = "@@(#)ex_shell.c	10.33 (Berkeley) 4/27/96";
d40 1
a40 1
#include <sys/wait.h>
a46 1
#include <stdlib.h>
d48 1
d51 7
a57 3
#include "../common/common.h"

static const char *sigmsg __P((int));
a62 2
 *
 * PUBLIC: int ex_shell __P((SCR *, EXCMD *));
d65 1
a65 1
ex_shell(sp, cmdp)
d67 2
a68 1
	EXCMD *cmdp;
a69 1
	int rval;
a71 8
	/* We'll need a shell. */
	if (opts_empty(sp, O_SHELL, 0))
		return (1);

	/*
	 * XXX
	 * Assumes all shells use -i.
	 */
d73 1
a73 12

	/* If we're stil in a vi screen, move out explicitly. */
	rval = ex_exec_proc(sp, cmdp, buf, NULL, !F_ISSET(sp, SC_SCR_EXWROTE));

	/*
	 * !!!
	 * Historically, vi didn't require a continue message after the
	 * return of the shell.  Match it.
	 */
	F_SET(sp, SC_EX_DONTWAIT);

	return (rval);
a78 2
 *
 * PUBLIC: int ex_exec_proc __P((SCR *, EXCMD *, char *, const char *, int));
d81 1
a81 1
ex_exec_proc(sp, cmdp, cmd, msg, need_newline)
d83 1
a83 4
	EXCMD *cmdp;
	char *cmd;
	const char *msg;
	int need_newline;
d87 1
d89 2
a90 2
	/* We'll need a shell. */
	if (opts_empty(sp, O_SHELL, 0))
d93 8
a100 8
	/* Enter ex mode. */
	if (F_ISSET(sp, SC_VI)) {
		if (sp->gp->scr_screen(sp, SC_EX)) {
			ex_emsg(sp, cmdp->cmd->name, EXM_NOCANON);
			return (1);
		}
		F_SET(sp, SC_SCR_EX | SC_SCR_EXWROTE);
	}
d102 5
a106 8
	/* Put out additional newline, message. */
	if (need_newline)
		(void)ex_puts(sp, "\n");
	if (msg != NULL) {
		(void)ex_puts(sp, msg);
		(void)ex_puts(sp, "\n");
	}
	(void)ex_fflush(sp);
d108 1
d111 2
d114 2
a115 1
		return (1);
d117 3
d125 2
a126 1
		msgq_str(sp, M_SYSERR, O_STR(sp, O_SHELL), "execl: %s");
d130 4
a133 1
		return (proc_wait(sp, (long)pid, cmd, 0, 0));
a134 2
	/* NOTREACHED */
}
d136 3
a138 33
/*
 * proc_wait --
 *	Wait for one of the processes.
 *
 * !!!
 * The pid_t type varies in size from a short to a long depending on the
 * system.  It has to be cast into something or the standard promotion
 * rules get you.  I'm using a long based on the belief that nobody is
 * going to make it unsigned and it's unlikely to be a quad.
 *
 * PUBLIC: int proc_wait __P((SCR *, long, const char *, int, int));
 */
int
proc_wait(sp, pid, cmd, silent, okpipe)
	SCR *sp;
	long pid;
	const char *cmd;
	int silent, okpipe;
{
	size_t len;
	int nf, pstat;
	char *p;

	/* Wait for the utility, ignoring interruptions. */
	for (;;) {
		errno = 0;
		if (waitpid((pid_t)pid, &pstat, 0) != -1)
			break;
		if (errno != EINTR) {
			msgq(sp, M_SYSERR, "waitpid");
			return (1);
		}
	}
d141 5
a145 3
	 * Display the utility's exit status.  Ignore SIGPIPE from the
	 * parent-writer, as that only means that the utility chose to
	 * exit before reading all of its input.
d147 1
a147 12
	if (WIFSIGNALED(pstat) && (!okpipe || WTERMSIG(pstat) != SIGPIPE)) {
		for (; isblank(*cmd); ++cmd);
		p = msg_print(sp, cmd, &nf);
		len = strlen(p);
		msgq(sp, M_ERR, "%.*s%s: received signal: %s%s",
		    MIN(len, 20), p, len > 20 ? " ..." : "",
		    sigmsg(WTERMSIG(pstat)),
		    WCOREDUMP(pstat) ? "; core dumped" : "");
		if (nf)
			FREE_SPACE(sp, p, 0);
		return (1);
	}
d149 1
a149 187
	if (WIFEXITED(pstat) && WEXITSTATUS(pstat)) {
		/*
		 * Remain silent for "normal" errors when doing shell file
		 * name expansions, they almost certainly indicate nothing
		 * more than a failure to match.
		 *
		 * Remain silent for vi read filter errors.  It's historic
		 * practice.
		 */
		if (!silent) {
			for (; isblank(*cmd); ++cmd);
			p = msg_print(sp, cmd, &nf);
			len = strlen(p);
			msgq(sp, M_ERR, "%.*s%s: exited with status %d",
			    MIN(len, 20), p, len > 20 ? " ..." : "",
			    WEXITSTATUS(pstat));
			if (nf)
				FREE_SPACE(sp, p, 0);
		}
		return (1);
	}
	return (0);
}

/*
 * XXX
 * The sys_siglist[] table in the C library has this information, but there's
 * no portable way to get to it.  (Believe me, I tried.)
 */
typedef struct _sigs {
	int	 number;		/* signal number */
	char	*message;		/* related message */
} SIGS;

SIGS const sigs[] = {
#ifdef SIGABRT
	SIGABRT,	"Abort trap",
#endif
#ifdef SIGALRM
	SIGALRM,	"Alarm clock",
#endif
#ifdef SIGBUS
	SIGBUS,		"Bus error",
#endif
#ifdef SIGCLD
	SIGCLD,		"Child exited or stopped",
#endif
#ifdef SIGCHLD
	SIGCHLD,	"Child exited",
#endif
#ifdef SIGCONT
	SIGCONT,	"Continued",
#endif
#ifdef SIGDANGER
	SIGDANGER,	"System crash imminent",
#endif
#ifdef SIGEMT
	SIGEMT,		"EMT trap",
#endif
#ifdef SIGFPE
	SIGFPE,		"Floating point exception",
#endif
#ifdef SIGGRANT
	SIGGRANT,	"HFT monitor mode granted",
#endif
#ifdef SIGHUP
	SIGHUP,		"Hangup",
#endif
#ifdef SIGILL
	SIGILL,		"Illegal instruction",
#endif
#ifdef SIGINFO
	SIGINFO,	"Information request",
#endif
#ifdef SIGINT
	SIGINT,		"Interrupt",
#endif
#ifdef SIGIO
	SIGIO,		"I/O possible",
#endif
#ifdef SIGIOT
	SIGIOT,		"IOT trap",
#endif
#ifdef SIGKILL
	SIGKILL,	"Killed",
#endif
#ifdef SIGLOST
	SIGLOST,	"Record lock",
#endif
#ifdef SIGMIGRATE
	SIGMIGRATE,	"Migrate process to another CPU",
#endif
#ifdef SIGMSG
	SIGMSG,		"HFT input data pending",
#endif
#ifdef SIGPIPE
	SIGPIPE,	"Broken pipe",
#endif
#ifdef SIGPOLL
	SIGPOLL,	"I/O possible",
#endif
#ifdef SIGPRE
	SIGPRE,		"Programming error",
#endif
#ifdef SIGPROF
	SIGPROF,	"Profiling timer expired",
#endif
#ifdef SIGPWR
	SIGPWR,		"Power failure imminent",
#endif
#ifdef SIGRETRACT
	SIGRETRACT,	"HFT monitor mode retracted",
#endif
#ifdef SIGQUIT
	SIGQUIT,	"Quit",
#endif
#ifdef SIGSAK
	SIGSAK,		"Secure Attention Key",
#endif
#ifdef SIGSEGV
	SIGSEGV,	"Segmentation fault",
#endif
#ifdef SIGSOUND
	SIGSOUND,	"HFT sound sequence completed",
#endif
#ifdef SIGSTOP
	SIGSTOP,	"Suspended (signal)",
#endif
#ifdef SIGSYS
	SIGSYS,		"Bad system call",
#endif
#ifdef SIGTERM
	SIGTERM,	"Terminated",
#endif
#ifdef SIGTRAP
	SIGTRAP,	"Trace/BPT trap",
#endif
#ifdef SIGTSTP
	SIGTSTP,	"Suspended",
#endif
#ifdef SIGTTIN
	SIGTTIN,	"Stopped (tty input)",
#endif
#ifdef SIGTTOU
	SIGTTOU,	"Stopped (tty output)",
#endif
#ifdef SIGURG
	SIGURG,		"Urgent I/O condition",
#endif
#ifdef SIGUSR1
	SIGUSR1,	"User defined signal 1",
#endif
#ifdef SIGUSR2
	SIGUSR2,	"User defined signal 2",
#endif
#ifdef SIGVTALRM
	SIGVTALRM,	"Virtual timer expired",
#endif
#ifdef SIGWINCH
	SIGWINCH,	"Window size changes",
#endif
#ifdef SIGXCPU
	SIGXCPU,	"Cputime limit exceeded",
#endif
#ifdef SIGXFSZ
	SIGXFSZ,	"Filesize limit exceeded",
#endif
};

/*
 * sigmsg --
 * 	Return a pointer to a message describing a signal.
 */
static const char *
sigmsg(signo)
	int signo;
{
	static char buf[40];
	const SIGS *sigp;
	int n;

	for (n = 0,
	    sigp = &sigs[0]; n < sizeof(sigs) / sizeof(sigs[0]); ++n, ++sigp)
		if (sigp->number == signo)
			return (sigp->message);
	(void)snprintf(buf, sizeof(buf), "Unknown signal: %d", signo);
	return (buf);
@


1.1.1.6
log
@import of nvi 1.79
@
text
@d13 1
a13 1
static const char sccsid[] = "@@(#)ex_shell.c	10.38 (Berkeley) 8/19/96";
d58 1
a58 4
	/* Restore the window name. */
	(void)sp->gp->scr_rename(sp, NULL, 0);

	/* If we're still in a vi screen, move out explicitly. */
a60 3
	/* Set the window name. */
	(void)sp->gp->scr_rename(sp, sp->frp->name, 1);

d66 1
a66 1
	F_SET(sp, SC_EX_WAIT_NO);
a84 1
	GS *gp;
a87 2
	gp = sp->gp;

d94 1
a94 1
		if (gp->scr_screen(sp, SC_EX)) {
a97 1
		(void)gp->scr_attr(sp, SA_ALTERNATE, 0);
@

