Opened 11 years ago
Closed 11 years ago
#25 closed defect (fixed)
perl: system() fails on sh scripts in scalar mode
Reported by: | dmik | Owned by: | |
---|---|---|---|
Priority: | critical | Milestone: | |
Component: | Version: | ||
Severity: | Keywords: | ||
Cc: |
Description
The system() call fails with SYS1041 (The name NNN is not recognized...) when passed a scalar argument like this and the command to execute is a SH script:
system("aclocal --version"); if ( $? == -1 ) { print "command failed: $!\n"; } else { printf "command exited with value %d", $? >> 8; }
This must be because according to the docs scalar arguments are executed with the shell command which in case of OS/2 seems to be cmd.exe /c
.
Interesting is that if you use the list form instead (system("aclocal", "--version")
), all works. Perhaps, because LIBC exec() is used in this case which can properly recognize SH scripts and use SH.EXE for them.
This needs to be fixed as it obviously breaks many things (like automake
).
Attachments (1)
Change History (9)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
I can't build perl so far. Various issues. Both from SRPM and from SVN.
The SVN build fails because it can't properly generate regnodes.h
for some reason.
The RPM build fails because Extutils/MakeMaker.pm
is not at the right place and I see no code that would put it there. I see however that a file lib/buildcustomize.pl
is generated and this file contains the right INC statements that would make MakeMaker.pm
available for miniperl.exe
. There is also an option to Configure (usesitecustomize
, defines a macro USE_SITECUSTOMIZE
) that enables buildcustomize.pl
processing, but it is not defined by the build process. This all looks completely weird to me.
comment:3 by , 11 years ago
Okay, I found the reason. USE_SITECUSTOMIZE
is set automatically whenever PERL_IS_MINIPERL
is set. The problem was that the OS/2 makefile generator (os2/Makefile.SHs
) is outdated and didn't pass PERL_IS_MINIPERL
to the miniperl build command. The fix is attached below.
I didn't commit it to SVN yet because SVN is somehow out of sync with the source RPM (i.e. files os2/os2.sym
and os2/os2add.sym
are missing from SVN for some reason, there are some more). First, I want it to get back in sync. Yuri, can you comment on this?
by , 11 years ago
Attachment: | miniperl-build-fix.diff added |
---|
comment:4 by , 11 years ago
Going further. The title of the defect is not entirely correct. It fails not all SH scripts but only on some. In short, perl tries to guess if the first argument to system()
is an executable or a script. If it thinks the file is a script, it tries to process the #!
magic which tells which script interpreter to use on its own. If you specify a full path to a normal OS/2 EXE there, all works as expected. However, if what you give after #!
is a symlink to an exe, perl fails to recognize it as an exe and falls bak to a default case under which it assumes some unknown command or script is given and calls the system shell passing it everything in a hope that the system shell will figure that out.
So there are two separate problems:
file_type()
falis to recognize symlinks to exes as exes.- perl assumes that the system shell is always an OS/2 CMD.EXE compatible shell and hence uses the
CMD /C
syntax to start unknown commands and there is no way to override it.
Fixing any of the above would fix the particular problem I have with aclocal
from autoconf
but I think we should fix both.
In general, this part of the code is very dirty (many warnings marking dead code and such), overcomplicated and I really don't like that perl tries to be smarter than LIBC (which also has shell and script launcher detection which usually works OK). But it's too much work to do a full cleanup so I will only fix the mentioned problem for now.
comment:5 by , 11 years ago
comment:6 by , 11 years ago
Regarding problem 2. Actually, perl already recognizes the EXECSHELL
variable which you can use to specify the default shell for unknown scripts instead of OS2_SHELL
. It didn't help me before because it only allows to specify the shell name and not the argument used to issue a command (like /C
). However, the real problem with aclocal
was not using CMD.EXE instead of SH.EXE but the fact that #!perl
inside this script referred to a symlink on my machine (which points to perl.exe) and prior r744 understanding symlinks at this place was broken. Now it's fixed and it doesn't seem to be necessary to support EMXSHELL/SHELL/whatever
with the -c
option instead of OS2_SHELL
since all known scripts will work well now (given that the shell executable is correctly specified in #!
and exists). If it's not the case, then passing the script to EXECSHELL
directly (i.e. w/o the -c
option) will work: the specified shell is supposed to read it as a script and execute it (which of course means that the "unknown" script and the shell in EXECSHELL
match).
comment:7 by , 11 years ago
I also found by accident and fixed in r745 another quite a nasty bug related to shell script execution from perl. If the shell specified in #!
did't point to an existing file perl would endlessly try to search for it until killed. I'm sure I saw this behavior before.
comment:8 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
This seems to be done. I or Yuri will release a new perl RPM soon.
A possible fix is to grab the LIBC logic of detecting the current shell (see http://trac.netlabs.org/libc/ticket/287 for details) and depending on it use either
-c
or/c
.