Program termination: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|PostScript}}: - This is postscript!)
Line 454: Line 454:
endif;</lang>
endif;</lang>


=={{header|PowerShell}}==
=={{header|PostScript}}==
There are two ways which differ slightly:
There are two ways which differ slightly:
<lang postscript>condition {stop} if</lang>
<lang postscript>condition {stop} if</lang>

Revision as of 08:01, 27 March 2011

Task
Program termination
You are encouraged to solve this task according to the task description, using any language you may know.

Show the syntax for a complete stoppage of a program inside a conditional. This includes all threads/processes which are part of your program.

Explain the cleanup (or lack thereof) caused by the termination (allocated memory, database connections, open files, object finalizers/destructors, run-on-exit hooks, etc.). Unless otherwise described, no special cleanup outside that provided by the operating system is provided.

Ada

Ada programs execute in one or more tasks. All tasks created during the execution of a program depend in a hierarchical manner on the task that create them, except for the environment task which executes the "main" procedure for the program. Each task will abort (terminate abnormally) if the task upon which it depends is aborted. This approach to task termination is not recommended because it does not allow tasks to terminate in a known state.

However, this Rosetta Code task requires a simple stoppage of the program including all tasks. The simple way to achieve this is to abort the environment task.

<lang ada>with Ada.Task_Identification; use Ada.Task_Identification;

procedure Main is

  -- Create as many task objects as your program needs

begin

  -- whatever logic is required in your Main procedure
  if some_condition then
     Abort_Task (Current_Task);
  end if;

end Main;</lang> Aborting a task with Abort_Task is equivalent to abort statement, which is not used here because the environment task object is anonymous. The semantics of abort is as follows:

  • Abort is deferred until certain unbreakable actions are accomplished. These are protected actions on shared objects, initialization, assignment, and finalization of controlled objects, waiting for dependent tasks to be aborted;
  • Local objects of the task are finalized;
  • The tasks dependent on the aborted task are aborted.
  • The state of external files will depend on the OS

The above is a preemptive way to abort tasks, which is not recommended to use, unless you firmly know what you are doing. A standard approach to such termination is either (or a combination of):

  • to provide an entry in each task created by the environment task which, when called by the task upon which it depends, causes the called task to terminate in a known state;
  • to provide "terminate" alternative open in each of such tasks.

In both cases the task objects are made local or otherwise destroyed upon completion of the main task. Note that destruction of a task always waits for its termination. If the task refuses to terminate it deadlocks.

With the first approach: <lang ada>procedure Main is

  -- Create as many task objects as your program needs

begin

  -- whatever logic is required in your Main procedure
  if some_condition then
     -- for each task created by the Main procedure
     The_task.Stop;
     -- end the Main procedure
     return;  -- actually, this is not needed
  end if;

end Main;</lang> A task might look like: <lang ada>task body Some_Task is begin

  loop
     select
        -- Some alternatives
        ...
     or accept Stop do
           -- Some cleanup while holding the caller is here
        end Stop;
           -- A cleanup asynchronous to the caller is here
        exit; -- We are through
     end select
  end loop;

end Some_Task;</lang> With the second approach one simply returns from Main and all tasks are terminated by selecting the terminate alternative. Such tasks might look like: <lang ada>task body Some_Task is begin

  loop
     select
        -- Some alternatives
        ...
     or terminate; -- We are through
     end select
  end loop;

end Some_Task;</lang>

ALGOL 68

The label "stop" appears at the start of the standard-postlude and can be invoked to terminate any program. <lang algol68>IF problem = 1 THEN

  stop

FI</lang> The standard-postlude closes any opens files and basically wraps up execution.

AWK

<lang awk>if(problem)exit 1</lang>

AppleScript

AppleScript doesn't include a built-in command for immediate script termination. The return command can be used to exit the main run handler, but will not force termination of the entire script from another handler/function. <lang AppleScript >on run If problem then return end run</lang>It's possible to simulate an immediate program termination from within any handler by throwing a user error, but this will force a modal dialog (AppleScript Error) to appear announcing the error. Such a dialog cannot be bypassed, and the script immediately quits upon user acknowledgement. <lang AppleScript >on run f() display dialog "This message will never be displayed." end run

on f() error end f</lang>Memory is automatically managed and reclaimed by AppleScript.

AutoHotkey

<lang AutoHotkey>If (problem)

 ExitApp</lang>

AutoIt

Then Endif is entirely unnecessary, but it is good form. <lang AutoIt>If problem Then

 Exit

Endif</lang>

BASIC

Works with: QuickBasic version 4.5

<lang qbasic>if problem = 1 then

  end

end if</lang>

Applesoft BASIC

<lang Applesoft BASIC>10 IF 1 THEN STOP</lang>

ZX Spectrum Basic

The ZX Spectrum has a STOP command, rather than an END command:

<lang basic> 10 LET a = 1: LET b = 1 20 IF a = b THEN GO TO 9995

9995 STOP </lang>

Batch File

<lang dos>if condition exit</lang> In Windows batch files this doesn't need to exit the program but instead can also just exit a subroutine. exit /b can also be used alternatively if a return value if desired.

C

<lang c>#include <stdlib.h>

if(problem){

 exit(integerErrorCode);
 /* conventionally, error code 0 or EXIT_SUCCESS is the code for "OK",
    EXIT_FAILURE is the code for "not OK",
    while anything else is a problem that is implementation-defined */
 /*optionally: return the integerErrorCode from the main() function*/

}</lang>

The atexit() function (also in stdlib.h) can be used to register functions to be run when the program exits. Registered functions will be called in the reverse order in which they were registered.

<lang c>#include <stdlib.h>

if(problem){

 abort();

}</lang> Unlike exit(), abort() will not do any cleanup other than the normal OS one. Also, it may cause other actions like producing a core dump or starting a debugger.

C++

There are several ways to terminate a program. The following is mostly the same as in C: <lang cpp>#include <cstdlib>

void problem_occured() {

 std::exit(EXIT_FAILURE);

}</lang> The argument is the return value passed to the operating system. Returning 0 or the EXIT_SUCCESS signals successful termination to the calling process, EXIT_FAILURE signals failure. The meaning of any other value is implementation defined.

On calling std::exit, all functions registered with std::atexit are called, and the destructors of all objects at namespace scope, as well as of all static objects already constructed, are called. However the destructors of automatic objects (i.e. local variables) are not called (and of course, objects allocated with new will not be destructed as well, except if one of the called destructors destroys them). Due to this inconsistency calling std::exit is often not a good idea.

<lang cpp>#include <cstdlib>

void problem_occured() {

 std::abort();

}</lang> Unlike std::exit, std::abort will not do any cleanup other than the normal OS one. Also, it may cause other actions like producing a core dump or starting a debugger.

<lang cpp>#include <exception>

void problem_occured() {

 std::terminate();

}</lang> The function std::terminate is what is automatically called when certain exception related failures happen. However it also can be called directly. By default it just calls abort, but unlike abort, its behaviour can be overridden with std::set_terminate (but it still must terminate the program in one way or anouther). Thererfore the amount of cleanup it does depends on whether it was overridden, and what the overridden function does.

Note that returning a value from main is mostly equivalent to calling std::exit with the returned value, except that automatic variables are correctly destructed. If one wants to return from an inner function, while still doing complete cleanup, a solution is to throw an exception caught in main (this will call the destructors of non-main local variables during stack unwinding), and to then return normally from main (which will destruct all automatic objects in main, and then do the cleanup like std::exit.

C#

<lang csharp>if (problem) {

  Environment.Exit(1);

}</lang>

Clojure

Translation of: Java

The call System.exit does not finalize any objects by default. This default is to keep the program thread-safe. From the javadocs for the method to change this default: "may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock." <lang clojure>(if problem

  (. System exit integerErrorCode))
  ;conventionally, error code 0 is the code for "OK",
  ; while anything else is an actual problem
  ;optionally: (-> Runtime (. getRuntime) (. exit integerErrorCode))

}</lang>

You can use (-> Runtime (. getRuntime) (. addShutdownHook myThread)) to add threads which represent actions to be run when the program exits.

This one does not perform cleanup: <lang clojure>(if problem

  (-> Runtime (. getRuntime) (. halt integerErrorCode)))
  ; conventionally, error code 0 is the code for "OK",
  ; while anything else is an actual problem

</lang>


Common Lisp

Many Common Lisp implementations provide a function named quit or sometimes exit which will exit the Lisp system; its parameters and the package it is in vary, but here are some implementations' versions, with a Unix-style exit status argument, and a fallback:

<lang lisp>(defun terminate (status)

 #+sbcl     (sb-ext:quit      :unix-status status)    ; SBCL
 #+ccl      (   ccl:quit      status)                 ; Clozure CL
 #+clisp    (   ext:quit      status)                 ; GNU CLISP
 #+cmu      (  unix:unix-exit status)                 ; CMUCL
 #+abcl     (   ext:quit      :status status)         ; Armed Bear CL
 #+allegro  (  excl:exit      status :quiet t)        ; Allegro CL
 (cl-user::quit))           ; Many implementations put QUIT in the sandbox CL-USER package.</lang>

There is no standard form because the Common Lisp standard does not assume the presence of an operating system outside of the Lisp environment to exit to.

What cleanup will be performed varies. Some implementations have at-exit hooks. SBCL will unwind the stack and execute any unwind-protects (like finally in other languages) it encounters, unless :recklessly-p t is specified.

E

Exit indicating successful completion:

<lang e>if (true) {

   interp.exitAtTop()

}</lang>

Exit indicating some problem:

<lang e>if (true) {

   interp.exitAtTop("because the task said so")

}</lang>

Both of these have the same effect with regard to cleanup as as reaching the end of the main program. [To do: Find out what effect that is.]

Forth

<lang forth>debug @ if QUIT \ quit back to the interpreter else BYE \ exit forth environment completely (e.g. end of a Forth shell script) then</lang>

Fortran

In Fortran STOP stops the execution of the main process and its "children" (tested with OpenMP; if using POSIX threads, I think the stop behaves almost like C exit). Allocated memory or any other resource except opened file (which are closed) is not cleaned up.

<lang fortran>IF (condition) STOP [message] ! message is optional and is a character string. ! If present, the message is output to the standard output device.</lang>

Gema

Terminate with an error message and a non-zero status code if "Star Trek" is found in the input stream. <lang gema> Star Trek=@err{found a Star Trek reference\n}@abort </lang>

Go

<lang go>import "os"

if problem {

 os.Exit(integerErrorCode)
 /* conventionally, error code 0 or EXIT_SUCCESS is the code for "OK",
    EXIT_FAILURE is the code for "not OK",
    while anything else is a problem that is implementation-defined */

}</lang>

Haskell

<lang haskell>import Control.Monad import System.Exit

when problem do

   exitWith ExitSuccess                    -- success
   exitWith (ExitFailure integerErrorCode) -- some failure with code
   exitSuccess                             -- success; in GHC 6.10+
   exitFailure                             -- generic failure</lang>

The above shows how to exit a thread. When the main thread exits, all other threads exit, and the return code in the exit call is the return code of the program. When any thread other than the main thread exits, only it is stopped, and if the exit code is not ExitSuccess, it is printed.

HicEst

<lang HicEst>ALARM( 999 ) </lang>

This closes windows, dialogs, files, DLLs, and frees allocated memory. Script editing is resumed on next start.

Icon and Unicon

<lang Icon>exit(i) # terminates the program setting an exit code of i stop(x1,x2,..) # terminates the program writing out x1,..; if any xi is a file writing switches to that file runerr(i,x) # terminates the program with run time error 'i' for value 'x'</lang>

J

Given condition, an integer which is zero if everything's OK (and we should NOT exit), or a non-zero exit code if there's a problem (and we should exit), then:

Tacit version: <lang j>2!:55^:] condition</lang>

Explicit version: <lang j>3 : 'if. 0~: condition do. 2!:55 condition end.'</lang>

Java

The call System.exit does not finalize any objects by default. This default is to keep the program thread-safe. From the javadocs for the method to change this default: "may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock." <lang java>if(problem){

  System.exit(integerErrorCode); 
  //conventionally, error code 0 is the code for "OK",
  // while anything else is an actual problem
  //optionally: Runtime.getRuntime().exit(integerErrorCode);

}</lang>

You can use Runtime.getRuntime().addShutdownHook(myThread); to add threads which represent actions to be run when the program exits.

This one does not perform cleanup: <lang java>if(problem){

  Runtime.getRuntime().halt(integerErrorCode); 
  //conventionally, error code 0 is the code for "OK",
  // while anything else is an actual problem

}</lang>

JavaScript

Works with: SpiderMonkey

The quit() function exits the shell. <lang javascript>if (some_condition)

   quit();</lang>

Works with: UCB Logo

<lang logo>bye  ; exits to shell

throw "toplevel  ; exits to interactive prompt

pause  ; escapes to interactive prompt for debugging continue  ; resumes after a PAUSE</lang>

Lua

<lang lua>if some_condition then

   os.exit( number )

end</lang>

M4

<lang M4>beginning define(`problem',1) ifelse(problem,1,`m4exit(1)') ending</lang>

Output:

beginning

Mathematica

<lang Mathematica>If[problem, Abort[]];</lang> Kernels stop all computation after "Abort[]" command. But the kernels are still operational, and all definitions are still available. Note that an Abort[] can be caught by a calling function using CheckAbort, in which case the computation will continue at that place.

Quit[]

This will completely quit the kernel. All definitions will be lost. Since this terminates the actual kernel process, this will also free all resources used by that kernel (especially memory). Note however that if the kernel is interactively used through a notebook, the notebook still remains operable.

MATLAB

<lang matlab>if condition

   return

end</lang>

There is no special way to stop a program. You can terminate it by calling return.

<lang matlab>if condition

   quit

end</lang>

The quit function runs the MATLAB script finish.m, if it exists, and terminates MATLAB completely.

Nimrod

<lang Nimrod>if problem:

 quit(QuitFailure)

</lang>

Objeck

The code below, will terminate a program without any cleanup.

<lang objeck> if(problem) {

 Runtime->Exit(1);

}; </lang>

OCaml

<lang ocaml>if problem then

 exit integerErrorCode;
 (* conventionally, error code 0 is the code for "OK",
    while anything else is an actual problem *)</lang>

The at_exit function can be used to register functions to be run when the program exits. Registered functions will be called in the reverse order in which they were registered.

Oz

<lang oz>if Problem then {Application.exit 0} end</lang> All threads exit. All processes (local and remote) exit unless they were created with detach:true. Finalizers are not executed (unless enforced with {System.gcDo}).

PARI/GP

<lang>if(stuff, quit)</lang>

Perl

<lang perl>if ($problem) {

   exit integerErrorCode;
   # conventionally, error code 0 is the code for "OK"
   #  (you can also omit the argument in this case)
   # while anything else is an actual problem

}</lang>

exit() will run any cleanup code that is in an END block.

PHP

<lang php>if (problem)

   exit(1);</lang>

The register_shutdown_function() function can be used to register functions to be run when the program exits.

PicoLisp

Calling 'bye', optionally with a numeric code, terminates the program.

This will execute all pending 'finally' expressions, close all open files and/or pipes, flush standard output, and execute all expressions in the global variable '*Bye' before exiting. <lang PicoLisp>(push '*Bye '(prinl "Goodbye world!")) (bye)</lang> Output:

Goodbye world!
$

PL/I

<lang PL/I> STOP; /* terminates the entire program */

     /* PL/I does any required cleanup, such as closing files. */

</lang>

<lang> STOP THREAD (tiger); /* terminates only thread "tiger". */ </lang>

<lang> SIGNAL FINISH; /* terminates the entire program. */

              /* PL/I does any required cleanup,  */
              /* such as closing files.           */

</lang>

PostScript

<lang postscript> 100 10 gt {quit} if </lang>

Pop11

This example may be incorrect due to a recent change in the task requirements or a lack of testing. Please verify it and remove this message. If the example does not match the requirements or does not work, replace this message with Template:incorrect or fix the code yourself.

<lang pop11>if condition then

   sysexit();

endif;</lang>

PostScript

There are two ways which differ slightly: <lang postscript>condition {stop} if</lang> will terminate a so-called stopped context which is a way of executing a block of code and catching errors that occur within. Any user program will always run in such a context and therefore be terminated upon calling stop

Neither the operand stack nor the dictionary stack are touched or cleaned up when calling stop. Anything pushed onto either stack will remain there afterwards. <lang postscript>condition {quit} if</lang> will terminate the PostScript interpreter. This is definitely a way to stop the current program but since an interpreter can run multiple programs at the same time, this should rarely, if ever, be used.

PowerShell

<lang powershell>if (somecondition) {

   exit

}</lang> This ends the scope for any non-global variables defined in the script. No special cleanup is performed.

Prolog

Terminate Prolog execution. Open files are closed. Exits the Interpreter.

<lang prolog>halt.</lang>

Terminate Prolog execution but don't exit the Interpreter. <lang prolog>abort.</lang>

PureBasic

This will free any allocated memory, close files and free other resources (i.e. windows, gadgets, threads, space for variable, etc.) that were set aside during execution of any PureBasic commands in the program. <lang PureBasic>If problem = 1

  End

EndIf</lang> It is possible to also access outside resources (i.e. via an OS API or linked library), and those items may or may not be cleaned up properly.

Python

<lang python>import sys if problem:

   sys.exit(1)</lang>

The atexit module allows you to register functions to be run when the program exits.

No cleanup is performed: <lang python>import os if problem:

   os.abort()</lang>

R

<lang R>if(problem) q(status=10)</lang>

REBOL

The quit word stops all evaluation, releases operating system resources and exits the interpreter. <lang REBOL>if error? try [6 / 0] [quit]</lang> A return value can be provided to the operating system: <lang REBOL>if error? try [dangerous-operation] [quit/return -12]</lang> Because of REBOL's tightly integrated REPL, you can also use q to do the same thing. <lang REBOL>if error? try [something-silly] [q/return -12]</lang> Since GUI programs are often developed from the REPL, a special halt word is provided to kill the GUI and return to the REPL. No cleanup is done and the GUI is still displayed (although halted). You can restart it with the do-events word. <lang REBOL>view layout [button "stopme" [halt]]</lang>

Retro

<lang Retro>problem? [ bye ] ifTrue</lang>

REXX

In REXX, the REXX interpretor takes care of the closing of any open files (or any I/O streams), as well as any memory management (cleanup). <lang rexx> /*REXX program showing five ways to do program termination. */


exit


exit (expression)


return /*which returns to this program's invoker. */

                      /*If this is the main body (and not a subroutine)*/
                      /*the REXX interperter terminates the program.   */


return (expression)


   /*control*/
   /*       */
   /*   |   */        /*if there is no EXIT and program control "falls */
   /*   |   */        /*through" to the "bottom" (end) of the program, */
   /*   |   */        /*an   EXIT   is simulated and the program is    */
   /*   |   */        /*terminated.                                    */
   /*   V   */
   /* e o f */

</lang>

Ruby

<lang ruby>if problem

   exit(1)

end</lang> or <lang ruby>if problem

   abort # equivalent to exit(1)

end</lang>

You can use at_exit { ... } to register a block of code which will be run when the program exits. Registered handlers will be called in the reverse order in which they were registered.

Slate

<lang slate>problem ifTrue: [exit: 1].</lang>

Scheme

Works with: Scheme version R6RS

<lang scheme>(if problem

 (exit)) ; exit successfully</lang>

or <lang scheme>(if problem

 (exit #f)) ; exit unsuccessfully</lang>

or <lang scheme>(if problem

 (exit some-value)) ; converts "some-value" into an appropriate exit code for your system</lang>

SNOBOL4

Conditional transfer to the required END label causes immediate termination and normal cleanup. In this example, if condition succeeds (is true), the value of errlevel is assigned to the &code keyword as the exit status of the program, and the :s( ) goto transfers control to END.

<lang SNOBOL4> &code = condition errlevel :s(end)</lang>

Standard ML

This example may be incorrect due to a recent change in the task requirements or a lack of testing. Please verify it and remove this message. If the example does not match the requirements or does not work, replace this message with Template:incorrect or fix the code yourself.

<lang sml>if problem then

 OS.Process.exit OS.Process.failure
 (* valid status codes include OS.Process.success and OS.Process.failure *)

else

 ()</lang>

The OS.Process.atExit function can be used to register functions to be run when the program exits. Registered functions will be called in the reverse order in which they were registered.

no cleanup performed: <lang sml>if problem then

 OS.Process.terminate OS.Process.failure
 (* valid status codes include OS.Process.success and OS.Process.failure *)

else

 ()</lang>

Tcl

The language runtime (in C) includes a mechanism for cleaning up open resources when the application quits, but access to this is not exposed at script level; extension packages just register with it automatically when required. At the script level, all that is needed to make the program terminate is the exit command: <lang tcl>if {$problem} {

   # Print a “friendly” message...
   puts stderr "some problem occurred"
   # Indicate to the caller of the program that there was a problem
   exit 1

}</lang> Alternatively, in a top-level script but not an event handler: <lang tcl>if {$problem} {

   error "some problem occurred"

}</lang>

TI-83 BASIC

<lang ti83b>

 :Stop

</lang>

TI-89 BASIC

<lang ti89b>Prgm

 ...
 Stop
 ...

EndPrgm</lang>

TUSCRIPT

<lang tuscript> $$ MODE TUSCRIPT IF (condition==1) STOP -> execution stops and message: IF (condition==2) ERROR/STOP "condition ",condition, " Execution STOP " </lang>

Unlambda

`ei

Note: the argument to the e function is the return value of the program; however many implementation simply ignore it.

There are no objects to be cleaned up.

Vedit macro language

<lang vedit>if (#99 == 1) { Return } // Exit current macro. Return to calling macro. if (#99 == 2) { Break_Out() } // Stop all macro execution and return to command mode. if (#99 == 3) { Exit } // Exit Vedit. Prompt for saving any changed files. if (#99 == 4) { Exit(4) } // As above, but return specified value (instead of 0) to OS if (#99 == 5) { Xall } // Exit Vedit. Save changed files without prompting. if (#99 == 6) { Qall } // Exit Vedit. Do not save any files.</lang> Return or Break_Out() do not perform any cleanup. If needed, cleanup has to be done in the macro before exit. Special locked-in macro can be used to perform cleanup in case user presses Break key.

When exit from Vedit is done, all the cleanup is performed automatically. Note, however, that if Edit Restore is enabled or a project is open, the session state is saved. In this case, if your macro does not do cleanup, you may eventually run out of free text registers, and you have to do manual cleanup.

VBScript

No matter how deep you're in, wscript.quit will get you out.

<lang vb>dim i, j j = 0 do

   for i = 1 to 100
       while j < i
           if i = 3 then
               wscript.quit
           end if
       wend
   next

loop</lang>

Visual Basic

While the example listed under BASIC will work unaltered, it is a terrible idea to use the End keyword in VB. Doing so will cause the immediate termination of the program without any clean up -- forms and other things are left loaded in memory.

When the app needs to end, for whatever reason, problem or not, it's always a good idea to unload the forms first.

<lang vb>Sub Main()

   '...
   If problem Then
       For n& = Forms.Count To 0 Step -1
           Unload Forms(n&)
       Next
       Exit Sub
   End If
   '...

End Sub</lang>