Skip Menu |

This queue is for tickets about the PAR-Packer CPAN distribution.

Report information
The Basics
Id: 82916
Status: resolved
Priority: 0/
Queue: PAR-Packer

People
Owner: RSCHUPP [...] cpan.org
Requestors: shutton [...] pobox.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.014
Fixed in: (no value)



Subject: Terminating during unpack results in corrupted cache, failure on next start
If a compiled script is killed while writing out its archive, a partially-written cache file may result (often a short extraction of libperl.so, as that tends to be the largest file in the archive). The present code in myldr/boot.c:extract_embedded_file() is willing to write a missing file, but not overwrite a partially-written file (one where the size in the archive differs from the size on the filesystem), resulting in an abort with a fatal "file exists" error. The attached patch permits the loader to overwrite a corrupt file. I added a warning to stderr to report this condition, but that may or may not be appropriate. It was a useful diagnostic aid for my purposes.
Subject: boot.c.diff
--- boot.c.orig 2013-01-22 14:05:26.000000000 -0800 +++ boot.c.patched 2013-01-23 10:48:44.000000000 -0800 @@ -37,11 +37,21 @@ fd = open(*ext_path, O_CREAT | O_EXCL | O_WRONLY | OPEN_O_BINARY, 0755); if ( fd == -1 ) { struct stat statbuf; - if ( errno == EEXIST - && par_lstat(*ext_path, &statbuf) == 0 - && statbuf.st_size == emb_file->size ) - return 1; /* file already exists and has the expected size */ - return 0; + if ( errno == EEXIST ) { + if ( par_lstat(*ext_path, &statbuf) == 0 + && statbuf.st_size == emb_file->size ) { + return 1; /* file already exists and has the expected size */ + } else { + /* Try to reopen for rewrite */ + fprintf(stderr, "extract_embedded_file(%s): rewriting due to size mismatch\n", *ext_path); + fd = open(*ext_path, O_CREAT | O_WRONLY | OPEN_O_BINARY, 0755); + if ( fd == -1 ) { + return 0; + } + } + } else { + return 0; + } } chunk = emb_file->chunks;
Attached a de-tabbed version of the patch.
Subject: boot.c.diff
--- boot.c.orig 2013-01-22 14:05:26.000000000 -0800 +++ boot.c.patched 2013-01-23 11:01:40.000000000 -0800 @@ -37,11 +37,21 @@ fd = open(*ext_path, O_CREAT | O_EXCL | O_WRONLY | OPEN_O_BINARY, 0755); if ( fd == -1 ) { struct stat statbuf; - if ( errno == EEXIST - && par_lstat(*ext_path, &statbuf) == 0 - && statbuf.st_size == emb_file->size ) - return 1; /* file already exists and has the expected size */ - return 0; + if ( errno == EEXIST ) { + if ( par_lstat(*ext_path, &statbuf) == 0 + && statbuf.st_size == emb_file->size ) { + return 1; /* file already exists and has the expected size */ + } else { + /* Try to reopen for rewrite */ + fprintf(stderr, "extract_embedded_file(%s): rewriting due to size mismatch\n", *ext_path); + fd = open(*ext_path, O_CREAT | O_WRONLY | OPEN_O_BINARY, 0755); + if ( fd == -1 ) { + return 0; + } + } + } else { + return 0; + } } chunk = emb_file->chunks;
I've applied your patch, thanks! Will be in the next release of PAR::Packer. Cheers, Roderich