I/O error detection is broken

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: I/O error detection is broken

#16 Post by foxidrive » 03 Jan 2016 23:30

Squashman wrote:
dbenham wrote:What the hell foxi :? :!: :?: :lol:

I am totally mystified as to what point you are trying to make.

I think he is trying to say the errorlevel should be a 1 and the conditional execution should not echo.


Very close Squashman, and thanks - it was that the conditional execution should not echo if it could be relied upon.
Dave said it could be relied upon. That's what I commented about.

The pad executable doesn't set an errorlevel - I commented on that at the same time.

Topic well and truly dragged over the hill, and under the dale.

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: I/O error detection is broken

#17 Post by penpen » 04 Jan 2016 11:57

dbenham wrote:But regardless whether the command is internal or external, if the command returns a 0 exit code, then && fires, if non-zero, then || fires. The really odd thing is that a few internal commands fire || upon error, yet fail to set ERRORLEVEL unless || is used. This is evidence that the exit code and ERRORLEVEL are not quite synonymous.
You are right; the exit code and the ERRORLEVEL are different constructs:
1) Exit code:
There are different x86 calling conventions (where to find parameters and return values).
The standard calling convention for the Microsoft Win32 API is "stdcall", so i assume it is also used by "cmd.exe".
Then the exit code is the value of the (E)AX register when returning from a function.
(This value of the exit code is just located somewhere else if "cmd.exe" uses another calling convention.)

2) ERRORLEVEL:
This information is stored within the process structure (line 0055) (sorry no Microsoft sources available; but it should be very similar), unique per process.
You could retrieve this information in C++ for example using GetExitCodeProcess.
The default is that the exit code updates the errorlevel (see "Remarks" section of GetExitCodeProcess linked above).
But if another application is executed before the internal command is finished, or if a thread exits later, it may replace the errorcode with no_error (or vice versa).
Internal catched Exception may not lead to en error (although this should be a bug from my point of view).
If an application is no console application then only the "loading success" is returned.


penpen

Edit 1: Changed "function" to "application" ("But if another application is executed before the internal ") because most times: functions will not set the errorlevel. (in this case: application == internal/external commands that set the errorlevel).
Edit 2: Corrected a flaw.
Last edited by penpen on 05 Jan 2016 18:25, edited 2 times in total.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: I/O error detection is broken

#18 Post by dbenham » 05 Jan 2016 12:13

@foxidrive - I've edited my initial post in an attempt to alleviate your concerns.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: I/O error detection is broken

#19 Post by Aacini » 06 Jan 2016 09:10

I want add a couple notes about this topic.

All external .exe files change the ERRORLEVEL value when they ends; there is no way to avoid this point.

The standard way to reset ERRORLEVEL to zero in a Batch file is using VER command; this works since the VER command existed. I can't find a MS note I read some time ago about this point, but it is really old.

This S.O. topic wrote:The only known difference between .cmd and .bat file execution is that in a .cmd file the ERRORLEVEL variable changes even on a successful command that is affected by Command Extensions (when Command Extensions are enabled), whereas in .bat files the ERRORLEVEL variable changes only upon errors.

For example, this .BAT file:

Code: Select all

@echo off
setlocal

:: Define input file
set "in=input.txt"

:: Create input file
>"%in%" (
  echo Line 1
  echo/
  echo Line 3
)

3<"%in%" call :test
exit /b


:test
echo Reading Line 1:
set "ln="
ver > nul
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

echo Reading Line 2:
set "ln="
ver > nul
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

echo Reading Line 3:
set "ln="
ver > nul
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

echo Reading Line 4:
set "ln="
ver > nul
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

... and this .CMD one:

Code: Select all

@echo off
setlocal

:: Define input file
set "in=input.txt"

:: Create input file
>"%in%" (
  echo Line 1
  echo/
  echo Line 3
)

3<"%in%" call :test
exit /b


:test
echo Reading Line 1:
set "ln="
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

echo Reading Line 2:
set "ln="
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

echo Reading Line 3:
set "ln="
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

echo Reading Line 4:
set "ln="
<&3 set /p "ln=" && echo OK || echo FAIL
echo ERRORLEVEL=%errorlevel%
echo result=[%ln%]
echo/

... both show the same output, in despite the last one does not reset the ERRORLEVEL.

Antonio

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: I/O error detection is broken

#20 Post by dbenham » 22 Jan 2016 11:40

@Aacini - Thanks for drawing attention to That S.O. post. I had seen it years ago, before it was edited to highlight the difference between the original Wikipedia quote and the User Group post. So I was under the false impression that all internal commands clear the ERRORLEVEL upon success when run from a .CMD script. In reality, there are still many internal commands that never clear the ERRORLEVEL upon success, even when run in a .CMD script.

@foxidrive - I've posted a treatise on && and || at StackOverflow that you and others might find interesting. Hopefully it helps.


Dave Benham

Post Reply