grep -efoo dropped core on the sparc
[unix-history] / usr / src / usr.bin / script / script.c
CommitLineData
22e155fc
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
c66a959c
KB
3 * All rights reserved.
4 *
cb956e54 5 * %sccs.include.redist.c%
22e155fc
DF
6 */
7
8#ifndef lint
9char copyright[] =
10"@(#) Copyright (c) 1980 Regents of the University of California.\n\
11 All rights reserved.\n";
c66a959c 12#endif /* not lint */
22e155fc 13
784bcaee 14#ifndef lint
c0468dfd 15static char sccsid[] = "@(#)script.c 5.14 (Berkeley) %G%";
c66a959c 16#endif /* not lint */
4ca10280 17
3481eb52 18/*
784bcaee 19 * script
3481eb52 20 */
784bcaee
BJ
21#include <sys/types.h>
22#include <sys/stat.h>
c1eb5ad2 23#include <termios.h>
784bcaee 24#include <sys/ioctl.h>
840fc587 25#include <sys/time.h>
bdd96e2c 26#include <sys/file.h>
435e8dff 27#include <sys/signal.h>
c66a959c 28#include <stdio.h>
435e8dff 29#include <paths.h>
784bcaee 30
784bcaee
BJ
31char *shell;
32FILE *fscript;
33int master;
34int slave;
35int child;
5e497b6f 36int subchild;
c66a959c 37char *fname;
784bcaee 38
c1eb5ad2 39struct termios tt;
5266af34 40struct winsize win;
784bcaee
BJ
41int lb;
42int l;
4e816c0a 43char line[] = "/dev/ptyXX";
784bcaee
BJ
44int aflg;
45
46main(argc, argv)
47 int argc;
48 char *argv[];
49{
c66a959c
KB
50 extern char *optarg;
51 extern int optind;
52 int ch;
4c529d71 53 void finish();
c66a959c
KB
54 char *getenv();
55
56 while ((ch = getopt(argc, argv, "a")) != EOF)
57 switch((char)ch) {
784bcaee
BJ
58 case 'a':
59 aflg++;
60 break;
c66a959c 61 case '?':
784bcaee 62 default:
c66a959c 63 fprintf(stderr, "usage: script [-a] [file]\n");
784bcaee 64 exit(1);
3481eb52 65 }
c66a959c
KB
66 argc -= optind;
67 argv += optind;
68
784bcaee
BJ
69 if (argc > 0)
70 fname = argv[0];
c66a959c
KB
71 else
72 fname = "typescript";
784bcaee
BJ
73 if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) {
74 perror(fname);
3481eb52
BJ
75 fail();
76 }
c66a959c
KB
77
78 shell = getenv("SHELL");
79 if (shell == NULL)
435e8dff 80 shell = _PATH_BSHELL;
c66a959c 81
c0468dfd
MT
82 (void) tcgetattr(0, &tt);
83 (void) ioctl(0, TIOCGWINSZ, (char *)&win);
84 if (openpty(&master, &slave, NULL, &tt, &win) == -1) {
85 perror("openpty");
86 exit(1);
87 }
88
784bcaee 89 printf("Script started, file is %s\n", fname);
c0468dfd 90 fixtty(); /* go raw */
3481eb52 91
784bcaee
BJ
92 (void) signal(SIGCHLD, finish);
93 child = fork();
94 if (child < 0) {
95 perror("fork");
96 fail();
97 }
98 if (child == 0) {
5e497b6f
JB
99 subchild = child = fork();
100 if (child < 0) {
784bcaee
BJ
101 perror("fork");
102 fail();
103 }
5e497b6f 104 if (child)
3481eb52 105 dooutput();
784bcaee
BJ
106 else
107 doshell();
3481eb52 108 }
784bcaee 109 doinput();
3481eb52
BJ
110}
111
3481eb52
BJ
112doinput()
113{
c66a959c 114 register int cc;
784bcaee 115 char ibuf[BUFSIZ];
3481eb52 116
784bcaee
BJ
117 (void) fclose(fscript);
118 while ((cc = read(0, ibuf, BUFSIZ)) > 0)
119 (void) write(master, ibuf, cc);
120 done();
121}
3481eb52 122
840fc587 123#include <sys/wait.h>
3481eb52 124
4c529d71 125void
784bcaee
BJ
126finish()
127{
128 union wait status;
5e497b6f
JB
129 register int pid;
130 register int die = 0;
3481eb52 131
4c529d71 132 while ((pid = wait3((int *)&status, WNOHANG, 0)) > 0)
5e497b6f
JB
133 if (pid == child)
134 die = 1;
135
136 if (die)
137 done();
3481eb52
BJ
138}
139
3481eb52
BJ
140dooutput()
141{
c66a959c
KB
142 register int cc;
143 time_t tvec, time();
144 char obuf[BUFSIZ], *ctime();
784bcaee
BJ
145
146 (void) close(0);
c66a959c 147 tvec = time((time_t *)NULL);
784bcaee
BJ
148 fprintf(fscript, "Script started on %s", ctime(&tvec));
149 for (;;) {
150 cc = read(master, obuf, sizeof (obuf));
151 if (cc <= 0)
152 break;
153 (void) write(1, obuf, cc);
154 (void) fwrite(obuf, 1, cc, fscript);
3481eb52 155 }
f640284e 156 done();
3481eb52
BJ
157}
158
3481eb52
BJ
159doshell()
160{
161
c0468dfd 162 close(master);
784bcaee 163 (void) fclose(fscript);
c0468dfd 164 login_tty(slave);
3481eb52 165 execl(shell, "sh", "-i", 0);
784bcaee 166 perror(shell);
3481eb52
BJ
167 fail();
168}
169
170fixtty()
171{
c1eb5ad2 172 struct termios rtt;
3481eb52 173
c1eb5ad2
MT
174 rtt = tt;
175 cfmakeraw(&rtt);
176 rtt.c_lflag &= ~ECHO;
df27234c 177 (void) tcsetattr(0, TCSAFLUSH, &rtt);
3481eb52
BJ
178}
179
180fail()
181{
182
784bcaee 183 (void) kill(0, SIGTERM);
3481eb52
BJ
184 done();
185}
186
187done()
188{
c66a959c
KB
189 time_t tvec, time();
190 char *ctime();
3481eb52 191
f640284e 192 if (subchild) {
c66a959c 193 tvec = time((time_t *)NULL);
c7953abd 194 fprintf(fscript,"\nScript done on %s", ctime(&tvec));
f640284e
S
195 (void) fclose(fscript);
196 (void) close(master);
197 } else {
df27234c 198 (void) tcsetattr(0, TCSAFLUSH, &tt);
5e497b6f
JB
199 printf("Script done, file is %s\n", fname);
200 }
784bcaee 201 exit(0);
3481eb52 202}