Make POSIX 1003.2 (Draft 11.2) compliant.

This commit is contained in:
jtc 1993-07-15 17:05:00 +00:00
parent fc0ba801cf
commit aab7593a78
4 changed files with 106 additions and 37 deletions

View File

@ -31,15 +31,15 @@
.\" .\"
.\" @(#)head.1 6.6 (Berkeley) 7/24/91 .\" @(#)head.1 6.6 (Berkeley) 7/24/91
.\" .\"
.Dd July 24, 1991 .Dd July 14, 1993
.Dt HEAD 1 .Dt HEAD 1
.Os BSD 3 .Os
.Sh NAME .Sh NAME
.Nm head .Nm head
.Nd give first few lines .Nd give first few lines
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm head .Nm head
.Op Fl Ns Ar count .Op Fl n Ar count
.Op Ar .Op Ar
.Sh DESCRIPTION .Sh DESCRIPTION
This filter gives the first This filter gives the first
@ -51,6 +51,16 @@ is omitted it defaults to
10. 10.
.Sh SEE ALSO .Sh SEE ALSO
.Xr tail 1 .Xr tail 1
.Sh STANDARDS
The
.Nm head
command is expected to be
.St -p1003.2
compliant.
.Pp
The historic command line syntax of
.Nm head
is supported by this implementation.
.Sh HISTORY .Sh HISTORY
The The
.Nm head .Nm head

View File

@ -42,7 +42,11 @@ static char sccsid[] = "@(#)head.c 5.5 (Berkeley) 6/1/90";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <ctype.h> #include <ctype.h>
static void usage ();
/* /*
* head - give the first few lines of a stream or of each of a set of files * head - give the first few lines of a stream or of each of a set of files
* *
@ -56,19 +60,28 @@ main(argc, argv)
register int ch, cnt; register int ch, cnt;
int firsttime, linecnt = 10; int firsttime, linecnt = 10;
if (argc > 1 && argv[1][0] == '-') { /* handle obsolete -number syntax */
if (!isdigit(argv[1][1])) { if (argc > 1 && argv[1][0] == '-' && isdigit(argv[1][1])) {
fprintf(stderr, "head: illegal option -- %c\n", argv[1][1]);
goto usage;
}
if ((linecnt = atoi(argv[1] + 1)) < 0) { if ((linecnt = atoi(argv[1] + 1)) < 0) {
usage: fputs("usage: head [-line_count] [file ...]\n", stderr); usage ();
exit(1);
} }
--argc; ++argv; argc--; argv++;
} }
while ((ch = getopt (argc, argv, "n:")) != EOF)
switch (ch) {
case 'n':
if ((linecnt = atoi(optarg)) < 0)
usage ();
break;
default:
usage();
}
argc -= optind, argv += optind;
/* setlinebuf(stdout); */ /* setlinebuf(stdout); */
for (firsttime = 1, --argc, ++argv;; firsttime = 0) { for (firsttime = 1; ; firsttime = 0) {
if (!*argv) { if (!*argv) {
if (!firsttime) if (!firsttime)
exit(0); exit(0);
@ -92,3 +105,12 @@ usage: fputs("usage: head [-line_count] [file ...]\n", stderr);
} }
/*NOTREACHED*/ /*NOTREACHED*/
} }
static void
usage ()
{
fputs("usage: head [-n line_count] [file ...]\n", stderr);
exit(1);
}

View File

@ -42,7 +42,7 @@
.Nd invoke a command immune to hangups .Nd invoke a command immune to hangups
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm nohup .Nm nohup
.Ar command .Ar utility
.Op Ar arg ... .Op Ar arg ...
.Sh DESCRIPTION .Sh DESCRIPTION
The The
@ -53,20 +53,13 @@ with
its arguments its arguments
and at this time sets the signal and at this time sets the signal
.Dv SIGHUP .Dv SIGHUP
to be ignored. The signal to be ignored.
.Dv SIGQUIT
may also be set
to be ignored.
If the standard output is a terminal, the standard output is If the standard output is a terminal, the standard output is
appended to the file appended to the file
.Pa nohup.out .Pa nohup.out
in the current directory. in the current directory.
If standard error is a terminal, it is directed to the same place If standard error is a terminal, it is directed to the same place
as the standard output. as the standard output.
.Pp
.Nm Nohup
exits 1 if an error occurs, otherwise the exit status is that of
.Ar command .
.Sh ENVIRONMENT .Sh ENVIRONMENT
The following variable is utilized by The following variable is utilized by
.Nm nohup . .Nm nohup .
@ -80,6 +73,26 @@ utility uses the directory named by
.Ev HOME .Ev HOME
to create the file. to create the file.
.El .El
.Sh DIAGNOSTICS
The
.Nm nohup
utility shall exit with one of the following values:
.Bl -tag -width Ds
.It 126
The
.Ar utility
was found but could not be invoked.
.It 127
The
.Ar utility
could not be found or an error occured in
.Nm nohup.
.El
.Pp
Otherwise, the exit status of
.Nm nohup
shall be that of
.Ar utility .
.Sh SEE ALSO .Sh SEE ALSO
.Xr signal 3 .Xr signal 3
.Sh STANDARDS .Sh STANDARDS

View File

@ -44,16 +44,31 @@ static char sccsid[] = "@(#)nohup.c 5.4 (Berkeley) 6/1/90";
#include <sys/param.h> #include <sys/param.h>
#include <sys/signal.h> #include <sys/signal.h>
#include <sys/file.h> #include <sys/file.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
extern int errno; static void dofile();
static void usage();
/* nohup shall exit with one of the following values:
126 - The utility was found but could not be invoked.
127 - An error occured in the nohup utility, or the utility could
not be found. */
#define EXIT_NOEXEC 126
#define EXIT_NOTFOUND 127
#define EXIT_MISC 127
int
main(argc, argv) main(argc, argv)
int argc; int argc;
char **argv; char **argv;
{ {
char *strerror(); int exit_status;
if (argc < 2) if (argc < 2)
usage(); usage();
@ -63,49 +78,58 @@ main(argc, argv)
if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) { if (isatty(STDERR_FILENO) && dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
/* may have just closed stderr */ /* may have just closed stderr */
(void)fprintf(stdin, "nohup: %s\n", strerror(errno)); (void)fprintf(stdin, "nohup: %s\n", strerror(errno));
exit(1); exit(EXIT_MISC);
} }
/* The nohup utility shall take the standard action for all signals
except that SIGHUP shall be ignored. */
(void)signal(SIGHUP, SIG_IGN); (void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGQUIT, SIG_IGN);
execvp(argv[1], &argv[1]); execvp(argv[1], &argv[1]);
(void)fprintf(stderr, exit_status = (errno = ENOENT) ? EXIT_NOTFOUND : EXIT_NOEXEC;
"nohup: %s: %s\n", argv[1], strerror(errno)); (void)fprintf(stderr, "nohup: %s: %s\n", argv[1], strerror(errno));
exit(1); exit(exit_status);
} }
static void
dofile() dofile()
{ {
int fd; int fd;
char *p, path[MAXPATHLEN]; char *p, path[MAXPATHLEN];
off_t lseek();
char *getenv(), *strcpy(), *strcat(), *strerror();
/* If the standard output is a terminal, all output written to
its standard output shall be appended to the end of the file
nohup.out in the current directory. If nohup.out cannot be
created or opened for appending, the output shall be appended
to the end of the file nohup.out in the directory specified
by the HOME environment variable.
If a file is created, the file's permission bits shall be
set to S_IRUSR | S_IWUSR. */
#define FILENAME "nohup.out" #define FILENAME "nohup.out"
p = FILENAME; if ((fd = open(FILENAME, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR)) >= 0)
if ((fd = open(p, O_RDWR|O_CREAT, 0600)) >= 0)
goto dupit; goto dupit;
if (p = getenv("HOME")) { if ((p = getenv("HOME")) != NULL) {
(void)strcpy(path, p); (void)strcpy(path, p);
(void)strcat(path, "/"); (void)strcat(path, "/");
(void)strcat(path, FILENAME); (void)strcat(path, FILENAME);
if ((fd = open(p = path, O_RDWR|O_CREAT, 0600)) >= 0) if ((fd = open(p = path, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR)) >= 0)
goto dupit; goto dupit;
} }
(void)fprintf(stderr, "nohup: can't open a nohup.out file.\n"); (void)fprintf(stderr, "nohup: can't open a nohup.out file.\n");
exit(1); exit(EXIT_MISC);
dupit: (void)lseek(fd, 0L, SEEK_END); dupit: (void)lseek(fd, 0L, SEEK_END);
if (dup2(fd, STDOUT_FILENO) == -1) { if (dup2(fd, STDOUT_FILENO) == -1) {
(void)fprintf(stderr, "nohup: %s\n", strerror(errno)); (void)fprintf(stderr, "nohup: %s\n", strerror(errno));
exit(1); exit(EXIT_MISC);
} }
(void)fprintf(stderr, "sending output to %s\n", p); (void)fprintf(stderr, "sending output to %s\n", p);
} }
static void
usage() usage()
{ {
(void)fprintf(stderr, "usage: nohup command\n"); (void)fprintf(stderr, "usage: nohup command\n");
exit(1); exit(EXIT_MISC);
} }