Skip Menu |

This queue is for tickets about the Proc-Daemon CPAN distribution.

Report information
The Basics
Id: 127359
Status: resolved
Priority: 0/
Queue: Proc-Daemon

People
Owner: Nobody in particular
Requestors: BORISD [...] cpan.org
Cc:
AdminCc:

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



Subject: Option key 'pid_file' does not work with value 'pid.fulla'
If I use the value 'pid.fulla' for the key 'pid_file' no file will be created. I'm not sure for the cause of this behavior. The following values will work: anything anything.fulla fulla.pid pid.file /tmp/pid.fulla It seems that it is nor 'pid' or 'fulla', but only both in combination in exact this order and without a path... I replaced all occurrences of 'pid.file' with 'pid.fulla' in t/02_testmodule.t, the test then hangs after test 10, while in original state it will complete fine. This is how you can reproduce the bug: user@host:~/repos/Proc-Daemon[master]$ git checkout t/02_testmodule.t user@host:~/repos/Proc-Daemon[master]$ perl -Ilib t/02_testmodule.t 1..19 ok 1 - child_1 was created with PID: 4180 ok 2 - child_1 process did exit within 2 sec. ok 3 - child_1 has created a 'pid.file' ok 4 - the 'pid.file' contains the right PID: 4180 ok 5 - the 'pid.file' has right permissions ok 6 - child_1 has created a 'output.file' ok 7 - the content of the 'output.file' was right. ok 8 - child_1 has created a 'error.file' ok 9 - child_1 has created the 'kid.pl' file ok 10 - child_2 was created with PID: 4184 ok 11 - child_2 created a 'pid_1.file' ok 12 - the 'pid_1.file' contains the right PID: 4184 ok 13 - child_2 created a 'output_1.file' ok 14 - child_2 created a 'error_1.file' ok 15 - 'kid.pl' daemon is still running ok 16 - stop daemon 'kid.pl' ok 17 - 'kid.pl' daemon was stopped within 1 sec. ok 18 - the 'umask.file' has right permissions ok 19 - the 'pid2.file' has right permissions via file_umask user@host:~/repos/Proc-Daemon[master]$ sed -i.bak 's/pid\.file/pid.fulla/g' t/02_testmodule.t user@host:~/repos/Proc-Daemon[master]$ perl -Ilib t/02_testmodule.t 1..19 ok 1 - child_1 was created with PID: 4198 ok 2 - child_1 process did exit within 2 sec. ok 3 - child_1 has created a 'pid.fulla' ok 4 - the 'pid.fulla' contains the right PID: 4198 ok 5 - the 'pid.fulla' has right permissions ok 6 - child_1 has created a 'output.file' ok 7 - the content of the 'output.file' was right. ok 8 - child_1 has created a 'error.file' ok 9 - child_1 has created the 'kid.pl' file ok 10 - child_2 was created with PID: 4202 ^C I provid this failing test file as attachment.
Subject: 99_pid_file.t
#!/usr/bin/perl use strict; use warnings; use Test::More tests => 19; use Cwd; use Proc::Daemon; if (${^TAINT}) { # blindly untaint PATH (since there's no way we can know what is safe) # hopefully anyone using Proc::Daemon in taint mode will set PATH more carefully # update: let's try to remove things known (reported) to be unsafe $ENV{'PATH'} = join ':', grep { $_ ne '.' && defined && -d && ((stat $_)[2] & 07777) < 494 } $ENV{'PATH'} =~ /([^:]+)/g; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; } # Since a daemon will not be able to print terminal output, we # have a test daemon creating a file and another which runs the created # Perl file. # The parent process will test for the existence of the created files # and for the running daemon. # Try to make sure we are in the test directory my $cwd = Cwd::cwd(); chdir 't' if $cwd !~ m{/t$}; $cwd = Cwd::cwd(); $cwd = ($cwd =~ /^(.*)$/)[0]; # untaint (needed for 03_taintmode) # create object my $daemon = Proc::Daemon->new( work_dir => $cwd, child_STDOUT => 'output.file', child_STDERR => 'error.file', pid_file => 'pid.fulla', ); # create a daemon umask 022; my $Kid_PID = $daemon->init; # init instead of Init is a test for the old style too! if ( ok( $Kid_PID, "child_1 was created with PID: " . ( defined $Kid_PID ? $Kid_PID : '<undef>' ) ) || defined $Kid_PID ) { # here goes the child unless ( $Kid_PID ) { # print something into 'output.file' print 'test1'; # print a new Perl file open( FILE, ">$cwd/kid.pl" ) || die; print FILE "#!/usr/bin/perl # create an empty file to test umask open FILE, '>$cwd/umask.file'; close FILE; # stay alive forever while ( 1 ) { sleep ( 1 ) } exit;"; close( FILE ); } # this is only for the parent else { # wait max. 1 min. for the child to exit my $r = 0; while ( $daemon->Status( $Kid_PID ) and $r <= 60 ) { $r++; sleep( 1 ); } if ( ok( ! $daemon->Status( $Kid_PID ), "child_1 process did exit within $r sec." ) ) { if ( ok( -e "$cwd/pid.fulla", "child_1 has created a 'pid.fulla'" ) ) { my ( $pid, undef ) = $daemon->get_pid( "$cwd/pid.fulla" ); ok( $pid == $Kid_PID, "the 'pid.fulla' contains the right PID: $pid" ); ok( (stat("$cwd/pid.fulla"))[2] == 33152, "the 'pid.fulla' has right permissions" ); unlink "$cwd/pid.fulla"; } if ( ok( -e "$cwd/output.file", "child_1 has created a 'output.file'" ) ) { open( FILE, "<", "$cwd/output.file" ); ok( <FILE> eq 'test1', "the content of the 'output.file' was right." ); close FILE; unlink "$cwd/output.file"; } if ( ok( -e "$cwd/error.file", "child_1 has created a 'error.file'" ) ) { unlink "$cwd/error.file"; } if ( ok( -e "$cwd/kid.pl", "child_1 has created the 'kid.pl' file" ) ) { my $Kid_PID2 = $daemon->Init( { exec_command => "perl $cwd/kid.pl", # this is essentially a noop but gives us better test coverage setgid => (split / /, $))[0], setuid => $>, } ); if ( ok( $Kid_PID2, "child_2 was created with PID: " . ( defined $Kid_PID2 ? $Kid_PID2 : '<undef>' ) ) ) { wait_for_file("$cwd/pid_1.file"); if ( ok( -e "$cwd/pid_1.file", "child_2 created a 'pid_1.file'" ) ) { my ( $pid, undef ) = $daemon->get_pid( "$cwd/pid_1.file" ); ok( $pid == $Kid_PID2, "the 'pid_1.file' contains the right PID: $pid" ) } wait_for_file("$cwd/output_1.file"); ok( -e "$cwd/output_1.file", "child_2 created a 'output_1.file'" ); wait_for_file("$cwd/error_1.file"); ok( -e "$cwd/error_1.file", "child_2 created a 'error_1.file'" ); my $pid = $daemon->get_pid_by_proc_table_attr( 'cmndline', "perl $cwd/kid.pl", 1 ); diag( "Proc::ProcessTable is installed and did find the right PID for 'perl $cwd/kid.pl': $pid" ) if defined $pid and $pid == $Kid_PID2; $pid = $daemon->Status( "$cwd/pid_1.file" ); if (! ok( $pid == $Kid_PID2, "'kid.pl' daemon is still running" )) { diag("$pid != $Kid_PID2"); diag("STDOUT:\n" . `cat $cwd/output_1.file`); diag("STDERR:\n" . `cat $cwd/error_1.file`); diag("$cwd:\n" . `ls -lt $cwd`); } wait_for_file("$cwd/umask.file"); my $stopped = $daemon->Kill_Daemon(); ok( $stopped == 1, "stop daemon 'kid.pl'" ); $r = 0; while ( $pid = $daemon->Status( $Kid_PID2 ) and $r <= 60 ) { $r++; sleep( 1 ); } ok( $pid != $Kid_PID2, "'kid.pl' daemon was stopped within $r sec." ); unlink "$cwd/pid_1.file"; unlink "$cwd/error_1.file"; unlink "$cwd/output_1.file"; ok( (stat("$cwd/umask.file"))[2] == 33188, "the 'umask.file' has right permissions" ); unlink "$cwd/umask.file"; } unlink "$cwd/kid.pl"; } } } } my $daemon2 = Proc::Daemon->new( work_dir => $cwd, child_STDOUT => 'output2.file', child_STDERR => 'error2.file', pid_file => 'pid2.file', file_umask => 022, ); my $Kid_PID2 = $daemon2->Init; if ( $Kid_PID2 ) { # wait max. 1 min. for the child to exit my $r = 0; while ( $daemon2->Status( $Kid_PID2 ) and $r <= 60 ) { $r++; sleep( 1 ); } ok( (stat("$cwd/pid2.file"))[2] == 33188, "the 'pid2.file' has right permissions via file_umask" ); unlink "$cwd/output2.file", "$cwd/error2.file", "$cwd/pid2.file"; } sub wait_for_file { my $file = shift; my $r = 0; while ( ! -e $file and $r <= 60 ) { $r++; sleep( 1 ); } } 1;
So I thought I have tracked the problem down to the testfile, but it seems I was mistaken. The error can't be reproduced with the test file as described, because the reason why it hangs after test number 10 seems to be another one (probably test implementation specific). It also hangs if I use sed to replace all "pid.file" e.g. with "anything". So I tried to reproduce the error with a small script: 1 use Proc::Daemon; 2 3 $daemon = Proc::Daemon->new( 4 work_dir => $ENV{PWD}, 5 pid_file => 'pid.fulla', 6 child_STDOUT => 'fulla.stdout', 7 child_STDERR => 'fulla.stderr', 8 ); 9 10 $Kid_1_PID = $daemon->Init; But also this script behaves as it should, meaning after running it, there will be a file 'pid.fulla' in the current directory. So all I can now point to is the original application where I have observed the problem, as it is described in the first post. The application is opensource, so I can link it here: https://gitlab.com/borisdaeppen/School-Security-Application The relevant code is right here: https://gitlab.com/borisdaeppen/School-Security-Application/blob/5286c35c8e68bd84e31e60340810f69d62f3249b/code/server/bin/fulla#L37 There you will find the line: pid_file => "/tmp/fulla.pid", where I have to use "/tmp/", because otherwise the pid-file will not be created (at all) in the current directory. It will however if I change the names, as described in the first post. This does not make any sense at all. I hope the "bug" for this strange behavior is not in my code though... it's rather bizarre! Sorry for not providing more information until now.
After a bit more investigation, I could track the behavior to my own code. This is the only thing that makes any sense to the funny behavior. (it has to do with starting & stopping behavior of daemons) I apologize for the unnecessary ticket. Thanks for your great library!
Show quoted text
> I apologize for the unnecessary ticket.
>
> Thanks for your great library!

You're welcome!