Hi all,

here's a patch which I wrote recently. The reasons and other details
(including a short list of potential problems) is in the head of the
patch head itself, so I won't repeat them here.

I don't know much about the current development status of screen; I
hope you are in a state where you can at least consider outside
patches.

regards,
Jörgen

-- 
  // Jörgen Grahn                  | mot du jour: Massachusetts! I    
\X/ <[EMAIL PROTECTED]>         | Velinga!                         
Here's a fairly minor patch against screen 4.0.3. Enjoy.

The background: we use screen as part of automated stability tests at
work, and we use the logging mechanism.  We noticed that we could come
back after a weekend run and find the disks filled with dozens of
gigabytes of output, when some command went crazy and kept spewing
output.

So I wrote a quick workaround for screen which closed the log files
after 1MB.  Then I wrote (on my own time) this patch, which makes it
configurable.

Drawbacks/limitations:

- I let logfwrite() return -1 when it passes the size limit. That
  closes the logfile nicely, but also displays a misleading "log file
  write failed" error message, with a misleading strerror().  I didn't
  want to mess around too much here.

- Integer overflow on some architectures. off_t seems to be signed 32-bit
  on some systems which support larger files.  But off_t was what the code
  already used, so I didn't try to change it.

- I have only tested this a little bit, and only compiled with gcc on
  Linux x86 and AMD64.

Jörgen Grahn
[EMAIL PROTECTED]

Index: logfile.c
===================================================================
RCS file: /home/cvs/screen/logfile.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- logfile.c	12 Jun 2008 21:24:52 -0000	1.1.1.1
+++ logfile.c	23 Jun 2008 20:44:05 -0000	1.3
@@ -31,6 +31,8 @@
 #include "extern.h"
 #include "logfile.h"
 
+extern off_t log_max_size;
+
 static void changed_logfile __P((struct logfile *));
 static struct logfile *lookup_logfile __P((char *));
 static int stolen_logfile __P((struct logfile *));
@@ -158,6 +160,15 @@
   return 0;
 }
 
+static int
+long_logfile(l)
+struct logfile *l;
+{
+  struct stat *s = l->st;
+  return log_max_size && s->st_size > log_max_size;
+}
+
+
 static struct logfile *
 lookup_logfile(name)
 char *name;
@@ -259,6 +270,8 @@
 
   if (stolen_logfile(l) && lf_reopen_fn(l->name, fileno(l->fp), l))
     return -1;
+  if (long_logfile(l))
+    return -1;
   r = fwrite(buf, n, 1, l->fp);
   l->writecount += l->flushcount + 1;
   l->flushcount = 0;
Index: process.c
===================================================================
RCS file: /home/cvs/screen/process.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- process.c	12 Jun 2008 21:24:52 -0000	1.1.1.1
+++ process.c	23 Jun 2008 20:44:05 -0000	1.2
@@ -54,6 +54,7 @@
 extern int captionalways;
 extern char *hardcopydir, *screenlogfile, *logtstamp_string;
 extern int log_flush, logtstamp_on, logtstamp_after;
+extern off_t log_max_size;
 extern char *VisualBellString;
 extern int VBellWait, MsgWait, MsgMinWait, SilenceWait;
 extern char SockPath[], *SockName;
@@ -2392,6 +2393,47 @@
 		Msg(0, "log flush timeout set to %ds\n", log_flush);
 	      break;
 	    }
+	  if (args[1] && !(strcmp(*args, "size")))
+	    {
+	      char * end;
+	      off_t tmp, tmp2;
+	      int badnumber = 0;
+	      tmp = strtoul(args[1], &end, 10);
+	      /* XXX should validate input better, but
+	       * we don't elsewhere (e.g. atoi doesn't).
+	       */
+	      if (!*end)
+		{
+		tmp2 = tmp;
+		}
+	      else if (*end=='k' || *end=='K')
+		tmp2 = tmp * 1024;
+	      else if (*end=='M')
+		tmp2 = tmp * 1024 * 1024;
+	      else if (*end=='G')
+		tmp2 = tmp * 1024 * 1024 * 1024;
+	      else
+		badnumber = 1;
+	      /* pathetic overflow check */
+	      if (badnumber || tmp2 < tmp)
+		{
+		  if (msgok)
+		    Msg(0, "usage: logfile size <size>\n");
+		}
+	      else
+		{
+		  log_max_size = tmp2;
+		  if (msgok)
+		    {
+		      if (log_max_size)
+			Msg(0, "logfile max size set to %lu bytes\n",
+			    (unsigned long)log_max_size);
+		      else
+			Msg(0, "logfile size restriction removed\n");
+		    }
+		}
+	      break;
+	    }
 	  if (ParseSaveStr(act, &screenlogfile) || !msgok)
 	    break;
 	}
Index: screen.c
===================================================================
RCS file: /home/cvs/screen/screen.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- screen.c	12 Jun 2008 21:24:52 -0000	1.1.1.1
+++ screen.c	23 Jun 2008 20:44:05 -0000	1.2
@@ -177,6 +177,7 @@
 
 char *screenlogfile;			/* filename layout */
 int log_flush = 10;           		/* flush interval in seconds */
+off_t log_max_size = 0;		        /* logfile size restriction off */
 int logtstamp_on = 0;			/* tstamp disabled */
 char *logtstamp_string;			/* stamp layout */
 int logtstamp_after = 120;		/* first tstamp after 120s */
Index: doc/screen.1
===================================================================
RCS file: /home/cvs/screen/doc/screen.1,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- doc/screen.1	12 Jun 2008 21:24:52 -0000	1.1.1.1
+++ doc/screen.1	23 Jun 2008 21:40:16 -0000	1.3
@@ -1,5 +1,5 @@
 .\" vi:set wm=5
-.TH SCREEN 1 "Aug 2003"
+.TH SCREEN 1 "Jun 2008"
 .if n .ds Q \&"
 .if n .ds U \&"
 .if t .ds Q ``
@@ -2110,12 +2110,26 @@
 .BI "logfile " filename
 .br
 .BI "logfile flush " secs
+.br
+.BI "logfile size " bytes
 .PP
 Defines the name the logfiles will get. The default is
-\*Qscreenlog.%n\*U. The second form changes the number of seconds
+\*Qscreenlog.%n\*U.
+The second form changes the number of seconds
 .I screen
 will wait before flushing the logfile buffer to the file-system. The
 default value is 10 seconds.
+.PP
+The third form sets a size limit on the log files,
+if you are worried a command may fill the file system with its output.
+The size may be given as a plain number of bytes, or with the suffix
+.BR k , " M " or " G" .
+For example,
+.I "logfile size 100k"
+limits log files to 100 kB.
+.I "logfile size 0"
+turns the limit off.
+Default is off.
 .sp
 .ne 3
 .BR "login " [ on | off ]
Index: doc/screen.texinfo
===================================================================
RCS file: /home/cvs/screen/doc/screen.texinfo,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -r1.1.1.1 -r1.4
--- doc/screen.texinfo	12 Jun 2008 21:24:52 -0000	1.1.1.1
+++ doc/screen.texinfo	23 Jun 2008 21:45:07 -0000	1.4
@@ -7,7 +7,7 @@
 @finalout
 @setchapternewpage odd
 @c %**end of header
[EMAIL PROTECTED] version 4.0.2
[EMAIL PROTECTED] version 4.0.3
 
 @direntry
 * Screen: (screen).             Full-screen window manager.
@@ -52,7 +52,7 @@
 @title Screen
 @subtitle The virtual terminal manager
 @subtitle for Version @value{version}
[EMAIL PROTECTED] Aug 2003
[EMAIL PROTECTED] Jun 2008
 
 @page
 @vskip 0pt plus 1filll
@@ -996,6 +996,12 @@
 Log all output in the current window.  @xref{Log}.
 @item logfile @var{filename}
 Place where to collect logfiles.  @xref{Log}.
[EMAIL PROTECTED] logfile flush @var{seconds}
+Logfile flush interval.  @xref{Log}.
[EMAIL PROTECTED] logfile size @var{bytes}
+Max logfile size.  @xref{Log}.
[EMAIL PROTECTED] logfile @var{filename}
+Place where to collect logfiles.  @xref{Log}.
 @item login [EMAIL PROTECTED]
 Log the window in @file{/etc/utmp}.  @xref{Login}.
 @item logtstamp [EMAIL PROTECTED]
@@ -2888,7 +2894,7 @@
 users.
 If your terminal sends characters, that cause you to abort copy mode,
 then this command may help by binding these characters to do nothing.
-The no-op character is `@' and is used like this: @code{markkeys @@=L=H}
+The no-op character is `@@' and is used like this: @code{markkeys @@=L=H}
 if you do not want to use the `H' or `L' commands any longer. 
 As shown in this example, multiple keys can be assigned to one function
 in a single statement.
@@ -4246,11 +4252,22 @@
 
 @deffn Command logfile filename
 @deffnx Command logfile flush secs
[EMAIL PROTECTED] Command logfile size bytes
 (none)@*
 Defines the name the logfiles will get. The default is @samp{screenlog.%n}.
 The second form changes the number of seconds @code{screen}
 will wait before flushing the logfile buffer to the file-system. The
 default value is 10 seconds.
+
+The third form sets a size limit on the log files,
+if you are worried a command may fill the file system with its output.
+The size may be given as a plain number of bytes, or with the suffix
[EMAIL PROTECTED], @code{M} or @code{G}.
+For example,
[EMAIL PROTECTED] size 100k}
+limits log files to [EMAIL PROTECTED]
[EMAIL PROTECTED] size 0} turns the limit off.
+Default is off.
 @end deffn
 
 @deffn Command logtstamp [state]

Attachment: signature.asc
Description: Digital signature

Reply via email to