* Copyright (c) 1988 Mark Nudleman
* Copyright (c) 1988 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
static char sccsid
[] = "@(#)os.c 5.12 (Berkeley) 3/1/91";
* 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.
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.
* Print the command which is to be executed,
* unless the command starts with a "-".
* De-initialize the terminal and take out of raw mode.
* Restore signals to their defaults.
* Force standard input to be the terminal, "/dev/tty",
* even if less's standard input is coming from a pipe.
if (open(_PATH_TTY
, O_RDONLY
, 0) < 0)
* Pass the command to the system to be executed.
* If we have a SHELL environment variable, use
* <$SHELL -c "command"> instead of just <command>.
* If the command is empty, just invoke a shell.
if ((shell
= getenv("SHELL")) != NULL
&& *shell
!= '\0')
(void)sprintf(cmdbuf
, "%s -c \"%s\"", shell
, cmd
);
* Restore standard input, reset signals, raw mode, etc.
#if defined(SIGWINCH) || defined(SIGWIND)
* Since we were ignoring window change signals while we executed
* the system command, we must assume the window changed.
* Like read() system call, but is deliberately interruptable.
* A call to intread() from a signal handler will interrupt
* We jumped here from intread.
* 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.
char *cmd
, *malloc(), *getenv();
static char buffer
[MAXPATHLEN
];
* We get the shell to expand the filename for us by passing
* an "echo" command to the shell and reading its output.
if (p
== NULL
|| *p
== '\0')
* Read the output of <echo filename>.
cmd
= malloc((u_int
)(strlen(filename
)+8));
(void)sprintf(cmd
, "echo \"%s\"", filename
);
* Read the output of <$SHELL -c "echo filename">.
cmd
= malloc((u_int
)(strlen(p
)+12));
(void)sprintf(cmd
, "%s -c \"echo %s\"", p
, filename
);
if ((f
= popen(cmd
, "r")) == NULL
)
for (p
= buffer
; p
< &buffer
[sizeof(buffer
)-1]; p
++)
if ((ch
= getc(f
)) == '\n' || ch
== EOF
)
bad_file(filename
, message
, len
)
char *filename
, *message
;
char *strcat(), *strerror();
if (stat(filename
, &statbuf
) < 0) {
(void)sprintf(message
, "%s: %s", filename
, strerror(errno
));
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
);
* Copy a string, truncating to the specified length if necessary.
* Unlike strncpy(), the resulting string is guaranteed to be null-terminated.
(void)strncpy(to
, from
, (int)len
);