This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / vi / nex / ex_shell.c
CommitLineData
18ae9d6b
AS
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)ex_shell.c 8.17 (Berkeley) 12/23/93";
36#endif /* not lint */
37
38#include <sys/param.h>
39#include <sys/stat.h>
40
41#include <curses.h>
42#include <errno.h>
43#include <string.h>
44#include <unistd.h>
45
46#include "vi.h"
47#include "excmd.h"
48#include "../svi/svi_screen.h"
49
50/*
51 * ex_shell -- :sh[ell]
52 * Invoke the program named in the SHELL environment variable
53 * with the argument -i.
54 */
55int
56ex_shell(sp, ep, cmdp)
57 SCR *sp;
58 EXF *ep;
59 EXCMDARG *cmdp;
60{
61 char buf[MAXPATHLEN];
62
63 (void)snprintf(buf, sizeof(buf), "%s -i", O_STR(sp, O_SHELL));
64 return (ex_exec_proc(sp, buf, "\n", NULL));
65}
66
67/*
68 * ex_exec_proc --
69 * Run a separate process.
70 */
71int
72ex_exec_proc(sp, cmd, p1, p2)
73 SCR *sp;
74 char *cmd, *p1, *p2;
75{
76 struct sigaction act, oact;
77 struct stat osb, sb;
78 struct termios term;
79 const char *name;
80 pid_t pid;
81 int isig, rval;
82
83 /* Clear the rest of the screen. */
84 if (sp->s_clear(sp))
85 return (1);
86
87 /* Save ex/vi terminal settings, and restore the original ones. */
88 EX_LEAVE(sp, isig, act, oact, sb, osb, term);
89
90 /* Put out various messages. */
91 if (p1 != NULL)
92 (void)write(STDOUT_FILENO, p1, strlen(p1));
93 if (p2 != NULL)
94 (void)write(STDOUT_FILENO, p2, strlen(p2));
95
96
97 switch (pid = vfork()) {
98 case -1: /* Error. */
99 msgq(sp, M_SYSERR, "vfork");
100 rval = 1;
101 goto err;
102 case 0: /* Utility. */
103 /*
104 * The utility has default signal behavior. Don't bother
105 * using sigaction(2) 'cause we want the default behavior.
106 */
107 (void)signal(SIGINT, SIG_DFL);
108 (void)signal(SIGQUIT, SIG_DFL);
109
110 if ((name = strrchr(O_STR(sp, O_SHELL), '/')) == NULL)
111 name = O_STR(sp, O_SHELL);
112 else
113 ++name;
114 execl(O_STR(sp, O_SHELL), name, "-c", cmd, NULL);
115 msgq(sp, M_ERR, "Error: execl: %s: %s",
116 O_STR(sp, O_SHELL), strerror(errno));
117 _exit(127);
118 /* NOTREACHED */
119 }
120
121 rval = proc_wait(sp, (long)pid, cmd, 0);
122
123 /* Restore ex/vi terminal settings. */
124err: EX_RETURN(sp, isig, act, oact, sb, osb, term);
125
126 /*
127 * XXX
128 * EX_LEAVE/EX_RETURN only give us 1-second resolution on the tty
129 * changes. A fast '!' command, e.g. ":!pwd" can beat us to the
130 * refresh. When there's better resolution from the stat(2) timers,
131 * this can go away.
132 */
133 F_SET(sp, S_REFRESH);
134
135 return (rval);
136}