A dash as an argument to the -f option will now cause lastcomm to

read data from the standard input.  This allows tail -f to pipe
data to lastcomm, and thereby real-time monitoring of executed
commands.  The manual page includes the exact incantation.

MFC after:	2 weeks
This commit is contained in:
Diomidis Spinellis 2007-04-04 16:04:58 +00:00
parent beaa515e95
commit 44c900afd7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=168367
2 changed files with 54 additions and 18 deletions

View File

@ -32,12 +32,12 @@
.\" From: @(#)lastcomm.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
.Dd September 18, 1996
.Dd April 4, 2007
.Dt LASTCOMM 1
.Os
.Sh NAME
.Nm lastcomm
.Nd show last commands executed in reverse order
.Nd show last commands executed
.Sh SYNOPSIS
.Nm
.Op Fl EScesu
@ -73,6 +73,12 @@ Read from
.Ar file
rather than the default
.Pa /var/account/acct .
If
.Ar file
is a single dash
.Pq Sq \&-
.Nm
reads accounting entries from the standard input.
.El
.Pp
If no options are specified,
@ -138,11 +144,28 @@ a fork, but without a following
``D'' indicates the command terminated with the generation of a
.Pa core
file, and ``X'' indicates the command was terminated with a signal.
.Pp
By default, accounting entries are printed going backwards in time,
starting from the time
.Nm
was executed.
However, if
.Nm
reads entries from its standard input, then entries are printed in
the order they are read.
.Sh FILES
.Bl -tag -width /var/account/acct -compact
.It Pa /var/account/acct
default accounting file
.El
.Sh EXAMPLES
The command
.Dl lastcomm -Ee
will print the exit time and elapsed time of each command logged in
.Pa /var/account/acct ,
while
.Dl tail -f -c 0 /var/account/acct | lastcomm -f -
will print details of each terminating command.
.Sh SEE ALSO
.Xr last 1 ,
.Xr sigvec 2 ,

View File

@ -132,27 +132,40 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
/* Open the file. */
if ((fp = fopen(acctfile, "r")) == NULL || fstat(fileno(fp), &sb))
err(1, "could not open %s", acctfile);
if (strcmp(acctfile, "-") == 0)
fp = stdin;
else {
/* Open the file. */
if ((fp = fopen(acctfile, "r")) == NULL ||
fstat(fileno(fp), &sb))
err(1, "could not open %s", acctfile);
/*
* Round off to integral number of accounting records, probably
* not necessary, but it doesn't hurt.
*/
size = sb.st_size - sb.st_size % sizeof(struct acct);
/*
* Round off to integral number of accounting records,
* probably not necessary, but it doesn't hurt.
*/
size = sb.st_size - sb.st_size % sizeof(struct acct);
/* Check if any records to display. */
if ((unsigned)size < sizeof(struct acct))
exit(0);
/* Check if any records to display. */
if ((unsigned)size < sizeof(struct acct))
exit(0);
}
do {
int rv;
size -= sizeof(struct acct);
if (fseeko(fp, size, SEEK_SET) == -1)
err(1, "seek %s failed", acctfile);
if ((rv = fread(&ab, sizeof(struct acct), 1, fp)) != 1)
err(1, "read %s returned %d", acctfile, rv);
if (fp != stdin) {
size -= sizeof(struct acct);
if (fseeko(fp, size, SEEK_SET) == -1)
err(1, "seek %s failed", acctfile);
}
if ((rv = fread(&ab, sizeof(struct acct), 1, fp)) != 1) {
if (feof(fp))
break;
else
err(1, "read %s returned %d", acctfile, rv);
}
if (ab.ac_comm[0] == '\0') {
ab.ac_comm[0] = '?';