Tcl_Exit(3)
π Tcl_Exit β ending the app (or just one thread) but make it graceful π
okay so bestie, welcome to another page of the Tcl Library Procedures manual, and this one is literally all about Tcl_Exit(3) and its whole little found family of exit-related functions. sit down, hydrate, we're ending applications the right way. π
β¨ NAME β¨
Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_ExitThread, Tcl_FinalizeThread, Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler, Tcl_SetExitProc β end the application or thread (and invoke exit handlers). that's the whole vibe. π¦
β¨ SYNOPSIS β¨
#include <tcl.h>
Tcl_Exit(status)
Tcl_Finalize()
Tcl_CreateExitHandler(proc, clientData)
Tcl_DeleteExitHandler(proc, clientData)
Tcl_ExitThread(status)
Tcl_FinalizeThread()
Tcl_CreateThreadExitHandler(proc, clientData)
Tcl_DeleteThreadExitHandler(proc, clientData)
Tcl_ExitProc *
Tcl_SetExitProc(proc)
like, that's a LOT of functions but they're all one big friend group, don't panic. π«Ά
β¨ ARGUMENTS β¨
int status (in)β tells everyone why the application or thread dipped out. ngl the exact meaning is platform-specific, so lowkey don't overthink it:0usually means a normal exit, and any nonzero value usually means something went wrong. πTcl_ExitProc *proc (in)β the procedure to invoke before exiting the application. or, forTcl_SetExitProc, you passNULLto uninstall the current application exit procedure. bye bye handler πvoid *clientData (in)β an arbitrary one-word value that gets passed along toproc. it's giving "here's a little something to remember me by" π
β¨ DESCRIPTION β¨
so the procedures on this page are the graceful way to end the execution of a Tcl application. exit handlers get invoked to clean up the application's state before Tcl code stops running. no mess, no chaos, we love a tidy departure. β¨
Invoke Tcl_Exit to end a Tcl application and to exit from this process. it's the one invoked by the exit Tcl command, and you can invoke it anywhere else too if you want to terminate the application. and listen β no-one should ever invoke the exit() system call directly. always invoke Tcl_Exit instead, so it can invoke exit handlers. also big heads-up: if other code invokes the exit() system call directly, or otherwise makes the application terminate without calling Tcl_Exit, then the exit handlers will not be run. π Tcl_Exit internally invokes the exit() system call, so it never returns control to its caller, periodt. and if an application exit handler has been installed (see Tcl_SetExitProc), that handler gets invoked with an argument consisting of the exit status (cast to void *); the application exit handler should not return control to Tcl.
Tcl_Finalize is basically Tcl_Exit's calmer sibling β similar, except it does not exit from the current process. it's the move when a process is done using Tcl but still wants to keep executing, and also when Tcl is used in a dynamically loaded extension that's about to be unloaded. your code should always invoke Tcl_Finalize when Tcl is being unloaded, so you get proper cleanup. good news though: Tcl_Finalize can be safely called more than once. slay, reentrant icon. π
Tcl_ExitThread is for terminating the current thread and invoking per-thread exit handlers. that finalization is actually done by Tcl_FinalizeThread, which you can call yourself if you just want to clean up per-thread state and invoke the thread exit handlers. and Tcl_Finalize calls Tcl_FinalizeThread for the current thread automatically, so it's got your back. π«Ά
Tcl_CreateExitHandler arranges for proc to be invoked by Tcl_Finalize and Tcl_Exit. Tcl_CreateThreadExitHandler arranges for proc to be invoked by Tcl_FinalizeThread and Tcl_ExitThread. this is your hook for cleanup operations like flushing buffers and freeing global memory. proc should match the type Tcl_ExitProc:
typedef void Tcl_ExitProc(
void *clientData);
the clientData parameter to proc is a copy of the clientData argument you gave to Tcl_CreateExitHandler or Tcl_CreateThreadExitHandler when the callback was created. typically, clientData points to a data structure containing application-specific info about what to do in proc. very "here's my little bag of secrets" energy. π
Tcl_DeleteExitHandler and Tcl_DeleteThreadExitHandler can be called to delete a previously-created exit handler. they remove the handler indicated by proc and clientData so that no call to proc will be made. and if no such handler exists? then Tcl_DeleteExitHandler or Tcl_DeleteThreadExitHandler does nothing. it's giving unbothered. π
Tcl_Finalize and Tcl_Exit execute all registered exit handlers in reverse order from the order in which they were registered. that matches the natural order in which extensions are loaded and unloaded: if extension A loads extension B, it usually unloads B before it itself is unloaded. so if extension A registers its exit handlers before loading extension B, this ensures that any exit handlers for B will be executed before the exit handlers for A. it's literally just stack vibes. last in, first out, no cap. π₯
Tcl_Finalize and Tcl_Exit call Tcl_FinalizeThread and the thread exit handlers after the process-wide exit handlers. why? because thread finalization shuts down the I/O channel system, so any attempt at I/O by the global exit handlers will vanish into the bitbucket. π gone. reduced to atoms.
Tcl_SetExitProc installs an application exit handler, returning the previously-installed application exit handler or NULL if no application handler was installed. if an application exit handler is installed, that exit handler takes over complete responsibility for finalization of Tcl's subsystems via Tcl_Finalize at an appropriate time. the argument passed to proc when it's invoked will be the exit status code (as passed to Tcl_Exit) cast to a void * value.
π¨ bestie, important: Tcl_SetExitProc can not be used in stub-enabled extensions. that's not a suggestion, that's the rule.
β¨ SEE ALSO β¨
β¨ KEYWORDS β¨
abort, callback, cleanup, dynamic loading, end application, exit, unloading, thread π
and that's the page, bestie!! go forth and end your applications gracefully, invoke Tcl_Exit instead of exit(), and never let your exit handlers get skipped. this one came from the Tcl 8.5 era of the Tcl Library Procedures, filed under Tcl_Exit(3) β mwah, take care of yourself, drink water, and delete your handlers when you're done with them πππ¦β¨
π¦ where this page comes from
- alpine 3.23: tcl9-doc 9.0.3-r0 Β· TCL
- alpine 3.24: tcl9-doc 9.0.3-r2 Β· TCL
- fedora 43: tcl-doc 1:9.0.2-1.fc43 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- fedora 44: tcl-doc 1:9.0.2-1.fc44 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- nixos 26.05: tcl 9.0.3
- nixpkgs unstable: tcl 9.1.0
- Copyright (c) 1995-1996 Sun Microsystems, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms