home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tcltk805.zip
/
tcl805s.zip
/
tcl8.0.5
/
os2
/
tclOS2Dll.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-08-19
|
9KB
|
356 lines
/*
* tclOS2Dll.c --
*
* This file contains the DLL entry point.
*
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
* Copyright (c) 1996-2001 Illya Vaes
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include "tclOS2Int.h"
int _CRT_init(void);
void _CRT_term(void);
static int tclProcessesAttached = 0;
/*
* The following data structure is used to keep track of all of the DLL's
* opened by Tcl so that they can be freed when the Tcl.dll is unloaded.
*/
typedef struct LibraryList {
HMODULE handle;
struct LibraryList *nextPtr;
} LibraryList;
/* List of currently loaded DLL's. */
static LibraryList *libraryList = NULL;
/*
* The following data structure is used to keep track of all of the memory
* alloced for environ by Tcl so that it can be freed when the dll is unloaded.
*/
typedef struct AllocedMemList {
unsigned long handle;
char **environ;
int nrEntries;
struct AllocedMemList *nextPtr;
} AllocedMemList;
/* List of currently loaded DLL's. */
static AllocedMemList *allocedMemoryList = NULL;
static HMODULE tclInstance; /* Global library instance handle. */
/*
* Declarations for functions that are only used in this file.
*/
static void UnloadLibraries _ANSI_ARGS_((void));
#ifndef STATIC_BUILD
/*
*----------------------------------------------------------------------
*
* _DLL_InitTerm --
*
* DLL entry point.
*
* Results:
* TRUE on sucess, FALSE on failure.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
unsigned long
_DLL_InitTerm(
unsigned long hInst, /* Library instance handle. */
unsigned long reason /* Reason this function is being called. */
)
{
switch (reason) {
case 0: { /* INIT */
PPIB pibPtr;
PTIB tibPtr;
AllocedMemList *ptr;
/* Add to the list for alloced memory */
ptr = (AllocedMemList*) ckalloc(sizeof(AllocedMemList));
#ifdef VERBOSE
printf("Inserting item, allocedMemoryList was %p\n", allocedMemoryList);
#endif
if (ptr == NULL) return FALSE;
ptr->handle = hInst;
ptr->nrEntries = 0;
ptr->environ = NULL;
ptr->nextPtr = allocedMemoryList;
allocedMemoryList = ptr;
/* Let Tcl know our handle */
tclInstance = (HMODULE)hInst;
/* Fill environ */
rc = DosGetInfoBlocks(&tibPtr, &pibPtr);
if (environ == NULL) {
/* Determine length of environment */
BOOL lastString = FALSE;
PCHAR nextString = pibPtr->pib_pchenv;
int length = 0;
#ifdef VERBOSE
int envSize = 0;
printf("Copying environ...\n");
#endif
if (nextString == NULL || *nextString == 0) {
lastString = TRUE;
}
while (!lastString) {
length = strlen(nextString);
#ifdef VERBOSE
envSize += length+1;
#endif
nextString += length+1;
ptr->nrEntries++;
if (*nextString == 0) lastString = TRUE;
}
#ifdef VERBOSE
printf("envSize %d\n", envSize);
#endif
if (ptr->nrEntries > 0) {
PCHAR copyString;
int count = 0;
environ = (char **) ckalloc(ptr->nrEntries * sizeof(char *));
if (environ == NULL) return FALSE;
#ifdef VERBOSE
printf("ckalloced environ %d\n", ptr->nrEntries*sizeof(char *));
#endif
ptr->environ = environ;
lastString = FALSE;
nextString = pibPtr->pib_pchenv;
while (!lastString) {
length = strlen(nextString);
copyString = ckalloc(length * sizeof(char) + 1);
#ifdef VERBOSE
printf("ckalloced copyString %d\n", length* sizeof(char)+1);
#endif
if (copyString == NULL) return FALSE;
strncpy(copyString, nextString, length);
environ[count] = copyString;
count++;
nextString += length+1;
if (*nextString == 0) lastString = TRUE;
}
}
#ifdef VERBOSE
} else {
printf("Not copying environ\n");
#endif
}
tclProcessesAttached++;
return TRUE;
}
case 1: { /* TERM */
AllocedMemList *ptr, *prevPtr;
/* Find in list of allocated memory */
ptr = allocedMemoryList;
prevPtr = ptr;
while (ptr != NULL && ptr->handle != hInst) {
#ifdef VERBOSE
printf("while search\n");
#endif
prevPtr = ptr;
ptr = ptr->nextPtr;
}
if (ptr != NULL) {
/* Remove from list */
if (allocedMemoryList == ptr) {
#ifdef VERBOSE
printf("remove first from list\n");
#endif
allocedMemoryList = ptr->nextPtr;
} else {
prevPtr->nextPtr = ptr->nextPtr;
#ifdef VERBOSE
printf("remove non-first from list\n");
#endif
}
/* Free memory */
while (ptr->nrEntries > 0) {
#ifdef VERBOSE
printf("ckfree entry %d [%s]\n", ptr->nrEntries - 1,
ptr->environ[ptr->nrEntries - 1]);
#endif
ckfree(ptr->environ[ptr->nrEntries - 1]);
ptr->nrEntries--;
}
ckfree((char *)ptr->environ);
#ifdef VERBOSE
printf("ckfree-ed environ\n");
#endif
}
tclProcessesAttached--;
if (tclProcessesAttached == 0) {
/*
* Finalize our use of Tcl.
*/
Tcl_Finalize();
}
return TRUE;
}
}
return FALSE;
}
#endif /* !STATIC_BUILD */
/*
*----------------------------------------------------------------------
*
* TclpFinalize --
*
* Clean up the OS/2 specific library state.
*
* Results:
* None.
*
* Side effects:
* Unloads any DLLs, if necessary.
*
*----------------------------------------------------------------------
*/
void
TclpFinalize()
{
/*
* Cleanup any dynamically loaded libraries.
*/
UnloadLibraries();
}
/*
*----------------------------------------------------------------------
*
* TclOS2LoadLibrary --
*
* This function is a wrapper for the system DosLoadModule. It is
* responsible for adding library handles to the library list so
* the libraries can be freed when tcl.dll is unloaded.
*
* Results:
* Returns the handle of the newly loaded library, or NULL on
* failure.
*
* Side effects:
* Loads the specified library into the process.
*
*----------------------------------------------------------------------
*/
HMODULE
TclOS2LoadLibrary(name)
char *name; /* Library file to load. */
{
HMODULE handle;
LibraryList *ptr;
UCHAR LoadError[256]; /* Area for name of DLL that we failed on */
#ifdef VERBOSE
LoadError[255] = '\0';
printf("TclOS2LoadLibrary [%s]\n", name);
fflush(stdout);
#endif
rc = DosLoadModule((PSZ)LoadError, sizeof(LoadError), (PSZ)name, &handle);
if (rc == NO_ERROR) {
#ifdef VERBOSE
printf("DosLoadModule [%s] OK (LoadError [%s])\n", name, LoadError);
fflush(stdout);
#endif
ptr = (LibraryList*) ckalloc(sizeof(LibraryList));
ptr->handle = handle;
ptr->nextPtr = libraryList;
libraryList = ptr;
return handle;
} else {
#ifdef VERBOSE
printf("DosLoadModule %s ERROR %d on %s\n", name, rc, LoadError);
fflush(stdout);
#endif
TclOS2ConvertError(rc);
return NULLHANDLE;
}
}
/*
*----------------------------------------------------------------------
*
* UnloadLibraries --
*
* Frees any dynamically allocated libraries loaded by Tcl.
*
* Results:
* None.
*
* Side effects:
* Frees the libraries on the library list as well as the list.
*
*----------------------------------------------------------------------
*/
static void
UnloadLibraries()
{
LibraryList *ptr;
while (libraryList != NULL) {
DosFreeModule(libraryList->handle);
ptr = libraryList->nextPtr;
ckfree((char *)libraryList);
libraryList = ptr;
}
/* Don't forget to cleanly exit PM if applicable */
if (usePm) {
TclOS2PMShutdown();
}
}
/*
*----------------------------------------------------------------------
*
* TclOS2GetTclInstance --
*
* Retrieves the global library instance handle.
*
* Results:
* Returns the global library instance handle.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
HMODULE
TclOS2GetTclInstance()
{
return tclInstance;
}