Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libtksh/tcl/tclFHandle.c
1810 views
1
/*
2
* tclFHandle.c --
3
*
4
* This file contains functions for manipulating Tcl file handles.
5
*
6
* Copyright (c) 1995 Sun Microsystems, Inc.
7
*
8
* See the file "license.terms" for information on usage and redistribution
9
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10
*
11
* SCCS: @(#) tclFHandle.c 1.8 96/06/27 15:31:34
12
*/
13
14
#include "tcl.h"
15
#include "tclInt.h"
16
#include "tclPort.h"
17
18
/*
19
* The FileHashKey structure is used to associate the OS file handle and type
20
* with the corresponding notifier data in a FileHandle.
21
*/
22
23
typedef struct FileHashKey {
24
int type; /* File handle type. */
25
ClientData osHandle; /* Platform specific OS file handle. */
26
} FileHashKey;
27
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. */
32
} FileHandle;
33
34
/*
35
* Static variables used in this file:
36
*/
37
38
static Tcl_HashTable fileTable; /* Hash table containing file handles. */
39
static int initialized = 0; /* 1 if this module has been initialized. */
40
41
/*
42
* Static procedures used in this file:
43
*/
44
45
static void FileExitProc _ANSI_ARGS_((ClientData clientData));
46
47
/*
48
*----------------------------------------------------------------------
49
*
50
* Tcl_GetFile --
51
*
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.
55
*
56
* Results:
57
* Returns the file handle associated with the file descriptor.
58
*
59
* Side effects:
60
* Initializes the file handle table if necessary.
61
*
62
*----------------------------------------------------------------------
63
*/
64
65
Tcl_File
66
Tcl_GetFile(osHandle, type)
67
ClientData osHandle; /* Platform specific file handle. */
68
int type; /* Type of file handle. */
69
{
70
FileHashKey key;
71
Tcl_HashEntry *entryPtr;
72
int new;
73
74
if (!initialized) {
75
Tcl_InitHashTable(&fileTable, sizeof(FileHashKey)/sizeof(int));
76
Tcl_CreateExitHandler(FileExitProc, 0);
77
initialized = 1;
78
}
79
key.osHandle = osHandle;
80
key.type = type;
81
entryPtr = Tcl_CreateHashEntry(&fileTable, (char *) &key, &new);
82
if (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);
89
}
90
91
return (Tcl_File) Tcl_GetHashValue(entryPtr);
92
}
93
94
/*
95
*----------------------------------------------------------------------
96
*
97
* Tcl_FreeFile --
98
*
99
* Deallocates an entry in the file handle table.
100
*
101
* Results:
102
* None.
103
*
104
* Side effects:
105
* None.
106
*
107
*----------------------------------------------------------------------
108
*/
109
110
void
111
Tcl_FreeFile(handle)
112
Tcl_File handle;
113
{
114
Tcl_HashEntry *entryPtr;
115
FileHandle *handlePtr = (FileHandle *) handle;
116
117
/*
118
* Invoke free procedure, then delete the handle.
119
*/
120
121
if (handlePtr->proc) {
122
(*handlePtr->proc)(handlePtr->data);
123
}
124
125
/*
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.
134
*/
135
136
if (initialized) {
137
entryPtr = Tcl_FindHashEntry(&fileTable, (char *) &handlePtr->key);
138
if (entryPtr) {
139
Tcl_DeleteHashEntry(entryPtr);
140
}
141
}
142
ckfree((char *) handlePtr);
143
}
144
145
/*
146
*----------------------------------------------------------------------
147
*
148
* Tcl_GetFileInfo --
149
*
150
* This function retrieves the platform specific file data and
151
* type from the file handle.
152
*
153
* Results:
154
* If typePtr is not NULL, sets *typePtr to the type of the file.
155
* Returns the platform specific file data.
156
*
157
* Side effects:
158
* None.
159
*
160
*----------------------------------------------------------------------
161
*/
162
163
ClientData
164
Tcl_GetFileInfo(handle, typePtr)
165
Tcl_File handle;
166
int *typePtr;
167
{
168
FileHandle *handlePtr = (FileHandle *) handle;
169
170
if (!handlePtr)
171
return 0;
172
if (typePtr) {
173
*typePtr = handlePtr->key.type;
174
}
175
return handlePtr->key.osHandle;
176
}
177
178
/*
179
*----------------------------------------------------------------------
180
*
181
* Tcl_SetNotifierData --
182
*
183
* This function is used by the notifier to associate platform
184
* specific notifier information and a deletion procedure with
185
* a file handle.
186
*
187
* Results:
188
* None.
189
*
190
* Side effects:
191
* Updates the data and delProc slots in the file handle.
192
*
193
*----------------------------------------------------------------------
194
*/
195
196
void
197
Tcl_SetNotifierData(handle, proc, data)
198
Tcl_File handle;
199
Tcl_FileFreeProc *proc;
200
ClientData data;
201
{
202
FileHandle *handlePtr = (FileHandle *) handle;
203
handlePtr->proc = proc;
204
handlePtr->data = data;
205
}
206
207
/*
208
*----------------------------------------------------------------------
209
*
210
* Tcl_GetNotifierData --
211
*
212
* This function is used by the notifier to retrieve the platform
213
* specific notifier information associated with a file handle.
214
*
215
* Results:
216
* Returns the data stored in a file handle by a previous call to
217
* Tcl_SetNotifierData, and places a pointer to the free proc
218
* in the location referred to by procPtr.
219
*
220
* Side effects:
221
* None.
222
*
223
*----------------------------------------------------------------------
224
*/
225
226
ClientData
227
Tcl_GetNotifierData(handle, procPtr)
228
Tcl_File handle;
229
Tcl_FileFreeProc **procPtr;
230
{
231
FileHandle *handlePtr = (FileHandle *) handle;
232
if (procPtr != NULL) {
233
*procPtr = handlePtr->proc;
234
}
235
return handlePtr->data;
236
}
237
238
/*
239
*----------------------------------------------------------------------
240
*
241
* FileExitProc --
242
*
243
* This function an exit handler that frees any memory allocated
244
* for the file handle table.
245
*
246
* Results:
247
* None.
248
*
249
* Side effects:
250
* Cleans up the file handle table.
251
*
252
*----------------------------------------------------------------------
253
*/
254
255
static void
256
FileExitProc(clientData)
257
ClientData clientData; /* Not used. */
258
{
259
Tcl_DeleteHashTable(&fileTable);
260
initialized = 0;
261
}
262
263