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