* Copyright (c) 1988 Mark Nudleman
* Copyright (c) 1988 Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)os.c 5.5 (Berkeley) %G%";
* 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("/dev/tty", 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')
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.
return(time((long *)NULL
));
* 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.
static char buffer
[FILENAME
];
* 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
= calloc(strlen(filename
)+8, sizeof(char));
sprintf(cmd
, "echo \"%s\"", filename
);
* Read the output of <$SHELL -c "echo filename">.
cmd
= calloc(strlen(p
)+12);
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
)
* Returns NULL if the file can be opened and
* is an ordinary file, otherwise an error message
* (if it cannot be opened or is a directory, etc.)
bad_file(filename
, message
, len
)
if (stat(filename
, &statbuf
) < 0)
return (errno_message(filename
, message
, len
));
if ((statbuf
.st_mode
& S_IFMT
) == S_IFDIR
)
static char is_dir
[] = " is a directory";
strtcpy(message
, filename
, len
-sizeof(is_dir
)-1);
if ((statbuf
.st_mode
& S_IFMT
) != S_IFREG
)
static char not_reg
[] = " is not a regular file";
strtcpy(message
, filename
, len
-sizeof(not_reg
)-1);
strcat(message
, not_reg
);
* errno_message: Return an error message based on the value of "errno".
* okreadfail: Return true if the previous failure of a read
* (on the input tty) should be considered ok.
extern char *sys_errlist
[];
errno_message(filename
, message
, len
)
sprintf(msg
, "Error %d", errno
);
strtcpy(message
, filename
, len
-strlen(p
)-3);