.title exit Exit from C programs .ident /000008/ .list meb,bex ; ;+ ; ; Index Normal exit from C programs ; Index Exit with status code ; Index $$exst -- Exit status code ; ; Usage ; ; exit(status); /* Exit, no return */ ; ; exits(status); /* Exit with status */ ; ; $$fail(); /* Immediate exit */ ; ; extern int $$exst; /* Exit status value */ ; ; Internal ; ; jmp $$exit ;Call exit routine ; ; Description ; ; On exit, the following sequence occurs: ; 1. The user-supplied wrapup() function is called. ; 2. User-supplied finalizers are called. ; 3. Profiles (if requested) are printed. ; 4. All files are closed. ; 5. The program exits to the operating system. ; ; By calling exits() with an appropriate value, the program can ; pass an exit status code to the operating system monitor. ; The RT11 and RSX11 monitors define exit status codes differently; ; the value passed to exits() is not checked for consistancy. ; ; RT11 RSX Meaning ; 1. 1. IO_SUCCESS -- no message is printed ; 2. 0. IO_WARNING -- minor error ; 4. 2. IO_ERROR -- serious error ; 8. 4. IO_FATAL -- severe error ; ; Calling exit() with some other value is equivalent to ; calling exits(IO_SUCCESS). This is compatible with ; Unix programs that exit by calling exit() without parameters. ; ; Note that the program may also set a value into $$exst ; and exit via exit(): ; ; extern int $$exst; ; ; ... ; ; $$exst = IO_WARNING; ; exit(); ; ; If the program calls, or jumps to, $$fail, it will immediately ; exit to the operating system without closing files, calling ; wrapup() or finalizers, or writing a profile file. ; ; Diagnostics ; ; Bugs ; ;- ; ; Edit history: ; 000001 22-May-80 MM From scratch ; 000002 21-Jul-80 MM Added exits() ; 000003 22-Jul-80 MM Globalized $$exst ; 000004 24-Nov-81 SDR Don't force line-feed on exit ; 000005 08-Feb-82 MM Fixed edit 04 per SDR source. ; 000006 27-Jun-82 MM New library ; 000007 04-Nov-82 MM Psect fix ; 000008 22-Nov-82 JSL Finalizer support; put code in the right psect! ; (Based on a preliminary 19-Jul-82 version) ; .iif ndf rsx rsx = 1 ;Assume RSX11M .if ne rsx .mcall exit$s, exst$s ;02 .iff .mcall .print, .exit ;02 USERRB = 53 ; User error code byte ;02 .endc .globl wrapup ;08 .psect c$data $$exst:: .word 1 ;Presuppose "normal" exit ;02/03 exitfl: .byte -2 ;-1 during wrapup(), finalizers; 0 during library exit .even ; ;08+ ; Stuff for finalizers - must declare all 3 psects! ; .psect $finl finl: ;Start of finalizer list .word wrapup ;Treat wrapup() as the first finalizer .psect $finl$ ;The list itself .psect $finl. finle: ;End of the finalizer list ;08- .psect c$code ;07 exits:: ;02 mov 2(sp),$$exst ;Set exit code and exit ;02/03/06+ br $$exit ; exit:: mov 2(sp),r0 ;User supplied parameter? bmi $$exit ;Nope cmp r0,#E$$XFA ;Bigger than IO_FATAL? bgt $$exit ;Can't use it then. mov r0,$$exst ;Set exit code ;06- $$exit:: incb exitfl ;Are we exiting? beq 20$ ;Br if here twice bpl $$fail ;Br if here too often ; ;08+ ; Call finalizers ; ; Warning: The code here depends on two facts: ; - There is always at least one finalizer (wrapup()) ; - This code cannot be entered except by flowing into it. If ; either of these does not hold, it is necessary to add a branch ; over the call so that r2 can be tested against finle BEFORE it ; is used. ; mov #finl,r2 ;-> First finalizer 10$: call @(r2)+ ;Call the next one cmp r2,#finle ;Any more? blo 10$ ;Do them, too ;08- 20$: call $$cl16 ;Close all channels ; ; We call the profiler after closing files to make sure there's a ; free logical unit and buffer space ; call @$$pptr ;Profiler .if ne rsx ;RSX11M ; ; Flush stderr, note: this depends on stderr not being in the lun table ; mov stderr,-(sp) ;Force out any pending line ;04 call fflush ;to the user's terminal ;04/05 .endc $$fail:: ;Very hard exit .if ne rsx EXST$S $$exst ;Return status code ;02/03 EXIT$S ;Back to RSX (EXST$ not emulated) ;02 .iff bisb $$exst,@#USERRB ;Stuff status code ;02/03 clr r0 ;Hard exit .exit .endc .end