Operating System - OpenVMS
1753487 Members
4423 Online
108794 Solutions
New Discussion юеВ

Re: DCL command 'SUBMIT' exit status check

 
SOLVED
Go to solution
Joseph Huber_1
Honored Contributor

Re: DCL command 'SUBMIT' exit status check

>> I didn't even try that as I thought it would no longer relate to SUBMIT due to the stuff that happens between it and the IF statement.

And You are right to think so: $STATUS/$SEVERITY is that after the pipe, not what You want.

The only solution I can see is to write the SUBMIT command message into a temporary file, and chain the command with an command-file, which saves the $STATUS/$SEVERITY, then reads and logs the temporary file:

$ PIPE SUBMIT ... >tempfile ; @logit tempfile

"PIPE ; " does not create a subprocess (no sys$pipe), but has valid $STATUS in @logit.
"PIPE | " creates a subprocess with sys$pipe, but then $STATUS is not available.
http://www.mpp.mpg.de/~huber
Joost van der Knaap
Occasional Advisor

Re: DCL command 'SUBMIT' exit status check

In that case I think I might follow some of Craig's suggestions and do something like this:

$ DEFINE/JOB SYS$OUTPUT SUBMIT.LIS
$ DEFINE/JOB SYS$ERROR SUBMIT.LIS
$ 'SUBMITCMD'
$ STATUS := "''$status' ''$severity'"
$ SHOW SYMBOL STATUS
$ DEASSIGN/JOB SYS$OUTPUT
$ DEASSIGN/JOB SYS$ERROR

And then open the file to determine the results.

Either way it seems I'm not going to avoid additional I/O and a cleanup subroutine for temp files.
Craig A
Valued Contributor

Re: DCL command 'SUBMIT' exit status check

Joost

If you use /USER rather then /JOB then the definition only remains in place for the next image activAtion. In this case the use of SUBMIT.EXE

So you don't need to DEASSIGN the logicals.

Craig
Hoff
Honored Contributor

Re: DCL command 'SUBMIT' exit status check

Jess Goodman
Esteemed Contributor

Re: DCL command 'SUBMIT' exit status check

There are a couple of cases where SUBMIT outputs an informational message before the line that has "JOB jobname".

$ SUBMIT LOGIN /NOLOG /RETAIN=UNTIL=YESTERDAY
%JBC-I-ITMREMOVED, meaningless items were removed from request
Job LOGIN (queue SYS$BATCH_AX38, entry 2003955) started on SYS$BATCH_AX38

These would cause your test of the first output line for the string "JOB jobname" to fail.


I have one, but it's personal.
Joseph Huber_1
Honored Contributor

Re: DCL command 'SUBMIT' exit status check

Just to add another solution avoiding a temporary file:

pipe (submit xyz ; write sys$output "SEV: ",$severity) | @logit

This puts the severity of the SUBMIT as last line to the output pipe.
So logit.com can do a read loop on sys$pipe, and check for a line starting with "SEV:" to handle the results.
http://www.mpp.mpg.de/~huber
Joseph Huber_1
Honored Contributor

Re: DCL command 'SUBMIT' exit status check

The DCL code for the above solution could look like this:

$ me=f$environment("PROCEDURE")
$ if p1.eqs."#LOG#" then goto LOG

...

$ pipe (submit xyz ; write sys$output "SEV: ",$severity) | @'me' #LOG#

...

$LOG:
$ n=0
$LOOP:
$ read/end=DONE sys$pipe line
$ if f$extract(0,4,line).eqs."SEV:"
$ then
$ severity = f$element(1," ",line)
$ else
$ line'n' = line
$ n=n+1
$ endif
$ goto LOOP
$DONE:
$ tag="ER"
$ if f$integer(severity).eq.1 then tag="IN"
$ i=0
$LL:
$ result = line'i'
$ CALL LOGTHIS "''RESULT'" 'tag'
$ i=i+1
$ if i.lt.n then goto LL
$ exit
http://www.mpp.mpg.de/~huber
John Gillings
Honored Contributor

Re: DCL command 'SUBMIT' exit status check

Joost,

First to answer your direct question:

>Is there a list of possible exit
>messages for SUBMIT?

In theory, you might be able to work it out, but in practice, not really. Looking at the source of SUBMIT you may be able to find all the condition codes which are explicitly signalled or returned, but you then need to consider all the subsystems it calls - SYS$, RMS$, LCK$ and on and on. This becomes a very large, and somewhat unpredictable set. Even if you could construct such a set, it could potentially change in future, so you make yourself a maintenance task.

Onwards...

I think you're making this far more complex than necessary. As I see it there are two issues:

1) You want the procedure to detect if the SUBMIT was successful (or, more generally, any particular action in your procedure)

2) If an action fails you want to capture the exact and complete error message.

Your problem is you're trying to do both simultaneously, which is leading to convoluted code to try and account for many possibilities (for example, multiple lines of error message). This also adds extra things that might fail, and thus you recurse into a cascade of checks upon checks upon checks.

Try tackling each issue separately. 1 is simple, use $STATUS

$ SUBMIT ...whatever
$ stat=$STATUS
$ IF stat
$ THEN
$ ...OK
$ ELSE
$ ...Failed
$ ENDIF

Simple!

For 2, realise that the error message is complete and intact in the log file of the batch job. You can log that an error occurred, including the primary status. You can also add a pointer to the log file containing the completetext:

$ IF F$GETQUI("DISPLAY_ENTRY","JOB_LOG_NULL",,"THIS_JOB")
$ THEN
$ Msg = "(no log file)"
$ ELSE
$ Msg = "See Logfile:"+F$PARSE(F$GETQUI("DISPLAY_ENTRY","LOG_SPECIFICATION",,"THIS_JOB"),-
"SYS$LOGIN:.LOG;",F$GETQUI("DISPLAY_ENTRY","JOB_NAME",,"THIS_JOB"))
$ ENDIF
$ out=F$FAO("!AS: !UL error!%S in !AS on node !AS. !AS",Name,Err,Title,Node,Msg)

(in this example, I count the number of errors that occurred in symbol "Err" - the message is then MAILed at the end of the job.

To further highlight any issues, I usually submit jobs with /RETAIN=ERROR, and track the worst status value in symbol "stat". Last line is:

$ EXIT %X10000000.OR.F$INTEGER(stat)+(F$VERIFY(verf).AND.0)

"verf" contains the verification value on entry, stat is the completion code, and %X10000000 sets the STS$M_INHIB bit to tell DCL not to display an error message.

I have a daily job that hunts for and reports on any retained jobs.
A crucible of informative mistakes
John Gillings
Honored Contributor

Re: DCL command 'SUBMIT' exit status check

Joost,
Taking another (more general) approach...

Since the error message is in the log file, which is periodically flushed, you can get the message live from the log file at run time with, for example, TYPE/TAIL, or any other command which can read a shared file. You can therefore use ON WARNING to collect error messages from ANY command which generates an error using a GOSUB so you don't interrupt the flow of execution. Try this:

CATCHWARN.COM
$ SET NOON
$ SET VERIFY
$ GOSUB SetupLog
$
$ WRITE SYS$OUTPUT "Some stuff in the log file"
$ SHOW PROCESS
$
$ WRITE SYS$OUTPUT "Now generate some errors"
$
$ TYPE junk.dat
$
$ SUBMIT/QUEUE=noqueue nojob
$
$ WRITE SYS$OUTPUT "More stuff in log file"
$ EXIT
$
$ SetupLog: v='F$VERIFY(0)'
$ outrate="0:0:01"
$ SET OUTPUT_RATE='outrate'
$ mylog=F$PARSE(F$GETQUI("DISPLAY_ENTRY","LOG_SPECIFICATION",,"THIS_JOB"),-
"SYS$LOGIN:.LOG;",F$GETQUI("DISPLAY_ENTRY","JOB_NAME",,"THIS_JOB"))
$ SHOW SYM mylog
$ OPEN/WRITE log SYS$LOGIN:OTHER.LOG
$ ON WARNING THEN GOSUB Logit
$ RETURN ! 'F$VERIFY(v)'
$
$ Logit: stat=$STATUS ! 'F$VERIFY(0)'
$ WAIT 'outrate'
$ WRITE log "Error status=''stat' at ''F$TIME()' Last 5 lines in ''mylog'"
$ WRITE log "-----"
$ PIPE TYPE/TAIL=5/HEADER 'mylog' > log
$ WRITE log "-----"
$ ON WARNING THEN GOSUB Logit
$ RETURN 1+0*F$VERIFY(v)

So, subroutine SetupLog finds the log file of the batch job, and creates a secondary log file. It also saves verification state and sets the output rate to a known value.
We then use:

$ ON WARNING THEN GOSUB Logit

to execute a subroutine any time a WARNING or higher condition occurs.

Subroutine Logit waits for the output rate period, to make sure any messages up to the warning event have been flushed to the log. It then writes a report line and dumps the last 5 lines of the file into the secondary log file. Finally it resets the ON WARNING condition and restores verification.

Note that the RETURN must return a success status, otherwise it will immediately call Logit again after returning (infinite loop). That means the only change from "normal" DCL in your mainline, is any additional processing of status needs to look at "stat" instead of $STATUS, (but you need to make sure an "old" value in "stat" isn't picked up later as it isn't automatically updated, like $STATUS).

Another option in communicating status back to the main line would be to use the unused success status 7 to indicate an error. So, the end of Logit could look like:

$ RETURN stat.OR.7+0*F$VERIFY(v)

Your mainline then knows an error or warning has occured if $SEVERITY is 7, and can retrieve the actual status (including the true severity) from "stat".

$ SUBMIT/QUEUE=noqueue nojob
$ IF $SEVERITY.EQ.7
$ THEN
$ WRITE SYS$OUTPUT "Submit failed - status ''stat'"
$ ENDIF

Have fun!
A crucible of informative mistakes
Joost van der Knaap
Occasional Advisor

Re: DCL command 'SUBMIT' exit status check

@everyone: Thanks for all the suggestions.
As usual in DCL, there seem to be plenty ways of going about it.

Per John Gillings' last remark - I'm off to have fun with this.