Hi monks,
I've spent some time tracking down a strange problem in a daemon script - ultimately I've no-one to blame but myself, as I wasn't checking my return codes and/or
$!, but I've found some surprising behaviour... Much reduced code:
#!/usr/bin/perl -w
use strict;
use IO::Socket::INET;
my $server =IO::Socket::INET->new(LocalPort => 4848, Listen=> 1,ReuseA
+ddr => 1) or die "listen: $!";
my $client;
USER: while($client= $server->accept()){
if (my $pid = fork()){
#parent
close $client;
$SIG{CHLD} = sub {};
}else{
print $client "hello, world!\n";
select(undef,undef,undef,2);
exit;
}
}
warn "fell out of loop - $!";
The sleep in the child process causes SIGCHLD to be delivered to the parent when it is in blocking in
accept(), and sure enough I get
fell out of loop - Interrupted system call at /tmp/z.pl line 17.I understand from chapter 16 of the Camel Book that this could happen with old, horrible Unices, but I'm surprised it happens with
This is perl, v5.10.0 built for i486-linux-gnu-thread-multi on
Debian 5.0.3Can anyone shed some light on this?? An strace looks like it's going to work, but doesn't...
bind(3, {sa_family=AF_INET, sin_port=htons(4848), sin_addr=inet_addr("
+0.0.0.0")}, 16) = 0
listen(3, 1) = 0
accept(3, {sa_family=AF_INET, sin_port=htons(23694), sin_addr=inet_add
+r("127.0.0.1")}, [16]) = 4
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffa26c8) = -1 EINVAL (Inval
+id argument)
_llseek(4, 0, 0xbffa2710, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffa26c8) = -1 EINVAL (Inval
+id argument)
_llseek(4, 0, 0xbffa2710, SEEK_CUR) = -1 ESPIPE (Illegal seek)
fcntl64(4, F_SETFD, FD_CLOEXEC) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIG
+CHLD, child_tidptr=0xb7d9f908) = 5206
close(4) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, {0x809a270, [], 0}, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
accept(3, 0xbffa28c8, [4096]) = ? ERESTARTSYS (To be restart
+ed)
--- SIGCHLD (Child exited) @ 0 (0) ---
sigreturn() = ? (mask now [])
rt_sigprocmask(SIG_BLOCK, [CHLD], NULL, 8) = 0
rt_sigaction(SIGCHLD, NULL, {0x809a270, [], 0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [CHLD], NULL, 8) = 0
open("/usr/share/locale/locale.alias", O_RDONLY) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=2586, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
+ 0) = 0xb7f7a000
read(4, "# Locale name alias data base.\n# "..., 4096) = 2586
read(4, ""..., 4096) = 0
close(4) = 0
munmap(0xb7f7a000, 4096) = 0
open("/usr/share/locale/en_GB.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) =
+-1 ENOENT (No such file or directory)
open("/usr/share/locale/en_GB.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -
+1 ENOENT (No such file or directory)
open("/usr/share/locale/en_GB/LC_MESSAGES/libc.mo", O_RDONLY) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=1474, ...}) = 0
mmap2(NULL, 1474, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb7f7a000
close(4) = 0
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1
+ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 E
+NOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT
+ (No such file or directory)
write(2, "fell out of loop - Interrupted sy"..., 65) = 65
close(3) = 0
exit_group(0) = ?
Thanks!