head 1.7; access; symbols RELENG_4_0_0_RELEASE:1.4 RELENG_4:1.4.0.6 RELENG_4_BP:1.4 RELENG_3_4_0_RELEASE:1.4 RELENG_3_3_0_RELEASE:1.4 RELENG_3_2_PAO:1.4.0.4 RELENG_3_2_PAO_BP:1.4 RELENG_3_2_0_RELEASE:1.4 RELENG_3_1_0_RELEASE:1.4 RELENG_3:1.4.0.2 RELENG_3_BP:1.4 RELENG_2_2_8_RELEASE:1.1.1.1.8.1 RELENG_3_0_0_RELEASE:1.4 RELENG_2_2_7_RELEASE:1.1.1.1.8.1 RELENG_2_2_6_RELEASE:1.1.1.1 RELENG_2_2_5_RELEASE:1.1.1.1 bsd_44_lite_2:1.1.1.1 RELENG_2_2_2_RELEASE:1.1.1.1 RELENG_2_2_1_RELEASE:1.1.1.1 RELENG_2_2_0_RELEASE:1.1.1.1 RELENG_2_1_7_RELEASE:1.1.1.1 RELENG_2_1_6_1_RELEASE:1.1.1.1 RELENG_2_1_6_RELEASE:1.1.1.1 RELENG_2_2:1.1.1.1.0.8 RELENG_2_2_BP:1.1.1.1 RELENG_2_1_5_RELEASE:1.1.1.1 RELENG_2_1_0_RELEASE:1.1.1.1 RELENG_2_1_0:1.1.1.1.0.6 RELENG_2_1_0_BP:1.1.1.1 RELENG_2_0_5_RELEASE:1.1.1.1 RELENG_2_0_5:1.1.1.1.0.4 RELENG_2_0_5_BP:1.1.1.1 RELENG_2_0_5_ALPHA:1.1.1.1 RELEASE_2_0:1.1.1.1 BETA_2_0:1.1.1.1 ALPHA_2_0:1.1.1.1.0.2 bsd_44_lite:1.1.1.1 CSRG:1.1.1; locks; comment @ * @; 1.7 date 2000.05.12.04.04.27; author hoek; state Exp; branches; next 1.6; 1.6 date 2000.05.09.04.13.49; author hoek; state Exp; branches; next 1.5; 1.5 date 2000.04.14.06.39.11; author imp; state Exp; branches; next 1.4; 1.4 date 98.07.31.04.05.11; author hoek; state Exp; branches 1.4.6.1; next 1.3; 1.3 date 98.06.14.16.03.40; author steve; state Exp; branches; next 1.2; 1.2 date 98.02.20.04.13.28; author jb; state Exp; branches; next 1.1; 1.1 date 94.05.27.12.30.44; author rgrimes; state Exp; branches 1.1.1.1; next ; 1.1.1.1 date 94.05.27.12.30.45; author rgrimes; state Exp; branches 1.1.1.1.8.1; next ; 1.1.1.1.8.1 date 98.07.17.04.19.45; author jkh; state Exp; branches; next ; 1.4.6.1 date 2000.05.09.04.18.38; author hoek; state Exp; branches; next 1.4.6.2; 1.4.6.2 date 2000.05.12.04.07.57; author hoek; state Exp; branches; next ; desc @@ 1.7 log @Improve hack from previous commit to this file: exit if we get successive EOFs from reading stderr (eg. not from argv[1]). @ text @/* * Copyright (c) 1988 Mark Nudleman * Copyright (c) 1988, 1993 * 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[] = "@@(#)os.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #ifndef lint static const char rcsid[] = "$FreeBSD: src/usr.bin/more/os.c,v 1.6 2000/05/09 04:13:49 hoek Exp $"; #endif /* not lint */ /* * Operating system dependent routines. * * Most of the stuff in here is based on Unix, but an attempt * has been made to make things work on other operating systems. * This will sometimes result in a loss of functionality, unless * someone rewrites code specifically for the new operating system. * * The makefile provides defines to decide whether various * Unix features are present. */ #include #include #include #include #include #include #include #include #include #include "less.h" #include "pathnames.h" volatile int reading; extern int screen_trashed; static jmp_buf read_label; /* * Pass the specified command to a shell to be executed. * Like plain "system()", but handles resetting terminal modes, etc. */ lsystem(cmd) char *cmd; { int inp; char cmdbuf[256]; char *shell, *getenv(); /* * Print the command which is to be executed, * unless the command starts with a "-". */ if (cmd[0] == '-') cmd++; else { lower_left(); clear_eol(); putstr("!"); putstr(cmd); putstr("\n"); } /* * De-initialize the terminal and take out of raw mode. */ deinit(); flush(); raw_mode(0); /* * Restore signals to their defaults. */ init_signals(0); /* * Force standard input to be the terminal, "/dev/tty", * even if less's standard input is coming from a pipe. */ inp = dup(0); (void)close(0); if (open(_PATH_TTY, O_RDONLY, 0) < 0) (void)dup(inp); /* * Pass the command to the system to be executed. * If we have a SHELL environment variable, use * <$SHELL -c "command"> instead of just . * If the command is empty, just invoke a shell. */ if ((shell = getenv("SHELL")) != NULL && *shell != '\0') { if (*cmd == '\0') cmd = shell; else { (void)snprintf(cmdbuf, sizeof(cmdbuf), "%s -c \"%s\"", shell, cmd); cmd = cmdbuf; } } if (*cmd == '\0') cmd = "sh"; (void)system(cmd); /* * Restore standard input, reset signals, raw mode, etc. */ (void)close(0); (void)dup(inp); (void)close(inp); init_signals(1); raw_mode(1); init(); screen_trashed = 1; #if defined(SIGWINCH) || defined(SIGWIND) /* * Since we were ignoring window change signals while we executed * the system command, we must assume the window changed. */ winch(); #endif } /* * Like read() system call, but is deliberately interruptable. * A call to intread() from a signal handler will interrupt * any pending iread(). */ iread(fd, buf, len) int fd; char *buf; int len; { register int n; static int neofs; if (setjmp(read_label)) /* * We jumped here from intread. */ return (READ_INTR); flush(); reading = 1; n = read(fd, buf, len); /* * XXX This is a hack. We do want to exit if we read a couple EOFs * from the terminal (to avoid spinning on input if the user * leaves us hanging), but we should be comparing against the * tty variable from ttyin.c. * * We wait for two successive EOFs just to give any potential * oddities the benefit of the doubt. */ if (fd == 2) { if (n == 0) neofs++; else neofs = 0; } if (neofs > 2) kill(getpid(), SIGHUP); reading = 0; if (n < 0) return (-1); return (n); } intread() { reading = 0; (void)sigsetmask(0L); longjmp(read_label, 1); } /* * Expand a filename, substituting any environment variables, etc. * The implementation of this is necessarily very operating system * dependent. This implementation is unabashedly only for Unix systems. */ FILE *popen(); char * glob(filename) char *filename; { FILE *f; char *p; int ch; char *cmd, *malloc(), *getenv(); static char buffer[MAXPATHLEN]; if (filename[0] == '#') return (filename); /* * We get the shell to expand the filename for us by passing * an "echo" command to the shell and reading its output. */ p = getenv("SHELL"); if (p == NULL || *p == '\0') { /* * Read the output of . */ (void)asprintf(&cmd, "echo \"%s\"", filename); if (cmd == NULL) return (filename); } else { /* * Read the output of <$SHELL -c "echo filename">. */ (void)asprintf(&cmd, "%s -c \"echo %s\"", p, filename); if (cmd == NULL) return (filename); } if ((f = popen(cmd, "r")) == NULL) return (filename); free(cmd); for (p = buffer; p < &buffer[sizeof(buffer)-1]; p++) { if ((ch = getc(f)) == '\n' || ch == EOF) break; *p = ch; } *p = '\0'; (void)pclose(f); return(buffer); } char * bad_file(filename, message, len) char *filename, *message; u_int len; { struct stat statbuf; char *strcat(), *strerror(); if (stat(filename, &statbuf) < 0) { (void)snprintf(message, len, "%s: %s", filename, strerror(errno)); return(message); } if ((statbuf.st_mode & S_IFMT) == S_IFDIR) { static char is_dir[] = " is a directory"; strtcpy(message, filename, (int)(len-sizeof(is_dir)-1)); (void)strcat(message, is_dir); return(message); } return((char *)NULL); } /* * Copy a string, truncating to the specified length if necessary. * Unlike strncpy(), the resulting string is guaranteed to be null-terminated. */ strtcpy(to, from, len) char *to, *from; int len; { char *strncpy(); (void)strncpy(to, from, (int)len); to[len-1] = '\0'; } @ 1.6 log @Exit if we read two EOFs from the keyboard input stream. Why two and not one? Just 'cause. PR: misc/14932 @ text @d41 1 a41 1 "$FreeBSD$"; d187 15 a201 5 /* There's really no terribly impressive reason why we should just * sighup after a single EOF read, nor is there any particular * reason why we SIGHUP ourselves rather than calling exit(). However, * none of it hurts, either. */ if (n == 0) neofs++; @ 1.5 log @#include where needed. Kill extern int errno;. Minor warnings in tip corrected. @ text @a32 2 * * $FreeBSD$ d39 5 d56 1 d59 2 a60 1 #include d62 1 a63 1 #include d66 2 a67 1 #include d176 1 d187 7 @ 1.4 log @Fix coredump when two signals are sent in rapid succession. PR: bin/5721 Submitted by: Oliver Fromme Also, add "volatile" to a variable modified by signal handlers (coincidentally, the same variable involved in the above fix, although this isn't related to the reported problem). @ text @d33 2 d56 1 a255 1 extern int errno; @ 1.4.6.1 log @Copy From Current: ordered includes, exit on eof, errno.h @ text @a38 5 #ifndef lint static const char rcsid[] = "$FreeBSD: src/usr.bin/more/os.c,v 1.6 2000/05/09 04:13:49 hoek Exp $"; #endif /* not lint */ a50 1 #include d53 2 a54 3 #include #include a55 1 #include d58 1 a58 2 #include "less.h" a166 1 static int neofs; a176 7 /* There's really no terribly impressive reason why we should just * sighup after a single EOF read, nor is there any particular * reason why we SIGHUP ourselves rather than calling exit(). However, * none of it hurts, either. */ if (n == 0) neofs++; if (neofs > 2) kill(getpid(), SIGHUP); d253 1 @ 1.4.6.2 log @CFC: improved version of hack from prev commit @ text @d41 1 a41 1 "$FreeBSD: src/usr.bin/more/os.c,v 1.7 2000/05/12 04:04:27 hoek Exp $"; d187 5 a191 15 /* * XXX This is a hack. We do want to exit if we read a couple EOFs * from the terminal (to avoid spinning on input if the user * leaves us hanging), but we should be comparing against the * tty variable from ttyin.c. * * We wait for two successive EOFs just to give any potential * oddities the benefit of the doubt. */ if (fd == 2) { if (n == 0) neofs++; else neofs = 0; } @ 1.3 log @sprintf -> snprintf to avoid potential buffer overflow. PR: 6907 Submitted by: Archie Cobbs @ text @d61 1 a61 1 int reading; d185 1 @ 1.2 log @Add #include to get prototypes for functions that gcc has builtin (and wants to know that the prototypes match). @ text @d126 2 a127 1 (void)sprintf(cmdbuf, "%s -c \"%s\"", shell, cmd); d219 1 a219 1 cmd = malloc((u_int)(strlen(filename)+8)); a221 1 (void)sprintf(cmd, "echo \"%s\"", filename); d227 1 a227 1 cmd = malloc((u_int)(strlen(p)+12)); a229 1 (void)sprintf(cmd, "%s -c \"echo %s\"", p, filename); d257 2 a258 1 (void)sprintf(message, "%s: %s", filename, strerror(errno)); @ 1.1 log @Initial revision @ text @d57 1 @ 1.1.1.1 log @BSD 4.4 Lite Usr.bin Sources @ text @@ 1.1.1.1.8.1 log @MFC: doc fixes, enhancements to locate & more, new tail functionality. @ text @a56 1 #include d125 1 a125 2 (void)snprintf(cmdbuf, sizeof(cmdbuf), "%s -c \"%s\"", shell, cmd); d217 1 a217 1 (void)asprintf(&cmd, "echo \"%s\"", filename); d220 1 d226 1 a226 1 (void)asprintf(&cmd, "%s -c \"echo %s\"", p, filename); d229 1 d257 1 a257 2 (void)snprintf(message, len, "%s: %s", filename, strerror(errno)); @