1/* Copyright (c) 1985 Ceriel J.H. Jacobs */
2
3#include "main.h"
4#include "commands.h"
5#include "display.h"
6#include "in_all.h"
7#include "options.h"
8#include "output.h"
9#include "process.h"
10#include "prompt.h"
11#include "term.h"
12
13int nopipe;
14char *progname;
15int interrupt;
16int no_tty;
17
18static int initialize(int x);
19static void sigquit(int signo);
20#ifdef SIGTSTP
21static void suspsig(int signo);
22#endif
23
24int
25main(int argc, char **argv)
26{
27 char **av;
28
29 (void)setlocale(LC_CTYPE, "");
30 if (!isatty(1)) {
31 no_tty = 1;
32 }
33 argv[argc] = 0;
34 progname = argv[0];
35 if ((av = readoptions(argv)) == (char **)0 || initialize(*av ? 1 : 0)) {
36 if (no_tty) {
37 close(1);
38 (void)dup(2);
39 }
40 putline("Usage: ");
41 putline(argv[0]);
42 putline(" [-c] [-u] [-n] [-q] [-number] [+command] [file ... ]\n");
43 flush();
44 exit(1);
45 }
46 if (no_tty) {
47 *--av = "cat";
48 execve("/bin/cat", av, (char *const[]){NULL});
49 } else
50 processfiles(argc - (av - argv), av);
51 (void)quit();
52 /* NOTREACHED */
53}
54
55/*
56 * Open temporary file for reading and writing.
57 * Panic if it fails
58 */
59
60/*
61 * Collect initializing stuff here.
62 */
63
64static int
65initialize(int x)
66{
67 if (!(nopipe = x)) {
68 /*
69 * Reading from pipe
70 */
71 if (isatty(0)) {
72 return 1;
73 }
74 stdf = dup(0); /* Duplicate file descriptor of input */
75 if (no_tty)
76 return 0;
77 /*
78 * Make sure standard input is from the terminal.
79 */
80 (void)close(0);
81 if (open("/dev/tty", O_RDONLY, 0) != 0) {
82 putline("Couldn't open terminal\n");
83 flush();
84 exit(1);
85 }
86 }
87 if (no_tty)
88 return 0;
89 /*
90 * Handle signals.
91 * Catch QUIT, DELETE and ^Z
92 */
93 (void)signal(SIGQUIT, SIG_IGN);
94 (void)signal(SIGINT, catchdel);
95 ini_terminal();
96#ifdef SIGTSTP
97 if (signal(SIGTSTP, SIG_IGN) == SIG_DFL) {
98 (void)signal(SIGTSTP, suspsig);
99 }
100#endif
101 (void)signal(SIGQUIT, sigquit);
102 return 0;
103}
104
105void
106catchdel(int signo)
107{
108 (void)signo;
109 (void)signal(SIGINT, catchdel);
110 interrupt = 1;
111}
112
113static void
114sigquit(int signo)
115{
116 (void)signo;
117 quit();
118}
119
120#ifdef SIGTSTP
121
122/*
123 * We had a SIGTSTP signal.
124 * Suspend, by a call to this routine.
125 */
126
127void
128suspend()
129{
130 nflush();
131 resettty();
132 (void)signal(SIGTSTP, SIG_DFL);
133 (void)kill(0, SIGTSTP);
134 /*
135 * We are not here anymore ...
136 *
137
138 *
139 * But we arive here ...
140 */
141 inittty();
142 putline(TI);
143 flush();
144 (void)signal(SIGTSTP, suspsig);
145}
146
147/*
148 * SIGTSTP signal handler.
149 * Just indicate that we had one, ignore further ones and return.
150 */
151
152static void
153suspsig(int signo)
154{
155 (void)signo;
156
157 suspend();
158 if (DoneSetJmp)
159 longjmp(SetJmpBuf, 1);
160}
161#endif
162
163/*
164 * quit : called on exit.
165 * I bet you guessed that much.
166 */
167
168int
169quit()
170{
171 clrbline();
172 resettty();
173 flush();
174 exit(0);
175}
176
177/*
178 * Exit, but nonvoluntarily.
179 * At least tell the user why.
180 */
181
182void
183panic(char *s)
184{
185 putline("\a\a\a\r\n");
186 putline(s);
187 putline("\r\n");
188 quit();
189}