Dir->rcopy invalid dirhandle

  • Hello everybody,


    I tried to create an listener-file using the Dir - rcopy - Function. Unfortunately it always gives me a warning like the one listed below:



    Code
    1. iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /usr/local/src/imscp-1.2.8/engine/PerlLib/iMSCP/Dir.pm line 312.


    It seems this is thrown when the loop is leaving the directory after the files and subfolders have been copied correctly. Does anybody know how to get rid of this warning?


    Regards Jörg

    Files

    (Ubuntu 16.04, i-MSCP 1.5.1, php-Fpm, Plugins: ClamAV, CronJobs, InstantSSH, LetsEncrypt, Mailgraph, Monitorix, OpenDKIM, PhpSwitcher, PolicydSPF, Postscreen, RecaptchaPMA, RoundcubePlugins, ServerDefaultPage, SpamAssassin, YubiKeyAuth)

    Edited once, last by UncleJ ().

  • Hello ;


    Show us your code please.

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206

  • I attached the code file to my original post.

    (Ubuntu 16.04, i-MSCP 1.5.1, php-Fpm, Plugins: ClamAV, CronJobs, InstantSSH, LetsEncrypt, Mailgraph, Monitorix, OpenDKIM, PhpSwitcher, PolicydSPF, Postscreen, RecaptchaPMA, RoundcubePlugins, ServerDefaultPage, SpamAssassin, YubiKeyAuth)

  • @UncleJ



    Your code



    First thing: You define the listener with prototype (sub CopyOwnTemplates($)) but listeners which listen on the afterInstall event doesn't receive any argument.


    Second thing: what is that second argument ---> -rf passed to the rcopy() method? The iMSCP::Dir::rcopy() method take two parameters. The firt is the target directory (where the directory must be copied), and the second which is OPTIONAL should be an hashref which can have the following keys/values:

    • excludeDir: A string representing a regexp for list of directory to exclude from the copy
    • excludeFile: A string representing a regexp for list of files to exclude from the copy
    • preserve: If defined and not equal to 'no', copy file attributes (uid, gid and mode)

    Anyway, I'll try your code which could works at first looking. I'll also rewrite thad iMSCP::Dir library.

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206

  • @UncleJ


    Bug confirmed.


    I've tested with the following test script:


    Perl
    1. #!/usr/bin/perluse lib '/var/www/imscp/engine/PerlLib';use warnings;use strict;use iMSCP::Debug;use iMSCP::EventManager;use iMSCP::Dir;use iMSCP::Bootstrapper;# Bootstrap i-MSCP engineiMSCP::Bootstrapper->getInstance()->boot();# Path where templates are stored# Here, the my_template directory contains a 'themes' directory with files# that must override the default that are provided by i-MSCPmy $templatePath = '/usr/local/src/my_templates';sub CopyOwnTemplates($){ my $rs; if(length($templatePath) > 0) { if(-e $templatePath) { my $templatePathFolder = iMSCP::Dir->new( 'dirname' => $templatePath ); my $targetPathFolder = iMSCP::Dir->new( 'dirname' => $main::imscpConfig{'GUI_ROOT_DIR'} ); if(!($templatePathFolder->isEmpty())) { $rs = $templatePathFolder->rcopy( $targetPathFolder->{'dirname'} , '-rf' ); return $rs if $rs; $rs = $targetPathFolder->mode(0550); return $rs if $rs; $rs = $targetPathFolder->owner("$main::imscpConfig{'SYSTEM_USER_PREFIX'}$main::imscpConfig{'SYSTEM_USER_MIN_UID'}","$main::imscpConfig{'SYSTEM_USER_PREFIX'}$main::imscpConfig{'SYSTEM_USER_MIN_UID'}"); return $rs if $rs; } } } 0;}my $eventManager = iMSCP::EventManager->getInstance();$eventManager->register('afterInstall', \&CopyOwnTemplates);$eventManager->trigger('afterInstall');1;


    which mimic the bahavior of your listener. Then, I get the following warnings too:


    Shell-Script
    1. root@jessie:/usr/local/src# perl test.pl[WARN] iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.iMSCP::Debug::__ANON__: closedir() attempted on invalid dirhandle DIRH at /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm line 312, <$fh> line 340.


    This is due to the fact that we are using a non-local typeglob for creating the directory filehandle and thus, the filehandle get automatically closed when a new one is created in loop, leading to those warnings.


    There is at least two ways to fix that issue:


    The first one, which you can apply easily on your current i-MSCP copy, is to make the typeglobs local to the rcopy() method block scope (temporal-limited package-based glob). For this, you must just add the following line before the line 226 of the /var/www/imscp/engine/PerlLib/iMSCP/Dir.pm file:


    Perl
    1. local *DIRH;


    To be more clear:


    Perl
    1. ... unless(opendir DIRH, $self->{'dirname'}) {...


    must now look like:


    Perl
    1. ... local *DIRH; unless(opendir DIRH, $self->{'dirname'}) {...


    Another solution is to replace the typeglob by an unitialized scalar variable (lexical variable).


    For instance:

    Perl
    1. ... opendir my $dh, $self->{'dirname'} or die(sprintf('Could not open directory: %s' $!));...


    But this need more code edition after...


    Well, I'll use the second way to fix the problem in our repository but atm, you can use the first way on your i-MSCP copy.


    BTW: Your listener should better be written as follow:



    Edit: Sorry for any identation issue in the examples above... Editor from WBB really suck...

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206

  • Hello everybody,


    thanks for the massive feedback and the final code :)
    I will definetly take care of your hints when creating future listeners.
    At the moment the warning is a little bit anoying but everything works so I will leave it as it is for the moment. So far there are no other negative behaviors resulting from this.


    Regards Jörg

    (Ubuntu 16.04, i-MSCP 1.5.1, php-Fpm, Plugins: ClamAV, CronJobs, InstantSSH, LetsEncrypt, Mailgraph, Monitorix, OpenDKIM, PhpSwitcher, PolicydSPF, Postscreen, RecaptchaPMA, RoundcubePlugins, ServerDefaultPage, SpamAssassin, YubiKeyAuth)

  • badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206

  • Hi,


    there is just one little missing thing with the final code - you need to replace "setRights" by "iMSCP::Rights->setRights" or add "use iMSCP::Rights;" to the script. Final version of the script is attached.


    Regards Jörg

    Files

    (Ubuntu 16.04, i-MSCP 1.5.1, php-Fpm, Plugins: ClamAV, CronJobs, InstantSSH, LetsEncrypt, Mailgraph, Monitorix, OpenDKIM, PhpSwitcher, PolicydSPF, Postscreen, RecaptchaPMA, RoundcubePlugins, ServerDefaultPage, SpamAssassin, YubiKeyAuth)

  • @UncleJ


    I've updated my code. Better is to do:


    Perl
    1. ...
    2. use iMSCP::Rights;
    3. ...


    and then, the setRights() is imported.


    See the updated code.

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206