4 * This file contains functions for manipulating Tcl file handles.
6 * Copyright (c) 1995 Sun Microsystems, Inc.
8 * See the file "license.terms" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 * SCCS: @(#) tclFHandle.c 1.9 96/07/01 15:41:26
19 * The FileHashKey structure is used to associate the OS file handle and type
20 * with the corresponding notifier data in a FileHandle.
23 typedef struct FileHashKey {
24 int type; /* File handle type. */
25 ClientData osHandle; /* Platform specific OS file handle. */
28 typedef struct FileHandle {
29 FileHashKey key; /* Hash key for a given file. */
30 ClientData data; /* Platform specific notifier data. */
31 Tcl_FileFreeProc *proc; /* Callback to invoke when file is freed. */
35 * Static variables used in this file:
38 static Tcl_HashTable fileTable; /* Hash table containing file handles. */
39 static int initialized = 0; /* 1 if this module has been initialized. */
42 * Static procedures used in this file:
45 static void FileExitProc _ANSI_ARGS_((ClientData clientData));
48 *----------------------------------------------------------------------
52 * This function retrieves the file handle associated with a
53 * platform specific file handle of the given type. It creates
54 * a new file handle if needed.
57 * Returns the file handle associated with the file descriptor.
60 * Initializes the file handle table if necessary.
62 *----------------------------------------------------------------------
66 Tcl_GetFile(osHandle, type)
67 ClientData osHandle; /* Platform specific file handle. */
68 int type; /* Type of file handle. */
71 Tcl_HashEntry *entryPtr;
75 Tcl_InitHashTable(&fileTable, sizeof(FileHashKey)/sizeof(int));
76 Tcl_CreateExitHandler(FileExitProc, 0);
79 key.osHandle = osHandle;
81 entryPtr = Tcl_CreateHashEntry(&fileTable, (char *) &key, &new);
83 FileHandle *newHandlePtr;
84 newHandlePtr = (FileHandle *) ckalloc(sizeof(FileHandle));
85 newHandlePtr->key = key;
86 newHandlePtr->data = NULL;
87 newHandlePtr->proc = NULL;
88 Tcl_SetHashValue(entryPtr, newHandlePtr);
91 return (Tcl_File) Tcl_GetHashValue(entryPtr);
95 *----------------------------------------------------------------------
99 * Deallocates an entry in the file handle table.
107 *----------------------------------------------------------------------
114 Tcl_HashEntry *entryPtr;
115 FileHandle *handlePtr = (FileHandle *) handle;
118 * Invoke free procedure, then delete the handle.
121 if (handlePtr->proc) {
122 (*handlePtr->proc)(handlePtr->data);
126 * Tcl_File structures may be freed as a result of running the
127 * channel table exit handler. The file table is freed by the file
128 * table exit handler, which may run before the channel table exit
129 * handler. The file table exit handler sets the "initialized"
130 * variable back to zero, so that the Tcl_FreeFile (when invoked
131 * from the channel table exit handler) can notice that the file
132 * table has already been destroyed. Otherwise, accessing a
133 * deleted hash table would cause a panic.
137 entryPtr = Tcl_FindHashEntry(&fileTable, (char *) &handlePtr->key);
139 Tcl_DeleteHashEntry(entryPtr);
142 ckfree((char *) handlePtr);
146 *----------------------------------------------------------------------
150 * This function retrieves the platform specific file data and
151 * type from the file handle.
154 * If typePtr is not NULL, sets *typePtr to the type of the file.
155 * Returns the platform specific file data.
160 *----------------------------------------------------------------------
164 Tcl_GetFileInfo(handle, typePtr)
168 FileHandle *handlePtr = (FileHandle *) handle;
171 *typePtr = handlePtr->key.type;
173 return handlePtr->key.osHandle;
177 *----------------------------------------------------------------------
179 * Tcl_SetNotifierData --
181 * This function is used by the notifier to associate platform
182 * specific notifier information and a deletion procedure with
189 * Updates the data and delProc slots in the file handle.
191 *----------------------------------------------------------------------
195 Tcl_SetNotifierData(handle, proc, data)
197 Tcl_FileFreeProc *proc;
200 FileHandle *handlePtr = (FileHandle *) handle;
201 handlePtr->proc = proc;
202 handlePtr->data = data;
206 *----------------------------------------------------------------------
208 * Tcl_GetNotifierData --
210 * This function is used by the notifier to retrieve the platform
211 * specific notifier information associated with a file handle.
214 * Returns the data stored in a file handle by a previous call to
215 * Tcl_SetNotifierData, and places a pointer to the free proc
216 * in the location referred to by procPtr.
221 *----------------------------------------------------------------------
225 Tcl_GetNotifierData(handle, procPtr)
227 Tcl_FileFreeProc **procPtr;
229 FileHandle *handlePtr = (FileHandle *) handle;
230 if (procPtr != NULL) {
231 *procPtr = handlePtr->proc;
233 return handlePtr->data;
237 *----------------------------------------------------------------------
241 * This function an exit handler that frees any memory allocated
242 * for the file handle table.
248 * Cleans up the file handle table.
250 *----------------------------------------------------------------------
254 FileExitProc(clientData)
255 ClientData clientData; /* Not used. */
257 Tcl_DeleteHashTable(&fileTable);