Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 524 forks source link

Is $! supposed to be set after system? #172

Closed p5pRT closed 20 years ago

p5pRT commented 24 years ago

Migrated from rt.perl.org#977 (status was 'resolved')

Searchable as RT977$

p5pRT commented 24 years ago

From @vlbrown

Is $! supposed to be set after system?

From p. 230 of the Camel (2nd edition) one might gather this and a lot of people seem to believe this to be the case.

But I am thinking it's a mis-assumption and system() (unlike\, say\, open) does not set $!.

This should be _explicitly_ documented\, especially in light of the example on p. 230 of Programming Perl which solidly implies that $! may get set.

However\, one of the clp-mod members did some playing with a C program that indicated errno is being set after a program is run\, so perhaps system() _should_ be setting $! and isn't.

Is this a bug?

(It's either a bug in the book\, i.e. Programming Perl should document that the use of $! in the code on p. 230 is not _directly_ related to system()... unlike certain other function such as open()\, system() does not actually set $!.

_Or_ system() is supposed to set $! and I can't make it do so.

If it's a documentation bug only I'll follow up with that. If it is a bug in system() you folks get it.

Vicki Brown \vlb@​cfcl\.com writes​:

From the Camel\, p. 230 ) ) $rc = 0xffff & system(@​args); [...] ) elsif ($rc == 0xff00) { ) print "command failed​: $!\n";

I cannot make $! contain anything useful no matter how hard I try\, or anyone else tries

At 21​:06 -0600 07/07/1999\, Tom Christiansen wrote in comp.lang.perl.moderated​:

​:If $! is meaningful in any situation after running system(...)

It was when I wrote that.

​:I'd appreciate an example. $! is empty when I try ​: system("cat food"); # no such file food; exit(2) from cat ​: system("cats food"); # no such program cats ​: system("command that seg faults");

Testing...

bsd% perl -le 'system("nonesuch"); print $!' \

linux% perl -le 'system("nonesuch"); print $!' \

sunos% perl -le 'system("nonesuch"); print $!' No such file or directory

and

bsd% perl -le 'system("/"); print $!' \

linux% perl -le 'system("/"); print $!' \

sunos% perl -le 'system("/"); print $!' Permission denied

Well\, something's odd. I'd report it.

One of the other folks on the list quoted the docs thusly​:

C\ returns C\<-1> if it is unable to request that the command be run. This happens if C\<fork()> fails\, for example. C\<$!> will say why C\<fork()> or some other call failed [though\, on most implementations\, I think C\<fork()> is the only thing that can fail to cause this case].

This isn't explicitly documented with Perl\, possibly because it depends on your operating system.

So perhaps $! is not meant to reflect the result of system()and the book (Programming Perl) should mention this as a comment in the code on p. 230.

However\, another clp-mod member tried this​:

At 19​:00 -0700 07/07/1999\, Dirk Myers wrote​:

If you take the programs that follow (test.c is compiled to test -- gcc test.c -o test -- \, and the file "gabba" in the current directory exists) you get​:

harpo 17% ./test.pl The error was -1\, errno was 17\, strerror was File exists 17 17 File exists

... it *looks like* $! works\, but isn't actually getting set to errno.

Is this a bug? I dunno... the C program is clearly setting errno and exiting with an error\, but $! sure isn't getting it...

--- snip here for test.c --- /* Test program to blow up with an error   * ... you gotta touch 'gabba' in the current directory before   * running it... */

#include \<stdlib.h> #include \<errno.h> #include \<fcntl.h> #include \<stdio.h>

void main(void) {   int rv ;   rv = open("./gabba"\, O_EXCL | O_CREAT | O_SHLOCK | O_EXLOCK) ; if (rv != 0 ) {   printf ("The error was %d\, errno was %d\, strerror was %s\n"\, rv\, errno\, strerror(errno)) ; }   exit (errno) ; --- snip for test.c ---

--- snip for test.pl --- #!/usr/local/bin/perl

$rv = system "./test" ; if ($rv) { $rv = $rv >> 8 ; print "$rv $!\n" ; $! = $rv ; print "$rv $!\n" ; } else { print "nope.\n" ; } --- snip for test.pl ---

Perl Info ``` Site configuration information for perl 5.00502: Configured by rdm at Sun Feb 7 16:25:31 PST 1999. Summary of my perl5 (5.0 patchlevel 5 subversion 2) configuration: Platform: osname=freebsd, osvers=2.2.8-release, archname=i386-freebsd uname='freebsd cfcl.com 2.2.8-release freebsd 2.2.8-release #0: fri jan 15 1 8:39:18 pst 1999 rdm@cfcl.com:usrsrcsyscompilefreebie i386 ' hint=recommended, useposix=true, d_sigaction=define usethreads=undef useperlio=undef d_sfio=undef Compiler: cc='cc', optimize='-O', gccversion=2.7.2.1 cppflags='-I/usr/local/include' ccflags ='-I/usr/local/include' stdchar='char', d_stdstdio=undef, usevfork=true intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 alignbytes=4, usemymalloc=n, prototype=define Linker and Libraries: ld='ld', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /usr/lib libs=-ldb -lm -lc -lcrypt libc=/usr/lib/libc.so.3.1, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-DPIC -fpic', lddlflags='-Bshareable -L/usr/local/lib' Locally applied patches: @INC for perl 5.00502: /usr/local/lib/perl5/5.00502/i386-freebsd /usr/local/lib/perl5/5.00502 /usr/local/lib/perl5/site_perl/5.005/i386-freebsd /usr/local/lib/perl5/site_perl/5.005 . Environment for perl 5.00502: HOME=/home/vlb LANG (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/vlb/bin:/usr/local/bin:/usr/local/nib:/usr/bin:/bin:/etc:/s bin:/u sr/sbin:/usr/local/games:/usr/games:.:/home/rdm/bin:/home/vlb/projex/ptf/bin PERL_BADLANG (unset) SHELL=/ulb/tcsh>Coming over from clp-mod -- -- |\ _,,,---,,_ Vicki Brown ZZZzz /,`.-'`' -. ;-;;,_ Journeyman Sourceror: Scripts & Philtres |,4- ) )-,_. ,\ ( `'-' P.O. Box 1269 San Bruno CA 94066 '---''(_/--' `-'\_) http://www.cfcl.com/~vlb http://www.macperl.com ```