1

The close() method of Spreadsheet::WriteExcel::Big (v 2.37) package destroys all the standard file descriptor (stdin,stdout and stderr) when run with perl v 5.8.0 i.e. Close() method reset the ^F = 0. But when run with perl 5.8.5 version, ^F is not reset to zero.

As ^F reset to zero So in my program if we open STDOUT then FD_CLOEXEC is set for this fd and its get closed upon exec() calls which cause the error "Bad file descriptor".

open(STDOUT, ">$newfile_ext") or exit 1;
exec('gzip', '-f', '-q',  '-c', $file) or die("Failed to exec gzip: $!\n"); 

Can anyone suggest me why ^F reset to zero on call of close() method and how to fix it ?

Below is attached sample program and its output with perl v 5.8.0 and perl 5.8.5

ExcelTest.pl

#!/usr/bin/perl -w
use strict;
use Spreadsheet::WriteExcel;
use Spreadsheet::WriteExcel::Big;

sub Wrkbk_close_test {
    print "Wrkbk_close_test  ^F : $^F \n";    
    my $workbook = new Spreadsheet::WriteExcel::Big("/tmp/close.xls");
    my $worksheet = $workbook->add_worksheet();    
    $worksheet->write('A1', "Hello");    
    $workbook->close();
    print "Wrkbk_close_test : After close ^F : $^F \n";
}

sub perl_details {
    print "\n    Perl version   : $]";
    print "\n    OS name        : $^O";
    print "\n    Module versions: (not all are required)\n";

    my @modules = qw(
                      Spreadsheet::WriteExcel
                      Spreadsheet::WriteExcel::Big
                      Parse::RecDescent
                      File::Temp
                      OLE::Storage_Lite
                      IO::Stringy
                      Spreadsheet::ParseExcel
                      Scalar::Util
                      Unicode::Map
                    );
    for my $module (@modules) {
        my $version;
        eval "require $module";

        if (not $@) {
            $version = $module->VERSION;
            $version = '(unknown)' if not defined $version;
        }
        else {
            $version = '(not installed)';
        }
        printf "%21s%-24s\t%s\n", "", $module, $version;
    }
}
perl_details;
Wrkbk_close_test;

output V 5.8.0 :

    Perl version   : 5.008
    OS name        : linux
    Module versions: (not all are required)
                     Spreadsheet::WriteExcel    2.37
                     Spreadsheet::WriteExcel::Big       2.37
                     Parse::RecDescent          1.94
                     File::Temp                 0.13
                     OLE::Storage_Lite          0.19
                     IO::Stringy                2.108
                     Spreadsheet::ParseExcel    0.2602
                     Scalar::Util               1.07
                     Unicode::Map               (not installed)
Wrkbk_close_test  ^F : 2
Wrkbk_close_test : After close ^F: 0

output V 5.8.5 :

 Perl version   : 5.008005
    OS name        : linux
    Module versions: (not all are required)
                     Spreadsheet::WriteExcel    2.37
                     Spreadsheet::WriteExcel::Big       2.37
                     Parse::RecDescent          1.94
                     File::Temp                 0.14
                     OLE::Storage_Lite          0.19
                     IO::Stringy                2.108
                     Spreadsheet::ParseExcel    0.2602
                     Scalar::Util               1.14
                     Unicode::Map               (not installed)
Wrkbk_close_test  ^F : 2
Wrkbk_close_test : After close ^F: 2
Miller
  • 34,962
  • 4
  • 39
  • 60
Sumit Kumar
  • 160
  • 1
  • 5

1 Answers1

1

John McNamara, Author of Spreadsheet::WriteExcel module suggested the fix :

Either localise $^F before every call to close() to prevent it getting changed.

   {
       local $^F;
       $workbook->close();
   }

OR localize $^F in close() sub of Workbook.pm file.

The issue appears localized to perl 5.8.0. The above suggestion and more discussion can be seen on the Google forum:

https://groups.google.com/forum/#!searchin/spreadsheet-writeexcel/close%7Csort:date/spreadsheet-writeexcel/ugcA9hUu7ao/O1euij5f4BcJ

Miller
  • 34,962
  • 4
  • 39
  • 60
Sumit Kumar
  • 160
  • 1
  • 5