diff options
| -rw-r--r-- | lib/nwlib.c | 600 | 
1 files changed, 300 insertions, 300 deletions
diff --git a/lib/nwlib.c b/lib/nwlib.c index 2dd0f4fa5..b0eea56c7 100644 --- a/lib/nwlib.c +++ b/lib/nwlib.c @@ -1,300 +1,300 @@ -/***************************************************************************
 - *                                  _   _ ____  _
 - *  Project                     ___| | | |  _ \| |
 - *                             / __| | | | |_) | |
 - *                            | (__| |_| |  _ <| |___
 - *                             \___|\___/|_| \_\_____|
 - *
 - * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
 - *
 - * This software is licensed as described in the file COPYING, which
 - * you should have received as part of this distribution. The terms
 - * are also available at http://curl.haxx.se/docs/copyright.html.
 - *
 - * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 - * copies of the Software, and permit persons to whom the Software is
 - * furnished to do so, under the terms of the COPYING file.
 - *
 - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 - * KIND, either express or implied.
 - *
 - * $Id$
 - ***************************************************************************/
 -
 -#include <errno.h>
 -#include <string.h>
 -#include <stdlib.h>
 -#include <library.h>
 -#include <netware.h>
 -#include <screen.h>
 -#include <nks/thread.h>
 -#include <nks/synch.h>
 -
 -#include "memory.h"
 -#include "memdebug.h"
 -
 -typedef struct
 -{
 -  int     _errno;
 -  void    *twentybytes;
 -} libthreaddata_t;
 -
 -typedef struct
 -{
 -  int         x;
 -  int         y;
 -  int         z;
 -  void        *tenbytes;
 -  NXKey_t     perthreadkey;   /* if -1, no key obtained... */
 -  NXMutex_t   *lock;
 -} libdata_t;
 -
 -int         gLibId      = -1;
 -void        *gLibHandle = (void *) NULL;
 -rtag_t      gAllocTag   = (rtag_t) NULL;
 -NXMutex_t   *gLibLock   = (NXMutex_t *) NULL;
 -
 -/* internal library function prototypes... */
 -int     DisposeLibraryData ( void * );
 -void    DisposeThreadData ( void * );
 -int     GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );
 -
 -
 -int _NonAppStart( void        *NLMHandle,
 -                  void        *errorScreen,
 -                  const char  *cmdLine,
 -                  const char  *loadDirPath,
 -                  size_t      uninitializedDataLength,
 -                  void        *NLMFileHandle,
 -                  int         (*readRoutineP)( int conn,
 -                                               void *fileHandle, size_t offset,
 -                                               size_t nbytes,
 -                                               size_t *bytesRead,
 -                                               void *buffer ),
 -                  size_t      customDataOffset,
 -                  size_t      customDataSize,
 -                  int         messageCount,
 -                  const char  **messages )
 -{
 -  NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
 -  
 -#ifndef __GNUC__
 -#pragma unused(cmdLine)
 -#pragma unused(loadDirPath)
 -#pragma unused(uninitializedDataLength)
 -#pragma unused(NLMFileHandle)
 -#pragma unused(readRoutineP)
 -#pragma unused(customDataOffset)
 -#pragma unused(customDataSize)
 -#pragma unused(messageCount)
 -#pragma unused(messages)
 -#endif
 -
 -/*
 -** Here we process our command line, post errors (to the error screen),
 -** perform initializations and anything else we need to do before being able
 -** to accept calls into us. If we succeed, we return non-zero and the NetWare
 -** Loader will leave us up, otherwise we fail to load and get dumped.
 -*/
 -  gAllocTag = AllocateResourceTag(NLMHandle,
 -                                  "<library-name> memory allocations",
 -                                  AllocSignature);
 -
 -  if (!gAllocTag) {
 -    OutputToScreen(errorScreen, "Unable to allocate resource tag for "
 -                   "library memory allocations.\n");
 -    return -1;
 -  }
 -
 -  gLibId = register_library(DisposeLibraryData);
 -
 -  if (gLibId < -1) {
 -    OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
 -    return -1;
 -  }
 -
 -  gLibHandle = NLMHandle;
 -
 -  gLibLock = NXMutexAlloc(0, 0, &liblock);
 -  
 -  if (!gLibLock) {
 -    OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
 -    return -1;
 -  }
 -
 -  return 0;
 -}
 -
 -/*
 -** Here we clean up any resources we allocated. Resource tags is a big part
 -** of what we created, but NetWare doesn't ask us to free those.
 -*/
 -void _NonAppStop( void )
 -{
 -  (void) unregister_library(gLibId);
 -  NXMutexFree(gLibLock);
 -}
 -
 -/*
 -** This function cannot be the first in the file for if the file is linked
 -** first, then the check-unload function's offset will be nlmname.nlm+0
 -** which is how to tell that there isn't one. When the check function is
 -** first in the linked objects, it is ambiguous. For this reason, we will
 -** put it inside this file after the stop function.
 -**
 -** Here we check to see if it's alright to ourselves to be unloaded. If not,
 -** we return a non-zero value. Right now, there isn't any reason not to allow
 -** it.
 -*/
 -int  _NonAppCheckUnload( void )
 -{
 -    return 0;
 -}
 -
 -int GetOrSetUpData(int id, libdata_t **appData,
 -                   libthreaddata_t **threadData )
 -{
 -  int                 err;
 -  libdata_t           *app_data;
 -  libthreaddata_t *thread_data;
 -  NXKey_t             key;
 -  NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
 -
 -  err         = 0;
 -  thread_data = (libthreaddata_t *) NULL;
 -
 -/*
 -** Attempt to get our data for the application calling us. This is where we
 -** store whatever application-specific information we need to carry in support
 -** of calling applications.
 -*/
 -  app_data = (libdata_t *) get_app_data(id);
 -
 -  if (!app_data) {
 -/*
 -** This application hasn't called us before; set up application AND per-thread
 -** data. Of course, just in case a thread from this same application is calling
 -** us simultaneously, we better lock our application data-creation mutex. We
 -** also need to recheck for data after we acquire the lock because WE might be
 -** that other thread that was too late to create the data and the first thread
 -** in will have created it.
 -*/
 -    NXLock(gLibLock);
 -
 -    if (!(app_data = (libdata_t *) get_app_data(id))) {
 -      app_data = (libdata_t *) malloc(sizeof(libdata_t));
 -
 -      if (app_data) {
 -        memset(app_data, 0, sizeof(libdata_t));
 -        
 -        app_data->tenbytes = malloc(10);
 -        app_data->lock     = NXMutexAlloc(0, 0, &liblock);
 -        
 -        if (!app_data->tenbytes || !app_data->lock) {
 -          if (app_data->lock)
 -            NXMutexFree(app_data->lock);
 -          
 -          free(app_data);
 -          app_data = (libdata_t *) NULL;
 -          err      = ENOMEM;
 -        }
 -        
 -        if (app_data) {
 -/*
 -** Here we burn in the application data that we were trying to get by calling
 -** get_app_data(). Next time we call the first function, we'll get this data
 -** we're just now setting. We also go on here to establish the per-thread data
 -** for the calling thread, something we'll have to do on each application
 -** thread the first time it calls us.
 -*/
 -          err = set_app_data(gLibId, app_data);
 -          
 -          if (err) {
 -            free(app_data);
 -            app_data = (libdata_t *) NULL;
 -            err      = ENOMEM;
 -          }
 -          else {
 -            /* create key for thread-specific data... */
 -            err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
 -            
 -            if (err)                /* (no more keys left?) */
 -              key = -1;
 -            
 -            app_data->perthreadkey = key;
 -          }
 -        }
 -      }
 -    }
 -    
 -    NXUnlock(gLibLock);
 -  }
 -
 -  if (app_data) {
 -    key = app_data->perthreadkey;
 -    
 -    if (key != -1 /* couldn't create a key? no thread data */
 -        && !(err = NXKeyGetValue(key, (void **) &thread_data))
 -        && !thread_data) {
 -/*
 -** Allocate the per-thread data for the calling thread. Regardless of whether
 -** there was already application data or not, this may be the first call by a
 -** a new thread. The fact that we allocation 20 bytes on a pointer is not very
 -** important, this just helps to demonstrate that we can have arbitrarily
 -** complex per-thread data.
 -*/
 -      thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));
 -      
 -      if (thread_data) {
 -        thread_data->_errno      = 0;
 -        thread_data->twentybytes = malloc(20);
 -          
 -        if (!thread_data->twentybytes) {
 -          free(thread_data);
 -          thread_data = (libthreaddata_t *) NULL;
 -          err         = ENOMEM;
 -        }
 -        
 -        if ((err = NXKeySetValue(key, thread_data))) {
 -          free(thread_data->twentybytes);
 -          free(thread_data);
 -          thread_data = (libthreaddata_t *) NULL;
 -        }
 -      }
 -    }
 -  }
 -
 -  if (appData)
 -    *appData = app_data;
 -
 -  if (threadData)
 -    *threadData = thread_data;
 -
 -  return err;
 -}
 -
 -int DisposeLibraryData( void    *data)
 -{
 -  if (data) {
 -    void    *tenbytes = ((libdata_t *) data)->tenbytes;
 -    
 -    if (tenbytes)
 -      free(tenbytes);
 -    
 -    free(data);
 -  }
 -
 -  return 0;
 -}
 -
 -void DisposeThreadData(void    *data)
 -{
 -  if (data) {
 -    void    *twentybytes = ((libthreaddata_t *) data)->twentybytes;
 -    
 -    if (twentybytes)
 -      free(twentybytes);
 -    
 -    free(data);
 -  }
 -}
 +/*************************************************************************** + *                                  _   _ ____  _ + *  Project                     ___| | | |  _ \| | + *                             / __| | | | |_) | | + *                            | (__| |_| |  _ <| |___ + *                             \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + ***************************************************************************/ + +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <library.h> +#include <netware.h> +#include <screen.h> +#include <nks/thread.h> +#include <nks/synch.h> + +#include "memory.h" +#include "memdebug.h" + +typedef struct +{ +  int     _errno; +  void    *twentybytes; +} libthreaddata_t; + +typedef struct +{ +  int         x; +  int         y; +  int         z; +  void        *tenbytes; +  NXKey_t     perthreadkey;   /* if -1, no key obtained... */ +  NXMutex_t   *lock; +} libdata_t; + +int         gLibId      = -1; +void        *gLibHandle = (void *) NULL; +rtag_t      gAllocTag   = (rtag_t) NULL; +NXMutex_t   *gLibLock   = (NXMutex_t *) NULL; + +/* internal library function prototypes... */ +int     DisposeLibraryData ( void * ); +void    DisposeThreadData ( void * ); +int     GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata ); + + +int _NonAppStart( void        *NLMHandle, +                  void        *errorScreen, +                  const char  *cmdLine, +                  const char  *loadDirPath, +                  size_t      uninitializedDataLength, +                  void        *NLMFileHandle, +                  int         (*readRoutineP)( int conn, +                                               void *fileHandle, size_t offset, +                                               size_t nbytes, +                                               size_t *bytesRead, +                                               void *buffer ), +                  size_t      customDataOffset, +                  size_t      customDataSize, +                  int         messageCount, +                  const char  **messages ) +{ +  NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0); +   +#ifndef __GNUC__ +#pragma unused(cmdLine) +#pragma unused(loadDirPath) +#pragma unused(uninitializedDataLength) +#pragma unused(NLMFileHandle) +#pragma unused(readRoutineP) +#pragma unused(customDataOffset) +#pragma unused(customDataSize) +#pragma unused(messageCount) +#pragma unused(messages) +#endif + +/* +** Here we process our command line, post errors (to the error screen), +** perform initializations and anything else we need to do before being able +** to accept calls into us. If we succeed, we return non-zero and the NetWare +** Loader will leave us up, otherwise we fail to load and get dumped. +*/ +  gAllocTag = AllocateResourceTag(NLMHandle, +                                  "<library-name> memory allocations", +                                  AllocSignature); + +  if (!gAllocTag) { +    OutputToScreen(errorScreen, "Unable to allocate resource tag for " +                   "library memory allocations.\n"); +    return -1; +  } + +  gLibId = register_library(DisposeLibraryData); + +  if (gLibId < -1) { +    OutputToScreen(errorScreen, "Unable to register library with kernel.\n"); +    return -1; +  } + +  gLibHandle = NLMHandle; + +  gLibLock = NXMutexAlloc(0, 0, &liblock); +   +  if (!gLibLock) { +    OutputToScreen(errorScreen, "Unable to allocate library data lock.\n"); +    return -1; +  } + +  return 0; +} + +/* +** Here we clean up any resources we allocated. Resource tags is a big part +** of what we created, but NetWare doesn't ask us to free those. +*/ +void _NonAppStop( void ) +{ +  (void) unregister_library(gLibId); +  NXMutexFree(gLibLock); +} + +/* +** This function cannot be the first in the file for if the file is linked +** first, then the check-unload function's offset will be nlmname.nlm+0 +** which is how to tell that there isn't one. When the check function is +** first in the linked objects, it is ambiguous. For this reason, we will +** put it inside this file after the stop function. +** +** Here we check to see if it's alright to ourselves to be unloaded. If not, +** we return a non-zero value. Right now, there isn't any reason not to allow +** it. +*/ +int  _NonAppCheckUnload( void ) +{ +    return 0; +} + +int GetOrSetUpData(int id, libdata_t **appData, +                   libthreaddata_t **threadData ) +{ +  int                 err; +  libdata_t           *app_data; +  libthreaddata_t *thread_data; +  NXKey_t             key; +  NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0); + +  err         = 0; +  thread_data = (libthreaddata_t *) NULL; + +/* +** Attempt to get our data for the application calling us. This is where we +** store whatever application-specific information we need to carry in support +** of calling applications. +*/ +  app_data = (libdata_t *) get_app_data(id); + +  if (!app_data) { +/* +** This application hasn't called us before; set up application AND per-thread +** data. Of course, just in case a thread from this same application is calling +** us simultaneously, we better lock our application data-creation mutex. We +** also need to recheck for data after we acquire the lock because WE might be +** that other thread that was too late to create the data and the first thread +** in will have created it. +*/ +    NXLock(gLibLock); + +    if (!(app_data = (libdata_t *) get_app_data(id))) { +      app_data = (libdata_t *) malloc(sizeof(libdata_t)); + +      if (app_data) { +        memset(app_data, 0, sizeof(libdata_t)); +         +        app_data->tenbytes = malloc(10); +        app_data->lock     = NXMutexAlloc(0, 0, &liblock); +         +        if (!app_data->tenbytes || !app_data->lock) { +          if (app_data->lock) +            NXMutexFree(app_data->lock); +           +          free(app_data); +          app_data = (libdata_t *) NULL; +          err      = ENOMEM; +        } +         +        if (app_data) { +/* +** Here we burn in the application data that we were trying to get by calling +** get_app_data(). Next time we call the first function, we'll get this data +** we're just now setting. We also go on here to establish the per-thread data +** for the calling thread, something we'll have to do on each application +** thread the first time it calls us. +*/ +          err = set_app_data(gLibId, app_data); +           +          if (err) { +            free(app_data); +            app_data = (libdata_t *) NULL; +            err      = ENOMEM; +          } +          else { +            /* create key for thread-specific data... */ +            err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key); +             +            if (err)                /* (no more keys left?) */ +              key = -1; +             +            app_data->perthreadkey = key; +          } +        } +      } +    } +     +    NXUnlock(gLibLock); +  } + +  if (app_data) { +    key = app_data->perthreadkey; +     +    if (key != -1 /* couldn't create a key? no thread data */ +        && !(err = NXKeyGetValue(key, (void **) &thread_data)) +        && !thread_data) { +/* +** Allocate the per-thread data for the calling thread. Regardless of whether +** there was already application data or not, this may be the first call by a +** a new thread. The fact that we allocation 20 bytes on a pointer is not very +** important, this just helps to demonstrate that we can have arbitrarily +** complex per-thread data. +*/ +      thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t)); +       +      if (thread_data) { +        thread_data->_errno      = 0; +        thread_data->twentybytes = malloc(20); +           +        if (!thread_data->twentybytes) { +          free(thread_data); +          thread_data = (libthreaddata_t *) NULL; +          err         = ENOMEM; +        } +         +        if ((err = NXKeySetValue(key, thread_data))) { +          free(thread_data->twentybytes); +          free(thread_data); +          thread_data = (libthreaddata_t *) NULL; +        } +      } +    } +  } + +  if (appData) +    *appData = app_data; + +  if (threadData) +    *threadData = thread_data; + +  return err; +} + +int DisposeLibraryData( void    *data) +{ +  if (data) { +    void    *tenbytes = ((libdata_t *) data)->tenbytes; +     +    if (tenbytes) +      free(tenbytes); +     +    free(data); +  } + +  return 0; +} + +void DisposeThreadData(void    *data) +{ +  if (data) { +    void    *twentybytes = ((libthreaddata_t *) data)->twentybytes; +     +    if (twentybytes) +      free(twentybytes); +     +    free(data); +  } +}  | 
