One of my users managed to hose up my gate hooks a few weeks back.  For our
project I wanted to have the gate hooks enforce a few things such as the first
line of the cset comments, only one head, ...and cstyle.  It's easy to enforce
the cstyle rules, given the way our source tree is set up.

This one user tried to push a file that was formatted to a very different
cstyle.  We discovered that if the file is large enough, 1900 lines and 65K in
this case, and generates enough cstyle output, 2550 lines and 217K in this
case, then cadmium and cstyle will hit a deadlock.  Cadmium will be attempting
to write to p.stdin.write() while cstyle is also writing, and neither is
reading.  We see this only when cstyle is being run by my gate hooks, via a
push over ssh.

For the gate's purposes, it seems reasonable that cstyle does not need to
print any output.  It just needs to exit on the first warning.

I've included a change to cstyle.pl to add a -e option to exit on the first
warning, and a change to CStyle.pl to gracefully handle the early closing of
the pipe.  These changes allow my gate hooks to survive the type of abuse I've
described above.

Dean



Index: webrev/usr/src/tools/scripts/cstyle.pl
===================================================================
--- webrev.orig/usr/src/tools/scripts/cstyle.pl 2008-06-20 10:53:52.000000000 
-0500
+++ webrev/usr/src/tools/scripts/cstyle.pl      2008-06-20 10:56:22.295016000 
-0500
@@ -56,8 +56,9 @@ use Getopt::Std;
 use strict;
 
 my $usage =
-"usage: cstyle [-chpvCP] [-o constructs] file ...
+"usage: cstyle [-chpvCPe] [-o constructs] file ...
        -c      check continuation indentation inside functions
+       -e      exit at first warning
        -h      perform heuristic checks that are sometimes wrong
        -p      perform some of the more picky checks
        -v      verbose
@@ -71,7 +72,7 @@ my $usage =
 
 my %opts;
 
-if (!getopts("cho:pvCP", \%opts)) {
+if (!getopts("cho:pvCPe", \%opts)) {
        print $usage;
        exit 2;
 }
@@ -82,6 +83,7 @@ my $picky = $opts{'p'};
 my $verbose = $opts{'v'};
 my $ignore_hdr_comment = $opts{'C'};
 my $check_posix_types = $opts{'P'};
+my $exit_first_warning = $opts{'e'};
 
 my $doxygen_comments = 0;
 my $splint_comments = 0;
@@ -192,6 +194,7 @@ sub err($) {
        unless ($no_errs) {
                printf $fmt, $filename, $., $error, $line;
                $err_stat = 1;
+               exit 1 if $exit_first_warning;
        }
 }
 
@@ -201,6 +204,7 @@ sub err_prefix($$) {
        unless ($no_errs) {
                printf $fmt, $filename, $., $error, $out;
                $err_stat = 1;
+               exit 1 if $exit_first_warning;
        }
 }
 
@@ -209,6 +213,7 @@ sub err_prev($) {
        unless ($no_errs) {
                printf $fmt, $filename, $. - 1, $error, $prev;
                $err_stat = 1;
+               exit 1 if $exit_first_warning;
        }
 }
 
Index: webrev/usr/src/tools/onbld/Checks/CStyle.py
===================================================================
--- webrev.orig/usr/src/tools/onbld/Checks/CStyle.py    2008-06-20 
10:58:16.000000000 -0500
+++ webrev/usr/src/tools/onbld/Checks/CStyle.py 2008-06-20 10:59:20.907213000 
-0500
@@ -42,7 +42,8 @@ def cstyle(fh, filename=None, output=sys
                'ignore_hdr_comment': '-C',
                'check_posix_types': '-P',
                'doxygen_comments': '-o doxygen',
-               'splint_comments': '-o splint'}
+               'splint_comments': '-o splint',
+               'exit_first_warning': '-e'}
 
     options = [opttrans[x] for x in opts]
     
@@ -57,13 +58,17 @@ def cstyle(fh, filename=None, output=sys
         print >> sys.stderr, "Could not execute cstyle: %s" % e
         sys.exit(3)
 
-    for line in fh:
-        p.stdin.write(line)
-    p.stdin.close()           # Close the input, or we deadlock
-
-    for line in p.stdout:
-        line = line.replace('<stdin>', filename)
-        output.write(line)
+    try:
+        for line in fh:
+            p.stdin.write(line)
+        p.stdin.close()           # Close the input, or we deadlock
+
+        for line in p.stdout:
+            line = line.replace('<stdin>', filename)
+            output.write(line)
+
+    except:
+        pass
 
     ret = p.wait()
     if ret < 0:

Reply via email to