Annotation of embedaddon/curl/lib/nwlib.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
! 9: *
! 10: * This software is licensed as described in the file COPYING, which
! 11: * you should have received as part of this distribution. The terms
! 12: * are also available at https://curl.haxx.se/docs/copyright.html.
! 13: *
! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
! 15: * copies of the Software, and permit persons to whom the Software is
! 16: * furnished to do so, under the terms of the COPYING file.
! 17: *
! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
! 19: * KIND, either express or implied.
! 20: *
! 21: ***************************************************************************/
! 22:
! 23: #include "curl_setup.h"
! 24:
! 25: #ifdef NETWARE /* Novell NetWare */
! 26:
! 27: #ifdef __NOVELL_LIBC__
! 28: /* For native LibC-based NLM we need to register as a real lib. */
! 29: #include <library.h>
! 30: #include <netware.h>
! 31: #include <screen.h>
! 32: #include <nks/thread.h>
! 33: #include <nks/synch.h>
! 34:
! 35: #include "curl_memory.h"
! 36: /* The last #include file should be: */
! 37: #include "memdebug.h"
! 38:
! 39: typedef struct
! 40: {
! 41: int _errno;
! 42: void *twentybytes;
! 43: } libthreaddata_t;
! 44:
! 45: typedef struct
! 46: {
! 47: int x;
! 48: int y;
! 49: int z;
! 50: void *tenbytes;
! 51: NXKey_t perthreadkey; /* if -1, no key obtained... */
! 52: NXMutex_t *lock;
! 53: } libdata_t;
! 54:
! 55: int gLibId = -1;
! 56: void *gLibHandle = (void *) NULL;
! 57: rtag_t gAllocTag = (rtag_t) NULL;
! 58: NXMutex_t *gLibLock = (NXMutex_t *) NULL;
! 59:
! 60: /* internal library function prototypes... */
! 61: int DisposeLibraryData(void *);
! 62: void DisposeThreadData(void *);
! 63: int GetOrSetUpData(int id, libdata_t **data, libthreaddata_t **threaddata);
! 64:
! 65:
! 66: int _NonAppStart(void *NLMHandle,
! 67: void *errorScreen,
! 68: const char *cmdLine,
! 69: const char *loadDirPath,
! 70: size_t uninitializedDataLength,
! 71: void *NLMFileHandle,
! 72: int (*readRoutineP)(int conn,
! 73: void *fileHandle, size_t offset,
! 74: size_t nbytes,
! 75: size_t *bytesRead,
! 76: void *buffer),
! 77: size_t customDataOffset,
! 78: size_t customDataSize,
! 79: int messageCount,
! 80: const char **messages)
! 81: {
! 82: NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
! 83:
! 84: #ifndef __GNUC__
! 85: #pragma unused(cmdLine)
! 86: #pragma unused(loadDirPath)
! 87: #pragma unused(uninitializedDataLength)
! 88: #pragma unused(NLMFileHandle)
! 89: #pragma unused(readRoutineP)
! 90: #pragma unused(customDataOffset)
! 91: #pragma unused(customDataSize)
! 92: #pragma unused(messageCount)
! 93: #pragma unused(messages)
! 94: #endif
! 95:
! 96: /*
! 97: * Here we process our command line, post errors (to the error screen),
! 98: * perform initializations and anything else we need to do before being able
! 99: * to accept calls into us. If we succeed, we return non-zero and the NetWare
! 100: * Loader will leave us up, otherwise we fail to load and get dumped.
! 101: */
! 102: gAllocTag = AllocateResourceTag(NLMHandle,
! 103: "<library-name> memory allocations",
! 104: AllocSignature);
! 105:
! 106: if(!gAllocTag) {
! 107: OutputToScreen(errorScreen, "Unable to allocate resource tag for "
! 108: "library memory allocations.\n");
! 109: return -1;
! 110: }
! 111:
! 112: gLibId = register_library(DisposeLibraryData);
! 113:
! 114: if(gLibId < -1) {
! 115: OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
! 116: return -1;
! 117: }
! 118:
! 119: gLibHandle = NLMHandle;
! 120:
! 121: gLibLock = NXMutexAlloc(0, 0, &liblock);
! 122:
! 123: if(!gLibLock) {
! 124: OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
! 125: return -1;
! 126: }
! 127:
! 128: return 0;
! 129: }
! 130:
! 131: /*
! 132: * Here we clean up any resources we allocated. Resource tags is a big part
! 133: * of what we created, but NetWare doesn't ask us to free those.
! 134: */
! 135: void _NonAppStop(void)
! 136: {
! 137: (void) unregister_library(gLibId);
! 138: NXMutexFree(gLibLock);
! 139: }
! 140:
! 141: /*
! 142: * This function cannot be the first in the file for if the file is linked
! 143: * first, then the check-unload function's offset will be nlmname.nlm+0
! 144: * which is how to tell that there isn't one. When the check function is
! 145: * first in the linked objects, it is ambiguous. For this reason, we will
! 146: * put it inside this file after the stop function.
! 147: *
! 148: * Here we check to see if it's alright to ourselves to be unloaded. If not,
! 149: * we return a non-zero value. Right now, there isn't any reason not to allow
! 150: * it.
! 151: */
! 152: int _NonAppCheckUnload(void)
! 153: {
! 154: return 0;
! 155: }
! 156:
! 157: int GetOrSetUpData(int id, libdata_t **appData,
! 158: libthreaddata_t **threadData)
! 159: {
! 160: int err;
! 161: libdata_t *app_data;
! 162: libthreaddata_t *thread_data;
! 163: NXKey_t key;
! 164: NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
! 165:
! 166: err = 0;
! 167: thread_data = (libthreaddata_t *) NULL;
! 168:
! 169: /*
! 170: * Attempt to get our data for the application calling us. This is where we
! 171: * store whatever application-specific information we need to carry in
! 172: * support of calling applications.
! 173: */
! 174: app_data = (libdata_t *) get_app_data(id);
! 175:
! 176: if(!app_data) {
! 177: /*
! 178: * This application hasn't called us before; set up application AND
! 179: * per-thread data. Of course, just in case a thread from this same
! 180: * application is calling us simultaneously, we better lock our application
! 181: * data-creation mutex. We also need to recheck for data after we acquire
! 182: * the lock because WE might be that other thread that was too late to
! 183: * create the data and the first thread in will have created it.
! 184: */
! 185: NXLock(gLibLock);
! 186:
! 187: app_data = (libdata_t *) get_app_data(id);
! 188: if(!app_data) {
! 189: app_data = calloc(1, sizeof(libdata_t));
! 190:
! 191: if(app_data) {
! 192: app_data->tenbytes = malloc(10);
! 193: app_data->lock = NXMutexAlloc(0, 0, &liblock);
! 194:
! 195: if(!app_data->tenbytes || !app_data->lock) {
! 196: if(app_data->lock)
! 197: NXMutexFree(app_data->lock);
! 198: free(app_data->tenbytes);
! 199: free(app_data);
! 200: app_data = (libdata_t *) NULL;
! 201: err = ENOMEM;
! 202: }
! 203:
! 204: if(app_data) {
! 205: /*
! 206: * Here we burn in the application data that we were trying to get
! 207: * by calling get_app_data(). Next time we call the first function,
! 208: * we'll get this data we're just now setting. We also go on here to
! 209: * establish the per-thread data for the calling thread, something
! 210: * we'll have to do on each application thread the first time
! 211: * it calls us.
! 212: */
! 213: err = set_app_data(gLibId, app_data);
! 214:
! 215: if(err) {
! 216: if(app_data->lock)
! 217: NXMutexFree(app_data->lock);
! 218: free(app_data->tenbytes);
! 219: free(app_data);
! 220: app_data = (libdata_t *) NULL;
! 221: err = ENOMEM;
! 222: }
! 223: else {
! 224: /* create key for thread-specific data... */
! 225: err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
! 226:
! 227: if(err) /* (no more keys left?) */
! 228: key = -1;
! 229:
! 230: app_data->perthreadkey = key;
! 231: }
! 232: }
! 233: }
! 234: }
! 235:
! 236: NXUnlock(gLibLock);
! 237: }
! 238:
! 239: if(app_data) {
! 240: key = app_data->perthreadkey;
! 241:
! 242: if(key != -1 /* couldn't create a key? no thread data */
! 243: && !(err = NXKeyGetValue(key, (void **) &thread_data))
! 244: && !thread_data) {
! 245: /*
! 246: * Allocate the per-thread data for the calling thread. Regardless of
! 247: * whether there was already application data or not, this may be the
! 248: * first call by a new thread. The fact that we allocation 20 bytes on
! 249: * a pointer is not very important, this just helps to demonstrate that
! 250: * we can have arbitrarily complex per-thread data.
! 251: */
! 252: thread_data = malloc(sizeof(libthreaddata_t));
! 253:
! 254: if(thread_data) {
! 255: thread_data->_errno = 0;
! 256: thread_data->twentybytes = malloc(20);
! 257:
! 258: if(!thread_data->twentybytes) {
! 259: free(thread_data);
! 260: thread_data = (libthreaddata_t *) NULL;
! 261: err = ENOMEM;
! 262: }
! 263:
! 264: err = NXKeySetValue(key, thread_data);
! 265: if(err) {
! 266: free(thread_data->twentybytes);
! 267: free(thread_data);
! 268: thread_data = (libthreaddata_t *) NULL;
! 269: }
! 270: }
! 271: }
! 272: }
! 273:
! 274: if(appData)
! 275: *appData = app_data;
! 276:
! 277: if(threadData)
! 278: *threadData = thread_data;
! 279:
! 280: return err;
! 281: }
! 282:
! 283: int DisposeLibraryData(void *data)
! 284: {
! 285: if(data) {
! 286: void *tenbytes = ((libdata_t *) data)->tenbytes;
! 287:
! 288: free(tenbytes);
! 289: free(data);
! 290: }
! 291:
! 292: return 0;
! 293: }
! 294:
! 295: void DisposeThreadData(void *data)
! 296: {
! 297: if(data) {
! 298: void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
! 299:
! 300: free(twentybytes);
! 301: free(data);
! 302: }
! 303: }
! 304:
! 305: #else /* __NOVELL_LIBC__ */
! 306: /* For native CLib-based NLM seems we can do a bit more simple. */
! 307: #include <nwthread.h>
! 308:
! 309: int main(void)
! 310: {
! 311: /* initialize any globals here... */
! 312:
! 313: /* do this if any global initializing was done
! 314: SynchronizeStart();
! 315: */
! 316: ExitThread(TSR_THREAD, 0);
! 317: return 0;
! 318: }
! 319:
! 320: #endif /* __NOVELL_LIBC__ */
! 321:
! 322: #else /* NETWARE */
! 323:
! 324: #ifdef __POCC__
! 325: # pragma warn(disable:2024) /* Disable warning #2024: Empty input file */
! 326: #endif
! 327:
! 328: #endif /* NETWARE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>