Commit d545a160 authored by eric@webkit.org's avatar eric@webkit.org

Reviewed by weinig.

        Add Content-Type support to DumpRenderTree and run-webkit-tests
        and move expected.txt files to expected.webarchive

        https://bugs.webkit.org/show_bug.cgi?id=15565

        * DumpRenderTree/cg/ImageDiffCG.cpp:
        (compareImages):
        (main):
        * DumpRenderTree/cg/PixelDumpSupportCG.cpp:
        (printPNG):
        * DumpRenderTree/mac/DumpRenderTree.mm:
        (dump):
        * Scripts/run-webkit-tests:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@35076 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9fcac210
2008-07-09 Eric Seidel <eric@webkit.org>
Reviewed by weinig.
Add Content-Type support to DumpRenderTree and run-webkit-tests
and move expected.txt files to expected.webarchive
https://bugs.webkit.org/show_bug.cgi?id=15565
* svg/custom/image-with-prefix-in-webarchive-expected.webarchive: Renamed from LayoutTests/svg/custom/image-with-prefix-in-webarchive-expected.txt.
* svg/webarchive/svg-cursor-subresources-expected.webarchive: Renamed from LayoutTests/svg/webarchive/svg-cursor-subresources-expected.txt.
* svg/webarchive/svg-feimage-subresources-expected.webarchive: Renamed from LayoutTests/svg/webarchive/svg-feimage-subresources-expected.txt.
* svg/webarchive/svg-script-subresouces-expected.webarchive: Renamed from LayoutTests/svg/webarchive/svg-script-subresouces-expected.txt.
* webarchive/archive-empty-frame-dom-expected.webarchive: Renamed from LayoutTests/webarchive/archive-empty-frame-dom-expected.txt.
* webarchive/archive-empty-frame-source-expected.webarchive: Renamed from LayoutTests/webarchive/archive-empty-frame-source-expected.txt.
* webarchive/archive-with-unencoded-url-expected.webarchive: Renamed from LayoutTests/webarchive/archive-with-unencoded-url-expected.txt.
* webarchive/doctype-expected.webarchive: Renamed from LayoutTests/webarchive/doctype-expected.txt.
* webarchive/test-body-background-expected.webarchive: Renamed from LayoutTests/webarchive/test-body-background-expected.txt.
* webarchive/test-css-import-expected.webarchive: Renamed from LayoutTests/webarchive/test-css-import-expected.txt.
* webarchive/test-duplicate-resources-expected.webarchive: Renamed from LayoutTests/webarchive/test-duplicate-resources-expected.txt.
* webarchive/test-frameset-expected.webarchive: Renamed from LayoutTests/webarchive/test-frameset-expected.txt.
* webarchive/test-img-src-expected.webarchive: Renamed from LayoutTests/webarchive/test-img-src-expected.txt.
* webarchive/test-input-src-expected.webarchive: Renamed from LayoutTests/webarchive/test-input-src-expected.txt.
* webarchive/test-link-href-expected.webarchive: Renamed from LayoutTests/webarchive/test-link-href-expected.txt.
* webarchive/test-object-data-expected.webarchive: Renamed from LayoutTests/webarchive/test-object-data-expected.txt.
* webarchive/test-script-src-expected.webarchive: Renamed from LayoutTests/webarchive/test-script-src-expected.txt.
* webarchive/test-table-background-expected.webarchive: Renamed from LayoutTests/webarchive/test-table-background-expected.txt.
* webarchive/test-td-background-expected.webarchive: Renamed from LayoutTests/webarchive/test-td-background-expected.txt.
* webarchive/test-xml-stylesheet-expected.txt: Removed.
* webarchive/test-xml-stylesheet-expected.webarchive: Copied from LayoutTests/platform/mac-leopard/webarchive/test-xml-stylesheet-expected.txt.
2008-07-09 Rob Buis <buis@kde.org>
Reviewed by Eric.
......@@ -5,20 +5,21 @@
<key>WebMainResource</key>
<dict>
<key>WebResourceData</key>
<data>
PD94bWwtc3R5bGVzaGVldCBocmVmPSJyZXNvdXJjZXMvdGVzdC14bWwtc3R5
bGVzaGVldC5jc3MiIHR5cGU9InRleHQvY3NzIj8+PGh0bWwgeG1sbnM9Imh0
dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgogIDxzY3JpcHQ+CiAgICBp
ZiAod2luZG93LmxheW91dFRlc3RDb250cm9sbGVyKQogICAgICAgIGxheW91
dFRlc3RDb250cm9sbGVyLmR1bXBET01Bc1dlYkFyY2hpdmUoKTsKICA8L3Nj
cmlwdD4KICA8c3R5bGU+CiAgICBkaXYgeyBiYWNrZ3JvdW5kOiByZWQ7IHdp
ZHRoOiAxMDBweDsgaGVpZ2h0OiAxMDBweDsgfQogIDwvc3R5bGU+CiAgPGRp
diBpZD0idGVzdCI+CiAgPC9kaXY+CjwvaHRtbD4=
</data>
<string>&lt;?xml-stylesheet href="resources/test-xml-stylesheet.css" type="text/css"?&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;script&gt;
if (window.layoutTestController)
layoutTestController.dumpDOMAsWebArchive();
&lt;/script&gt;
&lt;style&gt;
div { background: red; width: 100px; height: 100px; }
&lt;/style&gt;
&lt;div id="test"&gt;
&lt;/div&gt;
&lt;/html&gt;</string>
<key>WebResourceFrameName</key>
<string></string>
<key>WebResourceMIMEType</key>
<string>application/xml</string>
<string>text/xml</string>
<key>WebResourceTextEncodingName</key>
<string>UTF-8</string>
<key>WebResourceURL</key>
......
2008-07-09 Eric Seidel <eric@webkit.org>
Reviewed by weinig.
Add Content-Type support to DumpRenderTree and run-webkit-tests
and move expected.txt files to expected.webarchive
https://bugs.webkit.org/show_bug.cgi?id=15565
* DumpRenderTree/cg/ImageDiffCG.cpp:
(compareImages):
(main):
* DumpRenderTree/cg/PixelDumpSupportCG.cpp:
(printPNG):
* DumpRenderTree/mac/DumpRenderTree.mm:
(dump):
* Scripts/run-webkit-tests:
2008-07-08 Jon Honeycutt <jhoneycutt@apple.com>
Reviewed by Anders.
......
......@@ -147,7 +147,7 @@ static void compareImages(CGImageRef actualBitmap, CGImageRef baselineBitmap, un
RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0));
CGImageDestinationAddImage(imageDest.get(), image.get(), 0);
CGImageDestinationFinalize(imageDest.get());
printf("Content-length: %lu\n", CFDataGetLength(imageData.get()));
printf("Content-Length: %lu\n", CFDataGetLength(imageData.get()));
fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout);
fprintf(stdout, "diff: %01.2f%% failed\n", percentage);
} else
......@@ -183,7 +183,7 @@ int main(int argc, const char* argv[])
if (newLineCharacter)
*newLineCharacter = '\0';
if (!strncmp("Content-length: ", buffer, 16)) {
if (!strncmp("Content-Length: ", buffer, 16)) {
strtok(buffer, " ");
int imageSize = strtol(strtok(0, " "), 0, 10);
......
......@@ -55,7 +55,7 @@ static void printPNG(CGImageRef image)
RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0));
CGImageDestinationAddImage(imageDest.get(), image, 0);
CGImageDestinationFinalize(imageDest.get());
printf("Content-length: %lu\n", CFDataGetLength(imageData.get()));
printf("Content-Length: %lu\n", CFDataGetLength(imageData.get()));
fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout);
}
......
......@@ -823,6 +823,7 @@ void dump()
if (dumpTree) {
NSString *resultString = nil;
NSData *resultData = nil;
NSString *resultMimeType = @"text/plain";
bool dumpAsText = layoutTestController->dumpAsText();
dumpAsText |= [[[mainFrame dataSource] _responseMIMEType] isEqualToString:@"text/plain"];
......@@ -832,9 +833,11 @@ void dump()
} else if (layoutTestController->dumpDOMAsWebArchive()) {
WebArchive *webArchive = [[mainFrame DOMDocument] webArchive];
resultString = serializeWebArchiveToXML(webArchive);
resultMimeType = @"application/x-webarchive";
} else if (layoutTestController->dumpSourceAsWebArchive()) {
WebArchive *webArchive = [[mainFrame dataSource] webArchive];
resultString = serializeWebArchiveToXML(webArchive);
resultMimeType = @"application/x-webarchive";
} else {
sizeWebViewForCurrentTest();
resultString = [mainFrame renderTreeAsExternalRepresentation];
......@@ -843,6 +846,8 @@ void dump()
if (resultString && !resultData)
resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding];
printf("Content-Type: %s\n", [resultMimeType UTF8String]);
if (resultData) {
fwrite([resultData bytes], 1, [resultData length], stdout);
......
......@@ -98,6 +98,7 @@ sub epiloguesAndPrologues($$);
sub parseLeaksandPrintUniqueLeaks();
sub readFromDumpToolWithTimer(*;$);
sub setFileHandleNonBlocking(*$);
sub writeToFile($$);
# Argument handling
my $addPlatformExceptions = 0;
......@@ -478,7 +479,7 @@ $SIG{"PIPE"} = "catch_pipe";
print "Testing ", scalar @tests, " test cases.\n";
my $overallStartTime = time;
my %expectedResultDirectory;
my %expectedResultPaths;
# Reverse the tests
@tests = reverse @tests if $reverseTests;
......@@ -493,6 +494,7 @@ for my $test (@tests) {
openDumpTool();
my $base = stripExtension($test);
my $expectedExtension = ".txt";
my $dir = $base;
$dir =~ s|/[^/]+$||;
......@@ -568,6 +570,9 @@ for my $test (@tests) {
my $actual = $actualRead->{output};
my $error = $errorRead->{output};
$expectedExtension = $actualRead->{extension};
my $expectedFileName = "$base-$expectedTag.$expectedExtension";
unless ($actualRead->{status} eq "success" && $errorRead->{status} eq "success") {
my $crashed = $actualRead->{status} eq "crashed" || $errorRead->{status} eq "crashed";
testCrashedOrTimedOut($test, $base, $crashed, $actual, $error);
......@@ -580,10 +585,10 @@ for my $test (@tests) {
$durations{$test} = time - $startTime if $report10Slowest;
my $expected;
my $expectedDir = expectedDirectoryForTest($base, $isText, 0);
$expectedResultDirectory{$base} = $expectedDir;
my $expectedDir = expectedDirectoryForTest($base, $isText, $expectedExtension);
$expectedResultPaths{$base} = "$expectedDir/$expectedFileName";
if (!$resetResults && open EXPECTED, "<", "$expectedDir/$base-$expectedTag.txt") {
if (!$resetResults && open EXPECTED, "<", "$expectedDir/$expectedFileName") {
$expected = "";
while (<EXPECTED>) {
next if $stripEditingCallbacks && $_ =~ /^EDITING DELEGATE:/;
......@@ -593,7 +598,7 @@ for my $test (@tests) {
}
my $expectedMac;
if (!isOSX() && $strictTesting && !$isText) {
if (!$resetResults && open EXPECTED, "<", "$testDirectory/platform/mac/$base-$expectedTag.txt") {
if (!$resetResults && open EXPECTED, "<", "$testDirectory/platform/mac/$expectedFileName") {
$expectedMac = "";
while (<EXPECTED>) {
$expectedMac .= $_;
......@@ -612,7 +617,7 @@ for my $test (@tests) {
my $diffResult = "passed";
if ($pixelTests) {
my $expectedPixelDir = expectedDirectoryForTest($base, $isText, 1);
my $expectedPixelDir = expectedDirectoryForTest($base, $isText, "png");
my $actualHash = "";
my $expectedHash = "";
......@@ -624,7 +629,7 @@ for my $test (@tests) {
$actualHash = $1;
} elsif (/BaselineHash: ([a-f0-9]{32})/) {
$expectedHash = $1;
} elsif (/Content-length: (\d+)\s*/) {
} elsif (/Content-Length: (\d+)\s*/) {
$actualPNGSize = $1;
read(IN, $actualPNG, $actualPNGSize);
}
......@@ -636,15 +641,15 @@ for my $test (@tests) {
open EXPECTEDPNG, "$expectedPixelDir/$base-$expectedTag.png";
read(EXPECTEDPNG, $expectedPNG, $expectedPNGSize);
print DIFFOUT "Content-length: $actualPNGSize\n";
print DIFFOUT "Content-Length: $actualPNGSize\n";
print DIFFOUT $actualPNG;
print DIFFOUT "Content-length: $expectedPNGSize\n";
print DIFFOUT "Content-Length: $expectedPNGSize\n";
print DIFFOUT $expectedPNG;
while (<DIFFIN>) {
last if /^error/ || /^diff:/;
if (/Content-length: (\d+)\s*/) {
if (/Content-Length: (\d+)\s*/) {
read(DIFFIN, $diffPNG, $1);
}
}
......@@ -658,16 +663,12 @@ for my $test (@tests) {
if ($actualPNGSize && ($resetResults || !-f "$expectedPixelDir/$base-$expectedTag.png")) {
mkpath catfile($expectedPixelDir, dirname($base)) if $testDirectory ne $expectedPixelDir;
open EXPECTED, ">", "$expectedPixelDir/$base-expected.png" or die "could not create $expectedPixelDir/$base-expected.png\n";
print EXPECTED $actualPNG;
close EXPECTED;
writeToFile("$expectedPixelDir/$base-$expectedTag.png", $actualPNG);
}
# update the expected hash if the image diff said that there was no difference
if ($actualHash ne "" && ($resetResults || !-f "$expectedPixelDir/$base-$expectedTag.checksum")) {
open EXPECTED, ">", "$expectedPixelDir/$base-$expectedTag.checksum" or die "could not create $expectedPixelDir/$base-$expectedTag.checksum\n";
print EXPECTED $actualHash;
close EXPECTED;
writeToFile("$expectedPixelDir/$base-$expectedTag.checksum", $actualHash);
}
}
......@@ -708,12 +709,8 @@ for my $test (@tests) {
$expectedMac =~ s/\s+"\n/"\n/g;
if ($simplified_actual ne $expectedMac) {
open ACTUAL, ">", "/tmp/actual.txt" or die;
print ACTUAL $simplified_actual;
close ACTUAL;
open ACTUAL, ">", "/tmp/expected.txt" or die;
print ACTUAL $expectedMac;
close ACTUAL;
writeToFile("/tmp/actual.txt", $simplified_actual);
writeToFile("/tmp/expected.txt", $expectedMac);
system "diff -u \"/tmp/expected.txt\" \"/tmp/actual.txt\" > \"/tmp/simplified.diff\"";
$diffResult = "failed";
......@@ -738,9 +735,7 @@ for my $test (@tests) {
if ($generateNewResults || $resetResults) {
mkpath catfile($expectedDir, dirname($base)) if $testDirectory ne $expectedDir;
open EXPECTED, ">", "$expectedDir/$base-$expectedTag.txt" or die "could not create $expectedDir/$base-$expectedTag.txt\n";
print EXPECTED $actual;
close EXPECTED;
writeToFile("$expectedDir/$expectedFileName", $actual);
}
deleteExpectedAndActualResults($base);
unless ($resetResults) {
......@@ -773,10 +768,8 @@ for my $test (@tests) {
my $expectedResultIsMaximallyPlatformSpecific = $expectedBase =~ m|^\Q$platformTestDirectory\E/|;
if (!$testIsMaximallyPlatformSpecific && !$expectedResultIsMaximallyPlatformSpecific) {
mkpath catfile($platformTestDirectory, dirname($base));
my $expectedFile = catfile($platformTestDirectory, "$base-$expectedTag.txt");
open EXPECTED, ">", $expectedFile or die "could not create $expectedFile\n";
print EXPECTED $actual;
close EXPECTED;
my $expectedFile = catfile($platformTestDirectory, "$expectedFileName");
writeToFile("$expectedFile", $actual);
$message .= " (results generated in $platformTestDirectory)";
}
}
......@@ -794,15 +787,10 @@ for my $test (@tests) {
if ($pixelTests && $diffPNG && $diffPNG ne "") {
$imagesPresent{$base} = 1;
open ACTUAL, ">", "$testResultsDirectory/$base-$actualTag.png" or die;
print ACTUAL $actualPNG;
close ACTUAL;
open DIFF, ">", "$testResultsDirectory/$base-$diffsTag.png" or die;
print DIFF $diffPNG;
close DIFF;
writeToFile("$testResultsDirectory/$base-$actualTag.png", $actualPNG);
writeToFile("$testResultsDirectory/$base-$diffsTag.png", $diffPNG);
my $expectedPixelDir = expectedDirectoryForTest($base, $isText, 1);
my $expectedPixelDir = expectedDirectoryForTest($base, $isText, "png");
copy("$expectedPixelDir/$base-$expectedTag.png", "$testResultsDirectory/$base-$expectedTag.png");
open DIFFHTML, ">$testResultsDirectory/$base-$diffsTag.html" or die;
......@@ -855,9 +843,7 @@ for my $test (@tests) {
$dir =~ s|/([^/]+)$|| or die "Failed to find test name from base\n";
mkpath $dir;
open ERROR_OUT, ">", "$testResultsDirectory/$base-$errorTag.txt" or die;
print ERROR_OUT $error;
close ERROR_OUT;
writeToFile("$testResultsDirectory/$base-$errorTag.txt", $error);
$counts{error}++;
push @{$tests{error}}, $test;
......@@ -1063,9 +1049,7 @@ sub countAndPrintLeaks($$$)
print " + $count leaks ($bytes bytes) were found, details in $leaksFilePath\n";
}
open LEAKS, ">", $leaksFilePath or die;
print LEAKS $leaksOutput;
close LEAKS;
writeToFile($leaksFilePath, $leaksOutput);
push( @leaksFilenames, $leaksFilePath );
}
......@@ -1073,6 +1057,14 @@ sub countAndPrintLeaks($$$)
return $adjustedCount;
}
sub writeToFile($$)
{
my ($filePath, $contents) = @_;
open NEWFILE, ">", "$filePath" or die "could not create $filePath\n";
print NEWFILE $contents;
close NEWFILE;
}
# Break up a path into the directory (with slash) and base name.
sub splitpath($)
{
......@@ -1357,21 +1349,15 @@ sub isTextOnlyTest($)
sub expectedDirectoryForTest($;$;$)
{
my ($base, $isText, $isPixelTest) = @_;
my ($base, $isText, $expectedExtension) = @_;
my @directories = @platformHierarchy;
push @directories, map { catdir($platformBaseDirectory, $_) } qw(mac-leopard mac) if isCygwin();
push @directories, $expectedDirectory;
# If we already have expected results, just return their location.
if ($isPixelTest) {
foreach my $directory (@directories) {
return $directory if (-f "$directory/$base-$expectedTag.png");
}
} else {
foreach my $directory (@directories) {
return $directory if (-f "$directory/$base-$expectedTag.txt");
}
foreach my $directory (@directories) {
return $directory if (-f "$directory/$base-$expectedTag.$expectedExtension");
}
# For platform-specific tests, the results should go right next to the test itself.
......@@ -1426,9 +1412,7 @@ sub testCrashedOrTimedOut($$$$$) {
deleteExpectedAndActualResults($base);
if (defined($error) && length($error)) {
open CRASH, ">", "$testResultsDirectory/$base-$errorTag.txt" or die;
print CRASH $error;
close CRASH;
writeToFile("$testResultsDirectory/$base-$errorTag.txt", $error);
}
recordActualResultsAndDiff($base, $actual);
......@@ -1552,9 +1536,12 @@ sub linksForExpectedAndActualResults($)
my @links = ();
return \@links unless -s "$testResultsDirectory/$base-$diffsTag.txt";
my $expectedResultPath = $expectedResultPaths{$base};
my ($expectedResultFileName, $expectedResultsDirectory, $expectedResultExtension) = fileparse($expectedResultPath, qr{\.[^.]+$});
push @links, { href => "$base-$expectedTag.txt", text => "expected" };
push @links, { href => "$base-$actualTag.txt", text => "actual" };
push @links, { href => "$base-$expectedTag$expectedResultExtension", text => "expected" };
push @links, { href => "$base-$actualTag$expectedResultExtension", text => "actual" };
push @links, { href => "$base-$diffsTag.txt", text => "diffs" };
return \@links;
......@@ -1599,11 +1586,12 @@ sub linksForNewTest
my @links = ();
my $base = stripExtension($test);
my $expectedDir = $expectedResultDirectory{$base};
my $expectedResultPath = $expectedResultPaths{$base};
my $expectedResultPathMinusExtension = stripExtension($expectedResultPath);
push @links, { href => toURL("$expectedDir/$base-$expectedTag.txt"), text => "results" };
if ($pixelTests && -f "$expectedDir/$base-$expectedTag.png") {
push @links, { href => toURL("$expectedDir/$base-$expectedTag.png"), text => "image" };
push @links, { href => toURL($expectedResultPath), text => "results" };
if ($pixelTests && -f "$expectedResultPathMinusExtension.png") {
push @links, { href => toURL("$expectedResultPathMinusExtension.png"), text => "image" };
}
return \@links;
......@@ -1620,18 +1608,19 @@ sub deleteExpectedAndActualResults($)
sub recordActualResultsAndDiff($$)
{
my ($base, $actual) = @_;
my ($base, $actualResults) = @_;
return unless defined($actual) && length($actual);
open ACTUAL, ">", "$testResultsDirectory/$base-$actualTag.txt" or die "Couldn't open actual results file for $base";
print ACTUAL $actual;
close ACTUAL;
return unless defined($actualResults) && length($actualResults);
my $expectedResultPath = $expectedResultPaths{$base};
my ($expectedResultFileNameMinusExtension, $expectedResultDirectoryPath, $expectedResultExtension) = fileparse($expectedResultPath, qr{\.[^.]+$});
my $expectedResultFileName = "$expectedResultFileNameMinusExtension$expectedResultExtension";
my $expectedDir = $expectedResultDirectory{$base};
copy("$expectedDir/$base-$expectedTag.txt", "$testResultsDirectory/$base-$expectedTag.txt");
my $actualResultsPath = "$testResultsDirectory/$base-$actualTag$expectedResultExtension";
writeToFile("$actualResultsPath", $actualResults);
copy("$expectedResultPath", "$testResultsDirectory/$expectedResultFileName");
system "diff -u \"$testResultsDirectory/$base-$expectedTag.txt\" \"$testResultsDirectory/$base-$actualTag.txt\" > \"$testResultsDirectory/$base-$diffsTag.txt\"";
system "diff -u \"$testResultsDirectory/$expectedResultFileName\" \"$actualResultsPath\" > \"$testResultsDirectory/$base-$diffsTag.txt\"";
}
sub buildPlatformHierarchy()
......@@ -1707,6 +1696,18 @@ sub parseLeaksandPrintUniqueLeaks() {
}
sub extensionForMimeType($)
{
my ($mimeType) = @_;
if ($mimeType eq "application/x-webarchive") {
return "webarchive";
} elsif ($mimeType eq "application/pdf") {
return "pdf";
}
return "txt";
}
sub readFromDumpToolWithTimer(*;$)
{
my ($fh, $dontWaitForTimeOut) = @_;
......@@ -1721,6 +1722,10 @@ sub readFromDumpToolWithTimer(*;$)
my @output = ();
my $status = "success";
my $mimeType = "text/plain";
# We don't have a very good way to know when the "headers" stop
# and the content starts, so we use this as a hack:
my $haveSeenContentType = 0;
while (1) {
if (time - $timeOfLastSuccessfulRead > $maximumSecondsWithoutOutput) {
......@@ -1744,14 +1749,25 @@ sub readFromDumpToolWithTimer(*;$)
next;
}
last if $line =~ /#EOF/;
push @output, $line;
$timeOfLastSuccessfulRead = time;
if (!$haveSeenContentType && $line =~ /^Content-Type: (\S+)$/) {
$mimeType = $1;
$haveSeenContentType = 1;
next;
}
last if ($line =~ /#EOF/);
push @output, $line;
}
setFileHandleNonBlocking($fh, 0);
return { output => join("", @output), status => $status };
return {
output => join("", @output),
status => $status,
mimeType => $mimeType,
extension => extensionForMimeType($mimeType)
};
}
sub setFileHandleNonBlocking(*$)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment