tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

patch adding a pidfile-option to script(1)



On a 'console server' (hooked up to the (serial) consoles of multiple
other servers) I'm using script(1) to capture the console outputs; the
typescript files end up being the console logs.

In order to allow newsyslog to rotate those typescripts, I added an
option (-P) to script(1) which causes it to write a pidfile.

I'm not asking for this to be merged into NetBSD, but I also wouldn't
mind.  Maybe somebody finds it useful.


diff a/usr.bin/script/script.1 b/usr.bin/script/script.1
--- a/usr.bin/script/script.1
+++ b/usr.bin/script/script.1
@@ -39,6 +39,7 @@
 .Nm
 .Op Fl adefpqr
 .Op Fl c Ar command
+.Op Fl P Ar pidfile
 .Op Ar file
 .Sh DESCRIPTION
 .Nm
@@ -86,6 +87,9 @@ This is useful for watching the script output in real time.
 Play back a session recorded with the
 .Fl r
 flag in real time.
+.It Fl P Ar pidfile
+Write the PID of the writing subprocess into
+.Ar pidfile .
 .It Fl q
 Be quiet, and don't output started and ended lines.
 .It Fl r
@@ -131,6 +135,10 @@ is not set, the Bourne shell
 is assumed.
 (Most shells set this variable automatically).
 .El
+.Sh SIGNALS
+Upon receipt of SIGUSR1, the typescript will be re-opened,
+so as to allow rotating long-term typescripts e.g. via
+newsyslog(8).
 .Sh SEE ALSO
 .Xr csh 1
 (for the
diff a/usr.bin/script/script.c b/usr.bin/script/script.c
--- a/usr.bin/script/script.c
+++ b/usr.bin/script/script.c
@@ -80,6 +80,8 @@ static size_t	outcc;
 static int	usesleep, rawout;
 static int	quiet, flush;
 static const char *fname;
+static const char *fmode;
+static char	*pfile;
 
 static volatile	sig_atomic_t die = 0;	/* exit if 1 */
 static int	cstat = EXIT_SUCCESS;	/* cmd. exit status */
@@ -94,6 +96,7 @@ static sig_t	xsignal(int, sig_t);
 __dead static void	dooutput(void);
 static void	finish(int);
 static void	scriptflush(int);
+static void	scriptreopen(int);
 static void	record(FILE *, char *, size_t, int);
 static void	consume(FILE *, off_t, char *, int);
 __dead static void	playback(FILE *);
@@ -116,13 +119,13 @@ main(int argc, char *argv[])
 	quiet = 0;
 	flush = 0;
 	command = NULL;
-	while ((ch = getopt(argc, argv, "ac:defpqr")) != -1)
+	while ((ch = getopt(argc, argv, "ac:defpP:qr")) != -1)
 		switch(ch) {
 		case 'a':
 			aflg = 1;
 			break;
 		case 'c':
-			command = optarg;
+			command = strdup(optarg);
 			break;
 		case 'd':
 			usesleep = 0;
@@ -136,6 +139,9 @@ main(int argc, char *argv[])
 		case 'p':
 			pflg = 1;
 			break;
+		case 'P':
+			pfile = strdup(optarg);
+			break;
 		case 'q':
 			quiet = 1;
 			break;
@@ -145,7 +151,7 @@ main(int argc, char *argv[])
 		case '?':
 		default:
 			(void)fprintf(stderr,
-			    "Usage: %s [-c <command>][-adefpqr] [file]\n",
+			    "Usage: %s [-c <command>][-P <pidfile>][-adefpqr] [file]\n",
 			    getprogname());
 			exit(EXIT_FAILURE);
 		}
@@ -157,7 +163,8 @@ main(int argc, char *argv[])
 	else
 		fname = "typescript";
 
-	if ((fscript = fopen(fname, pflg ? "r" : aflg ? "a" : "w")) == NULL)
+	fmode = pflg ? "r" : aflg ? "a" : "w";
+	if ((fscript = fopen(fname, fmode)) == NULL)
 		err(EXIT_FAILURE, "fopen %s", fname);
 
 	if (pflg)
@@ -185,6 +192,7 @@ main(int argc, char *argv[])
 		(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
 	}
 
+	(void)signal(SIGUSR1, SIG_IGN);
 	(void)xsignal(SIGCHLD, finish);
 	child = fork();
 	if (child == -1) {
@@ -278,6 +286,18 @@ dooutput(void)
 	value.it_interval.tv_usec = 0;
 	value.it_value = value.it_interval;
 	(void)setitimer(ITIMER_REAL, &value, NULL);
+	if (pfile) {
+		FILE *pf = fopen(pfile, "w");
+		if (pf) {
+			fprintf(pf, "%d\n", (int)getpid());
+			fclose(pf);
+		} else {
+			warn("fopen %s", pfile);
+			free(pfile);
+			pfile = NULL;
+		}
+	}
+	(void)signal(SIGUSR1, scriptreopen);
 	for (;;) {
 		scc = read(master, obuf, sizeof(obuf));
 		if (scc <= 0)
@@ -295,6 +315,18 @@ dooutput(void)
 	done(cstat);
 }
 
+static void
+scriptreopen(int signo)
+{
+	(void)fclose(fscript);
+	outcc = 0;
+	fscript = fopen(fname, fmode);
+	if (outcc) {
+		(void)fflush(fscript);
+		outcc = 0;
+	}
+}
+
 static void
 scriptflush(int signo)
 {
@@ -357,6 +389,8 @@ done(int status)
 		if (!quiet)
 			(void)printf("Script done, output file is %s\n", fname);
 	}
+	if (pfile)
+		unlink(pfile);
 	exit(status);
 }
 


Home | Main Index | Thread Index | Old Index