Announcement

Collapse
No announcement yet.

Application Return value

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Roger Garstang
    replied
    Exactly. There are like 5 different situations to check for:

    < 0 meaning it can't spawn, and mine reports -1 back for any negative
    value since the C++ spawn command calling it returns that.

    0 which is the only time I check the log to verify. Normal logs have time/dates
    and 3 other fields per row for what is going on, what is sending, and its process. I didn't
    write the code making this and don't have access to it, so have no clue what it could
    log for all cases. All I want is if the file contains the text "run-time error" and
    reported 0 that it reports an error instead so the application calling it doesn't think
    everything is fine. It still needs the other 1-28 codes to know what to do on those no
    matter what the log says good or bad.

    1 to 28 meaning error

    29 to 255 which to me would mean error, but the company said they are fine.

    Then a check I added for > 255 since it is possible in the function
    calling that it gets a device error and the High Byte(AH) gets set. No
    chance of Ctl+Break or TSR Ends setting them high, but this does use
    Serial, so I wanted to cover all bases and return an error for it...and since
    the original code sees > 28 as fine I return 1 so it is in the error range.

    This is just a Band-Aid being named the original called filename and calling the
    renamed original file since an application upgrade to do this and detect the issue
    will take 6 months and they need it now, so I made this in a day...

    For some reason out of the blue this application our software calls started getting
    Stack Overflows. I'm guessing because of communication errors and retries at certain
    locations and Fuji programmers suck and didn't know how to error check better or used
    recursive function calls. Since their stuff comes and goes like Stanley Tools...no
    one can fix it. So, we have to recover from it.

    ------------------
    If you aim at nothing...you will hit it.



    [This message has been edited by Roger Garstang (edited December 08, 2006).]

    Leave a comment:


  • Michael Mattias
    replied
    Couldn't you just check the log file and forget about any returns
    from the band-aid program? Sounds like the easiest solution.
    That would be highly dependent on the application.

    "Checking the log" is simply not effective in a high-volume situation, where what you want is exception-based reporting/action. Using return codes wisely is an excellent way to effect this kind of reporting.

    Leave a comment:


  • Don Schullian
    replied
    Roger,

    Couldn't you just check the log file and forget about any returns
    from the band-aid program? Sounds like the easiest solution.

    ------------------
    C'ya
    Don
    don at DASoftVSS dot com
    http://www.DASoftVSS.com
    --
    "There are 2 Ss in Christmas, Cratchet, and they're both dollar signs!"

    Leave a comment:


  • Roger Garstang
    replied
    No need to check it if there is an actual error. And if it gets corrupt or
    in a state I'm not testing for then it could return an error when nothing
    is wrong.

    I made sort of a hybrid of Michael's code and the other's I found along
    with looking up the interupts and seeing what they really need. The Code
    below seems to work and doesn't blow up.

    Code:
    Function PBExec (Program As String, Parameter As String) As Integer
    ' DOS requires that the parameter string hold the length of the parameter
    ' text, followed by the parameter text, and then followed by a CHR$(13)
    ' Enter byte. The parameter block holds two CHR$(0) bytes followed by
    ' the address and segment of the parameter string.
    
    Dim Block As String * 14 'this is the DOS parameter block
    Dim Parm As String * 80 'and this is the actual parameter text
    Dim ZBuffer As String * 15 'this holds a copy of the program name
    Dim Zero As String * 1
    Dim SaveDefSeg As Word
    Dim Dummy As Long
    
    SaveDefSeg = pbvDefSeg
    Zero = Chr$(0) 'invoke CHR$() only once for efficiency
    ZBuffer = Program + Zero 'make an ASCIIZ string for DOS
    LSet Parm = Chr$(Len(Parameter)) + Parameter + Chr$(13)
    LSet Block = Zero + Zero + Mki$(VarPtr(Parm)) + Mki$(VARSEG(Parm))
    Dummy = SETMEM(-500000) 'free up memory for the program being run
    
    REG 1, &h4B00 ' AX
    REG 4, VarPtr(ZBuffer) ' DX
    REG 9, VARSEG(Block) ' ES
    REG 2, VarPtr(Block) ' BX
    REG 8, VARSEG(ZBuffer) ' DS
    Call INTERRUPT &H21
    
    If (REG(0) And 1) Then 'DOS error trying to run the program?
       PBExec = -(REG(1)) ' set function value to -1 * DOS error code
    Else
       REG 1, &H4D00 'retrieve subordinate process code (AX)
       Call Interrupt &H21
       PBExec = REG(1) 'set function value to exit code (AX)
    End If
    
    Dummy = SETMEM(500000) 'reclaim the memory relinquished eariler
    DEF SEG = SaveDefSeg ' restore DS to what it was at entry.
    End Function
    ------------------
    If you aim at nothing...you will hit it.

    Leave a comment:


  • Paul D. Elliott
    replied
    If you're not going to believe the return code all the time,
    why not just do your check of the log file from the other
    program?


    ------------------

    Leave a comment:


  • Arthur Gomide
    replied
    Code:
    on error goto errortrap
    
    open "onlyfortesting" for input as #1     'to force an error
    
    '...
    ' your code here
    '...
    
    errortrap:
        'some error trap here
        'or only continue to
        PRINT ERR
        END ERR
    ------------------
    Arthur Gomide
    Como diria nosso profeta da bola, Dadá Maravilha: "Para toda Problemática existe uma Solucionática!"

    Leave a comment:


  • Michael Mattias
    replied
    How to set it:
    http://support.microsoft.com/kb/77457

    (int 21, service 4C)

    How to get it from a child program:
    Code:
    ' EXECDOS.BAS
    ' Execute an exteernal program as a child proccess, interrogate
    ' it's return code.
    ' For PB/DOS 3.2
    ' Author: Michael Mattias Racine WI 
    ' from original version for Microsoft QuickBASIC by Ethan Winer.
    
    
    '============================================================
    '     SUB TO Execute a program as a child process           
    ' Function value = return code of process; if < 0, error is 
    ' -1 * (dos error)
    '============================================================
    
    ' REG equates as expected in REGS.INC
    DEFINT A-Z
    FUNCTION DosExecute% (Program$, Parameter$) LOCAL
      '---- Prepare the program name and parameter strings for processing.  DOS
      '     requires that the parameter string hold the length of the parameter
      '     text, followed by the parameter text, and then followed by a CHR$(13)
      '     Enter byte.  The parameter block holds two CHR$(0) bytes followed by
      '     the address and segment of the parameter string.
      '
      DIM Block   AS LOCAL STRING * 14    'this is the DOS parameter block
      DIM Parm    AS LOCAL STRING * 80    'and this is the actual parameter text
    
      DIM ZBuffer AS LOCAL STRING * 80    'this holds a copy of the program name
    
      SaveDefSeg = pbvDefSeg
      DEF SEG
      DefaultDS = pbvDefSeg
      Zero$ = CHR$(0)                  'invoke CHR$() only once for efficiency
      DOS = &H21                       'saves a few bytes
      ZBuffer$ = Program$ + Zero$      'make an ASCIIZ string for DOS
    
      LSET Parm$ = CHR$(LEN(Parameter$)) + Parameter$ + CHR$(13)
      LSET Block$ = Zero$ + Zero$ + MKI$(VARPTR(Parm$)) + MKI$(VARSEG(Parm$))
    
      Dummy& = SETMEM(-500000)         'free up memory for the program being run
      REG %RegAX, &h4B00
      REG %RegDX, VARPTR (ZBuffer$)
      REG %RegES, VARSEG(Block$)
      REG %RegBX, VARPTR(Block$) 
      REG %RegDS, DefaultDS
      CALL INTERRUPT DOS
      Flags = REG(0)
      ReturnAX = REG(%RegAX)
      IF (Flags AND 1) THEN          'DOS error trying to run the program?
        DosExecute% = -(ReturnAX)    'yes, set function value to -1 * error code
        GOTO Execute.Done            'and jump to reclaim memory
      END IF
    
      REG %RegAX, &H4D00               'retrieve subordinate process code
      CALL Interrupt DOS
      DosExecute% = REG (%RegAX)          'set function value to exit code
    
    Execute.Done:
      Dummy& = SETMEM(500000)          'reclaim the memory relinquished eariler
      DEF SEG = SaveDefSeg             ' restore DS to what it was at entry.
    
    END FUNCTION
    MCM



    [This message has been edited by Michael Mattias (edited December 07, 2006).]

    Leave a comment:


  • Kev Peel
    replied
    Search POFFs or this forum for "ERRORLEVEL", there are plenty of posts about it..

    ------------------
    kgpsoftware.com - Downloads
    kgpsoftware.com - Development and Consulting

    Leave a comment:


  • Clay Clear
    replied
    Ahhh, gotcha. My MASM614 (DOS assembler) has a routine that
    allows to shell to another DOS app and retrieve the shelled
    app's exit code. If you wish, I will reinstall the MASM and
    PB/DOS 3.5 backups and see if I can interpret it enough to port
    it to a PB/DOS routine.

    But you will have to tell me if you want me to do it before I will.
    I haven't messed with DOS programming for 3-4 years, and that
    stuff has pretty much left my mind, so it might be quite a feat
    to recall enough of what I did so I can port it to PB/DOS.

    Hmmmm, just realized - I *might* be able to do some twisting around
    of the MASM "shell" procedure so I can compile it as an OBJ file that can
    be LINK'd into a PB/DOS app. Would that be your preference?


    ------------------
    Clay 's Website
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Roger Garstang
    replied
    No, both will be DOS applications running in DOS 5/6.

    I did find some code here calling INT 21, but the way it allocates
    the memory is a little weird. I'll play around with it, or try to find
    my old C++ Compiler or something. I'm surprised this wasn't supported since END
    allows for an exit code.

    ------------------
    If you aim at nothing...you will hit it.

    Leave a comment:


  • Clay Clear
    replied
    NT-class OS's don't support retrieving the exit code for 16-bit
    apps. I know for sure that applies to 16-bit Windows apps. I don't
    know if it applies to 16-bit DOS apps. It's been years since I read
    that on MSDN, and I don't remember where/how I found that article.
    But I would suggest the documentation for the GetExitCodeProcess() API
    as a start.


    ------------------
    Clay 's Website
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Roger Garstang
    started a topic Application Return value

    Application Return value

    Been a while since I've used the DOS compiler full time. I'm needing
    to make a Band-Aid application to call a program and check its return
    value. 0= Good, anything else= error. What happens is sometimes when 0
    is returned it is after a Stack Overflow, so really there was an error condition.

    So, what I need to do is if <> 0 then END my app with the same return value so the calling
    program knows there was an error. If it returns 0 then I need to check a log file to see if
    it did what it was supposed to do. If it did then return 0, if not then return <> 0 so the
    calling app knows there was really an error. PB DOS has a way of returning completion codes with
    END, but how do I call an app and get the return code of it??? Shell and checking Err values doesn't
    appear to support this. Is ther a command I'm forgetting, or is there not a way to do this?

    ------------------
    If you aim at nothing...you will hit it.
Working...
X