Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pl2bat BAT files exit with incorrect ERRORLEVEL and process exit codes #16361

Open
p5pRT opened this issue Jan 13, 2018 · 5 comments
Open

pl2bat BAT files exit with incorrect ERRORLEVEL and process exit codes #16361

p5pRT opened this issue Jan 13, 2018 · 5 comments

Comments

@p5pRT
Copy link

@p5pRT p5pRT commented Jan 13, 2018

Migrated from rt.perl.org#132717 (status was 'open')

Searchable as RT132717$

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jan 13, 2018

From RIVY@cpan.org

Created by rivy@cpan.net

This is a bug report for perl from rivy@​cpan.net,
generated with the help of perlbug 1.40 running under perl 5.26.1.

-----------------------------------------------------------------
`pl2bat` BAT files exit with incorrect ERRORLEVEL and process exit codes

As currently defined, the BAT files created with `pl2bat` will exit with
incorrect ERRORLEVEL codes.

Examples of failures, (from the CMD shell)​:

#1

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "1" (wrong!, should be "10")
```

#2

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "SUCCESS" (wrong!, should be "FAIL")
echo %ERRORLEVEL%
:​: "1"
```

Changing...

`if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul`

... to ...

`if NOT "%errorlevel%" == "0" ( goto #_undefined_label_# 2>nul ||
"%COMSPEC%" /d /c exit %errorlevel% )`

will exit the process correctly, returning a correct process code and
passing the correct ERRORLEVEL back up to the shell.

With the change​:

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_# 2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )}; s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "10" (now correct)
```

Additionally, it works for all non-zero ERRORLEVELs (such as the common
"-1").

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_# 2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )}; s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL" (now correct)
echo %ERRORLEVEL%
:​: "-1"
```

Thanks for the attention!

Perl Info

Flags:
    category=utilities
    severity=medium

Site configuration information for perl 5.26.1:

Configured by strawberry-perl at Sun Sep 24 05:36:07 2017.

Summary of my perl5 (revision 5 version 26 subversion 1) configuration:

  Platform:
    osname=MSWin32
    osvers=6.3
    archname=MSWin32-x64-multi-thread
    uname='Win32 strawberry-perl 5.26.1.1 #1 Sun Sep 24 05:32:33 2017 x64'
    config_args='undef'
    hint=recommended
    useposix=true
    d_sigaction=undef
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=undef
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler:
    cc='gcc'
    ccflags =' -s -O2 -DWIN32 -DWIN64 -DCONSERVATIVE
-D__USE_MINGW_ANSI_STDIO -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -fwrapv -fno-strict-aliasing
-mms-bitfields'
    optimize='-s -O2'
    cppflags='-DWIN32'
    ccversion=''
    gccversion='7.1.0'
    gccosandvers=''
    intsize=4
    longsize=4
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    ivtype='long long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='long long'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='g++.exe'
    ldflags ='-s
-L"C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\perl\lib\CORE"
-L"C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\c\lib"'
    libpth=C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\c\lib
C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\c\x86_64-w64-mingw32\lib
C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\c\lib\gcc\x86_64-w64-mingw32\7.1.0
    libs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
    perllibs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
    libc=
    so=dll
    useshrplib=true
    libperl=libperl526.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs
    dlext=xs.dll
    d_dlsymun=undef
    ccdlflags=' '
    cccdlflags=' '
    lddlflags='-mdll -s
-L"C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\perl\lib\CORE"
-L"C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\c\lib"'



@INC for perl 5.26.1:

C:/Users/Roy/AppData/Local/scoop/apps/perl/5.26.1.1-PDL/perl/site/lib/MSWin32-x64-multi-thread
    C:/Users/Roy/AppData/Local/scoop/apps/perl/5.26.1.1-PDL/perl/site/lib
    C:/Users/Roy/AppData/Local/scoop/apps/perl/5.26.1.1-PDL/perl/vendor/lib
    C:/Users/Roy/AppData/Local/scoop/apps/perl/5.26.1.1-PDL/perl/lib


Environment for perl 5.26.1:
    CYGWIN=mintty
    HOME=C:\Users\Roy
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=POSIX
    LC_CTYPE=POSIX
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)

PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Users\Roy\OneDrive\Tools\#bin;C:\Users\Roy\OneDrive\Tools\#bin\lib;C:\Users\Roy\AppData\Local\scoop\shims;C:\Users\Roy\AppData\Local\scoop\apps\nodejs\8.9.4;C:\Users\Roy\AppData\Local\scoop\apps\nodejs\8.9.4\bin;C:\Users\Roy\AppData\Local\scoop\apps\nodejs\6.10.3\nodejs;C:\Users\Roy\AppData\Local\scoop\apps\python\2.7.10\scripts;C:\Users\Roy\AppData\Local\scoop\apps\latex\2.9.6521\texmfs\install\miktex\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\perl\site\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\perl\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.26.1.1-PDL\c\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.22.1.2\perl\site\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.22.1.2\perl\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.22.1.2\c\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.24.0.1-PDL\perl\site\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.24.0.1-PDL\perl\bin;C:\Users\Roy\AppData\Local\scoop\apps\perl\5.24.0.1-PDL\c\bin;C:\Users\Roy\AppData\Local\scoop\apps\openjdk\1.8.0.141-1\bin;C:\Users\Roy\AppData\Local\scoop\apps\ruby\2.2.1\bin;C:\Users\Roy\AppData\Local\scoop\apps\go\1.5\bin;C:\Users\Roy\AppData\Local\scoop\apps\ant\1.9.6\bin;C:\Users\Roy\AppData\Local\scoop\apps\gcc\5.1.0-tdm\bin;C:\Users\Roy\AppData\Local\Microsoft\WindowsApps;C:\Users\Roy\AppData\Local\Keybase;C:\Users\Roy\AppData\Local\Keybase
    PERL_BADLANG (unset)

PERL_CPAN_REPORTER_CONFIG=C:\Users\Roy\.CPANreporter\10-5.24.0\config.ini
    PERL_CPAN_REPORTER_DIR=C:\Users\Roy\.CPANreporter\10-5.24.0
    PERL_MB_OPTS=--color=always
    SHELL (unset)

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jan 14, 2018

From @Leont

On Sat, Jan 13, 2018 at 6​:12 PM, Roy Ivy III <perlbug-followup@​perl.org> wrote​:

`pl2bat` BAT files exit with incorrect ERRORLEVEL and process exit codes

As currently defined, the BAT files created with `pl2bat` will exit with
incorrect ERRORLEVEL codes.

Examples of failures, (from the CMD shell)​:

#1

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "1" (wrong!, should be "10")
```

#2

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "SUCCESS" (wrong!, should be "FAIL")
echo %ERRORLEVEL%
:​: "1"
```

Changing...

`if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul`

... to ...

`if NOT "%errorlevel%" == "0" ( goto #_undefined_label_# 2>nul ||
"%COMSPEC%" /d /c exit %errorlevel% )`

will exit the process correctly, returning a correct process code and
passing the correct ERRORLEVEL back up to the shell.

With the change​:

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_# 2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )}; s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "10" (now correct)
```

Additionally, it works for all non-zero ERRORLEVELs (such as the common
"-1").

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_# 2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )}; s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL" (now correct)
echo %ERRORLEVEL%
:​: "-1"
```

Thanks for the attention!

In the past two decades pl2bat got forked twice. First in
Module​::Build and the second time in ExtUtils​::Helpers. The latter is
the only one that has this issue fixed (primarily because it's the
only one that includes tests). A few months ago I have extracted this
logic into a new module (ExtUtils​::PL2Bat), with the intention of
making all of these modules use this single implementation that is
actually maintained.

My main limitation here is not really being a Windows person, and
hence currently not having a setup to test what I'm doing. I really
could use a hand there.

Leon

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jan 14, 2018

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jan 15, 2018

From RIVY@cpan.org

On Sun, 14 Jan 2018 14​:39​:20 -0800, LeonT wrote​:

On Sat, Jan 13, 2018 at 6​:12 PM, Roy Ivy III <perlbug-
followup@​perl.org> wrote​:

`pl2bat` BAT files exit with incorrect ERRORLEVEL and process exit
codes

As currently defined, the BAT files created with `pl2bat` will exit
with
incorrect ERRORLEVEL codes.

Examples of failures, (from the CMD shell)​:

#1

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "1" (wrong!, should be "10")
```

#2

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "SUCCESS" (wrong!, should be "FAIL")
echo %ERRORLEVEL%
:​: "1"
```

Changing...

`if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul`

... to ...

`if NOT "%errorlevel%" == "0" ( goto #_undefined_label_# 2>nul ||
"%COMSPEC%" /d /c exit %errorlevel% )`

will exit the process correctly, returning a correct process code and
passing the correct ERRORLEVEL back up to the shell.

With the change​:

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_#
2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )};
s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "10" (now correct)
```

Additionally, it works for all non-zero ERRORLEVELs (such as the
common
"-1").

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_#
2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )};
s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL" (now correct)
echo %ERRORLEVEL%
:​: "-1"
```

Thanks for the attention!

In the past two decades pl2bat got forked twice. First in
Module​::Build and the second time in ExtUtils​::Helpers. The latter is
the only one that has this issue fixed (primarily because it's the
only one that includes tests). A few months ago I have extracted this
logic into a new module (ExtUtils​::PL2Bat), with the intention of
making all of these modules use this single implementation that is
actually maintained.

My main limitation here is not really being a Windows person, and
hence currently not having a setup to test what I'm doing. I really
could use a hand there.

Leon

I can help.

I saw the [ExtUtils​::Helpers](https://github.com/Leont/extutils-helpers) repo. But, given the code that I saw in perl, I wasn't sure how it was related.

I've been working on an AppVeyor configuration that could help with the Windows testing. I'll open a couple of issues on the repo with some suggestions and an AppVeyor configuration.

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Feb 10, 2018

From RIVY@cpan.org

On Sun, 14 Jan 2018 14​:39​:20 -0800, LeonT wrote​:

On Sat, Jan 13, 2018 at 6​:12 PM, Roy Ivy III <perlbug-
followup@​perl.org> wrote​:

`pl2bat` BAT files exit with incorrect ERRORLEVEL and process exit
codes

As currently defined, the BAT files created with `pl2bat` will exit
with
incorrect ERRORLEVEL codes.

Examples of failures, (from the CMD shell)​:

#1

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "1" (wrong!, should be "10")
```

#2

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "SUCCESS" (wrong!, should be "FAIL")
echo %ERRORLEVEL%
:​: "1"
```

Changing...

`if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul`

... to ...

`if NOT "%errorlevel%" == "0" ( goto #_undefined_label_# 2>nul ||
"%COMSPEC%" /d /c exit %errorlevel% )`

will exit the process correctly, returning a correct process code and
passing the correct ERRORLEVEL back up to the shell.

With the change​:

``` batch
echo exit(10); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_#
2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )};
s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL"
echo %ERRORLEVEL%
:​: "10" (now correct)
```

Additionally, it works for all non-zero ERRORLEVELs (such as the
common
"-1").

``` batch
echo exit(-1); > "%TEMP%\fail.pl"
pl2bat "%TEMP%\fail.pl"
perl -pi.bak -e "$q=chr(34); $p=chr(37); $s=q{if errorlevel 1 goto
script_failed_so_exit_with_non_zero_val 2>nul}; $t=qq{if NOT
${q}${p}errorlevel${p}${q} == ${q}0${q} ( goto #_undefined_label_#
2>nul ||
${q}${p}COMSPEC${p}${q} /d /c exit ${p}errorlevel${p} )};
s/$s/$t/eg;"
"%TEMP%\fail.bat"
"%TEMP%\fail.bat" && echo SUCCESS || echo FAIL
:​: "FAIL" (now correct)
echo %ERRORLEVEL%
:​: "-1"
```

Thanks for the attention!

In the past two decades pl2bat got forked twice. First in
Module​::Build and the second time in ExtUtils​::Helpers. The latter is
the only one that has this issue fixed (primarily because it's the
only one that includes tests). A few months ago I have extracted this
logic into a new module (ExtUtils​::PL2Bat), with the intention of
making all of these modules use this single implementation that is
actually maintained.

My main limitation here is not really being a Windows person, and
hence currently not having a setup to test what I'm doing. I really
could use a hand there.

Leon

Leon,

I forked [ExtUtils​::PL2Bat](https​://github.com/rivy/perl.ExtUtils-PL2Bat) and added all the needed corrections (to PL2Bat, the AppVeyor CI config, and testing). I've pushed a [PR](Perl-Toolchain-Gang/extutils-pl2bat#3) for all the changes.

The PL2Bat changes include fixed handling of "echo", "ERRORLEVEL", and general environment state.

Testing now checks for correct process exit status as well as the actual exit code.

And the new AppVeyor config correctly tests against all `perl` versions back to v5.8.9; and all tests are now passing.

This should give you a much better Windows base for further changes. Let me know if I can be of further assistance, or if you need changes to the PR.

- Roy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants