Index: tools/scan-build/ccc-analyzer =================================================================== --- tools/scan-build/ccc-analyzer +++ tools/scan-build/ccc-analyzer @@ -136,7 +136,10 @@ SUFFIX => GetPPExt($Lang), DIR => $Dir); close ($PPH); - system $Clang, @$Args, "-E", "-o", $PPFile; + my $ExecLine = join(' ', qq/"$Clang"/, @{PrepareArgs($Args)}, "-E", "-o", $PPFile, "2>&1", "|"); + open(PS, $ExecLine); + while ( ) {} + close PS; # Create the info file. open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n"; @@ -145,7 +148,7 @@ print OUT "@$Args\n"; close OUT; `uname -a >> $PPFile.info.txt 2>&1`; - `$Compiler -v >> $PPFile.info.txt 2>&1`; + `"$Compiler" -v >> $PPFile.info.txt 2>&1`; rename($ofile, "$PPFile.stderr.txt"); return (basename $PPFile); } @@ -154,27 +157,28 @@ # Running the analyzer. ##----------------------------------------------------------------------------## +sub PrepareArgs { + my $Args = shift; + my @TempArgs = @$Args; + foreach (@TempArgs) { + $_ =~ s/"/\\"/g; + $_ = qq/"$_"/; + } + return \@TempArgs; +} + sub GetCCArgs { my $mode = shift; my $Args = shift; - pipe (FROM_CHILD, TO_PARENT); - my $pid = fork(); - if ($pid == 0) { - close FROM_CHILD; - open(STDOUT,">&", \*TO_PARENT); - open(STDERR,">&", \*TO_PARENT); - exec $Clang, "-###", $mode, @$Args; - } - close(TO_PARENT); my $line; - while () { + my $ExecLine = join(' ', qq/"$Clang"/, "-###", $mode, @{PrepareArgs($Args)}, "2>&1", "|"); + open(PS, $ExecLine); + while ( ) { next if (!/\s"?-cc1"?\s/); $line = $_; } - - waitpid($pid,0); - close(FROM_CHILD); + close PS; die "could not find clang line\n" if (!defined $line); # Strip leading and trailing whitespace characters. @@ -255,31 +259,21 @@ print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n"; } - # Capture the STDERR of clang and send it to a temporary file. - # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR. + # Save STDOUT and STDERR of clang to a temporary file and reroute + # all clang output to ccc-analyzer's STDERR. # We save the output file in the 'crashes' directory if clang encounters # any problems with the file. - pipe (FROM_CHILD, TO_PARENT); - my $pid = fork(); - if ($pid == 0) { - close FROM_CHILD; - open(STDOUT,">&", \*TO_PARENT); - open(STDERR,">&", \*TO_PARENT); - exec $Cmd, @CmdArgs; - } - - close TO_PARENT; my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir); - while () { + my $ExecLine = join(' ', qq/"$Cmd"/, @{PrepareArgs(\@CmdArgs)}, "2>&1", "|"); + open(PS, $ExecLine); + while ( ) { print $ofh $_; print STDERR $_; } - close $ofh; - - waitpid($pid,0); - close(FROM_CHILD); + close PS; my $Result = $?; + close $ofh; # Did the command die because of a signal? if ($ReportFailures) { @@ -446,11 +440,21 @@ my %Uniqued; # Forward arguments to gcc. -my $Status = system($Compiler,@ARGV); -if (defined $ENV{'CCC_ANALYZER_LOG'}) { - print STDERR "$Compiler @ARGV\n"; +{ + my $PreparedARGV = PrepareArgs(\@ARGV); + my $ExecLine = join(' ', qq/"$Compiler"/, @{$PreparedARGV}, "|"); + open(PS, $ExecLine); + while ( ) { + print $_; + } + close PS; + my $Status = $?; + + if (defined $ENV{'CCC_ANALYZER_LOG'}) { + print STDERR "$Compiler @{$PreparedARGV}\n"; + } + if ($Status) { exit($Status >> 8); } } -if ($Status) { exit($Status >> 8); } # Get the analysis options. my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'}; Index: tools/scan-build/scan-build =================================================================== --- tools/scan-build/scan-build +++ tools/scan-build/scan-build @@ -1232,16 +1232,9 @@ } my %EnabledCheckers; foreach my $lang ("c", "objective-c", "objective-c++", "c++") { - pipe(FROM_CHILD, TO_PARENT); - my $pid = fork(); - if ($pid == 0) { - close FROM_CHILD; - open(STDOUT,">&", \*TO_PARENT); - open(STDERR,">&", \*TO_PARENT); - exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###'); - } - close(TO_PARENT); - while() { + my $ExecLine = join(' ', qq/"$Clang"/, @PluginLoadCommandline_xclang, "--analyze", "-x", $lang, "-", "-###", "2>&1", "|"); + open(PS, $ExecLine); + while () { foreach my $val (split /\s+/) { $val =~ s/\"//g; if ($val =~ /-analyzer-checker\=([^\s]+)/) { @@ -1249,23 +1242,14 @@ } } } - waitpid($pid,0); - close(FROM_CHILD); } # Query clang for complete list of checkers. if (defined $Clang && -x $Clang) { - pipe(FROM_CHILD, TO_PARENT); - my $pid = fork(); - if ($pid == 0) { - close FROM_CHILD; - open(STDOUT,">&", \*TO_PARENT); - open(STDERR,">&", \*TO_PARENT); - exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help'); - } - close(TO_PARENT); + my $ExecLine = join(' ', qq/"$Clang"/, "-cc1", @PluginsToLoad, "-analyzer-checker-help", "2>&1", "|"); + open(PS, $ExecLine); my $foundCheckers = 0; - while() { + while () { if (/CHECKERS:/) { $foundCheckers = 1; last; @@ -1277,7 +1261,7 @@ else { print("\nAVAILABLE CHECKERS:\n\n"); my $skip = 0; - while() { + while() { if (/experimental/) { $skip = 1; next; @@ -1314,10 +1298,9 @@ } print $_; } - print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n" + print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n"; } - waitpid($pid,0); - close(FROM_CHILD); + close PS; } print <