jmacloue has asked for the wisdom of the Perl Monks concerning the following question:
I wrote a script which forks an unpriviledged child as it shown in perlipc example and found out that after a successul socketpair() call there is an error recorded in $!:
#!/usr/bin/perl -w use strict; use IO::Socket; print "Before socketpair() call: $!\n"; my @s = IO::Socket->socketpair(AF_UNIX, SOCK_STREAM, PF_UNIX) or die "socketpair: $!\n"; print "After socketpair() call: $!\n";
It prints out:
Before socketpair() call: After socketpair() call: Illegal seek
Despite socketpair() is successful (sockets work as expected and the script does not die) an "Illegal seek" is recorded in $! so I had to explicitly say $!=undef after the call to get rid of it or use a block with "local $!;".
Usually it is not a problem as most errors are reported in some other way (e.g., func() or die "$!") but when I need to change process uid/gid the only way to check for error is to see if $! is set, and if $! stays littered with an error from socketpair() the check fails:
$) = $run_gid; die "Setting egid: $!" if $!;
I tried to see if I'm doing anything wrong so I tried strace'ing my script, to get the following:
socketpair(PF_LOCAL, SOCK_STREAM, 1, [3, 4]) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGET +S, 0x7fff3ff30d00) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGET +S, 0x7fff3ff30d00) = -1 ENOTTY (Inappropriate ioctl for device) lseek(3, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) ioctl(4, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGET +S, 0x7fff3ff30d00) = -1 ENOTTY (Inappropriate ioctl for device) lseek(4, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) ioctl(4, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGET +S, 0x7fff3ff30d00) = -1 ENOTTY (Inappropriate ioctl for device) lseek(4, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fcntl(4, F_SETFD, FD_CLOEXEC) = 0
As we see, the system socketpair() call is followed by two lseek() calls somewhere inside Perl interpreter, which fail with ESPIPE, which is recorded in $!, but socketpair() still returns success.
Any insights on how to do this (socketpair/fork/drop privileges) properly?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Strange behaviour: $! is set after successful socketpair() call
by kennethk (Abbot) on Apr 12, 2014 at 20:53 UTC | |
|
Re: Strange behaviour: $! is set after successful socketpair() call
by LanX (Saint) on Apr 12, 2014 at 21:38 UTC | |
|
Re: Strange behaviour: $! is set after successful socketpair() call
by jmacloue (Beadle) on Apr 16, 2014 at 15:10 UTC |