home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tkisrc04.zip / tcl / os2 / tclFHandle.c < prev    next >
C/C++ Source or Header  |  1998-08-07  |  6KB  |  255 lines

  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.6 96/02/13 16:29:55
  12.  */
  13.  
  14. #include "tcl.h"
  15. #include "tclPort.h"
  16.  
  17. /*
  18.  * The FileHashKey structure is used to associate the OS file handle and type
  19.  * with the corresponding notifier data in a FileHandle.
  20.  */
  21.  
  22. typedef struct FileHashKey {
  23.     int type;            /* File handle type. */
  24.     ClientData osHandle;    /* Platform specific OS file handle. */
  25. } FileHashKey;
  26.  
  27. typedef struct FileHandle {
  28.     FileHashKey key;        /* Hash key for a given file. */
  29.     ClientData data;        /* Platform specific notifier data. */
  30.     Tcl_FileFreeProc *proc;    /* Callback to invoke when file is freed. */
  31. } FileHandle;
  32.  
  33. /*
  34.  * Static variables used in this file:
  35.  */
  36.  
  37. static Tcl_HashTable fileTable;    /* Hash table containing file handles. */
  38. static int initialized = 0;    /* 1 if this module has been initialized. */
  39.  
  40. /*
  41.  * Static procedures used in this file:
  42.  */
  43.  
  44. static void         FileExitProc _ANSI_ARGS_((ClientData clientData));
  45.  
  46. /*
  47.  *----------------------------------------------------------------------
  48.  *
  49.  * Tcl_GetFile --
  50.  *
  51.  *    This function retrieves the file handle associated with a
  52.  *    platform specific file handle of the given type.  It creates
  53.  *    a new file handle if needed.
  54.  *
  55.  * Results:
  56.  *    Returns the file handle associated with the file descriptor.
  57.  *
  58.  * Side effects:
  59.  *    Initializes the file handle table if necessary.
  60.  *
  61.  *----------------------------------------------------------------------
  62.  */
  63.  
  64. Tcl_File
  65. Tcl_GetFile(osHandle, type)
  66.     ClientData osHandle;    /* Platform specific file handle. */
  67.     int type;            /* Type of file handle. */
  68. {
  69.     FileHashKey key;
  70.     Tcl_HashEntry *entryPtr;
  71.     int new;
  72.  
  73.     if (!initialized) {
  74.     Tcl_InitHashTable(&fileTable, sizeof(FileHashKey)/sizeof(int));
  75.     Tcl_CreateExitHandler(FileExitProc, 0);
  76.     initialized = 1;
  77.     }
  78.     key.osHandle = osHandle;
  79.     key.type = type;
  80.     entryPtr = Tcl_CreateHashEntry(&fileTable, (char *) &key, &new);
  81.     if (new) {
  82.     FileHandle *newHandlePtr;
  83.     newHandlePtr = (FileHandle *) ckalloc(sizeof(FileHandle));
  84.     newHandlePtr->key = key;
  85.     newHandlePtr->data = NULL;
  86.     newHandlePtr->proc = NULL;
  87.     Tcl_SetHashValue(entryPtr, newHandlePtr);
  88.     }
  89.     
  90.     return (Tcl_File) Tcl_GetHashValue(entryPtr);
  91. }
  92.  
  93. /*
  94.  *----------------------------------------------------------------------
  95.  *
  96.  * Tcl_FreeFile --
  97.  *
  98.  *    Deallocates an entry in the file handle table.
  99.  *
  100.  * Results:
  101.  *    None.
  102.  *
  103.  * Side effects:
  104.  *    None.
  105.  *
  106.  *----------------------------------------------------------------------
  107.  */
  108.  
  109. void
  110. Tcl_FreeFile(handle)
  111.     Tcl_File handle;
  112. {
  113.     Tcl_HashEntry *entryPtr;
  114.     FileHandle *handlePtr = (FileHandle *) handle;
  115.  
  116.     /*
  117.      * Invoke free procedure, then delete the handle.
  118.      */
  119.  
  120.     if (handlePtr->proc) {
  121.     (*handlePtr->proc)(handlePtr->data);
  122.     }
  123.  
  124.     entryPtr = Tcl_FindHashEntry(&fileTable, (char *) &handlePtr->key);
  125.     if (entryPtr) {
  126.     Tcl_DeleteHashEntry(entryPtr);
  127.     ckfree((char *) handlePtr);
  128.     }
  129. }
  130.  
  131. /*
  132.  *----------------------------------------------------------------------
  133.  *
  134.  * Tcl_GetFileInfo --
  135.  *
  136.  *    This function retrieves the platform specific file data and
  137.  *    type from the file handle.
  138.  *
  139.  * Results:
  140.  *    If typePtr is not NULL, sets *typePtr to the type of the file.
  141.  *    Returns the platform specific file data.
  142.  *
  143.  * Side effects:
  144.  *    None.
  145.  *
  146.  *----------------------------------------------------------------------
  147.  */
  148.  
  149. ClientData
  150. Tcl_GetFileInfo(handle, typePtr)
  151.     Tcl_File handle;
  152.     int *typePtr;
  153. {
  154.     FileHandle *handlePtr = (FileHandle *) handle;
  155.  
  156.     if (typePtr) {
  157.     *typePtr = handlePtr->key.type;
  158.     }
  159.     return handlePtr->key.osHandle;
  160. }
  161.  
  162. /*
  163.  *----------------------------------------------------------------------
  164.  *
  165.  * Tcl_SetNotifierData --
  166.  *
  167.  *    This function is used by the notifier to associate platform
  168.  *    specific notifier information and a deletion procedure with
  169.  *    a file handle.
  170.  *
  171.  * Results:
  172.  *    None.
  173.  *
  174.  * Side effects:
  175.  *    Updates the data and delProc slots in the file handle.
  176.  *
  177.  *----------------------------------------------------------------------
  178.  */
  179.  
  180. void
  181. Tcl_SetNotifierData(handle, proc, data)
  182.     Tcl_File handle;
  183.     Tcl_FileFreeProc *proc;
  184.     ClientData data;
  185. {
  186.     FileHandle *handlePtr = (FileHandle *) handle;
  187.     handlePtr->proc = proc;
  188.     handlePtr->data = data;
  189. }
  190.  
  191. /*
  192.  *----------------------------------------------------------------------
  193.  *
  194.  * Tcl_GetNotifierData --
  195.  *
  196.  *    This function is used by the notifier to retrieve the platform
  197.  *    specific notifier information associated with a file handle.
  198.  *
  199.  * Results:
  200.  *    Returns the data stored in a file handle by a previous call to
  201.  *    Tcl_SetNotifierData, and places a pointer to the free proc
  202.  *    in the location referred to by procPtr.
  203.  *
  204.  * Side effects:
  205.  *    None.
  206.  *
  207.  *----------------------------------------------------------------------
  208.  */
  209.  
  210. ClientData
  211. Tcl_GetNotifierData(handle, procPtr)
  212.     Tcl_File handle;
  213.     Tcl_FileFreeProc **procPtr;
  214. {
  215.     FileHandle *handlePtr = (FileHandle *) handle;
  216.     if (procPtr != NULL) {
  217.     *procPtr = handlePtr->proc;
  218.     }
  219.     return handlePtr->data;
  220. }
  221.  
  222. /*
  223.  *----------------------------------------------------------------------
  224.  *
  225.  * FileExitProc --
  226.  *
  227.  *    This function an exit handler that frees any memory allocated
  228.  *    for the file handle table.
  229.  *
  230.  * Results:
  231.  *    None.
  232.  *
  233.  * Side effects:
  234.  *    Cleans up the file handle table.
  235.  *
  236.  *----------------------------------------------------------------------
  237.  */
  238.  
  239. static void
  240. FileExitProc(clientData)
  241.     ClientData clientData;    /* Not used. */
  242. {
  243.     Tcl_HashSearch search;
  244.     Tcl_HashEntry *entryPtr;
  245.  
  246.     entryPtr = Tcl_FirstHashEntry(&fileTable, &search);
  247.  
  248.     while (entryPtr) {
  249.     ckfree(Tcl_GetHashValue(entryPtr));
  250.     entryPtr = Tcl_NextHashEntry(&search);
  251.     }
  252.  
  253.     Tcl_DeleteHashTable(&fileTable);
  254. }
  255.