memory.h is included everywhere for this.
Changelog
Daniel (11 May 2004)
+- Seshubabu Pasam provided a patch that introduces curl_global_init_mem() -
+ like normal curl_global_init() but allows the app to replace all memory
+ functions with its own set. I modified it slightly.
+
- Based on Luca Alteas' comments, I modified the curllib.dsp generation code.
Daniel (10 May 2004)
This release includes the following changes:
+ o added curl_global_init_mem()
+ o removed curl_formparse()
o the MSVC project file in the release archive is automatically built
o curl --proxy-digest is a new command line option
o the Windows version of libcurl can use wldap32.dll for LDAP
- o curl_easy_strerror(), curl_multi_strerror() and curl_share_strerror()
+ o added curl_easy_strerror(), curl_multi_strerror() and curl_share_strerror()
o IPv6-enabled Windows hosts now resolves names threaded/asynch as well
o configure --with-libidn can be used to point out the root dir of a libidn
installation for curl to use, then libcurl can resolve and use IDNA names
To get fixed in 7.12.0 (planned release: June 2004)
======================
-
-33. Add a function to replace the malloc-calls within libcurl.
- Low prio. Seshubabu Pasam works on this?
curl_multi_perform.3 curl_multi_remove_handle.3 curl_share_cleanup.3 \
curl_share_init.3 curl_share_setopt.3 libcurl.3 libcurl-easy.3 \
libcurl-multi.3 libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
- curl_multi_strerror.3 curl_share_strerror.3
+ curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
- curl_share_strerror.html
+ curl_share_strerror.html curl_global_init_mem.html
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
curl_share_init.pdf curl_share_setopt.pdf libcurl.pdf \
libcurl-multi.pdf libcurl-easy.pdf libcurl-share.pdf \
libcurl-errors.pdf curl_easy_strerror.pdf curl_multi_strerror.pdf \
- curl_share_strerror.pdf
+ curl_share_strerror.pdf curl_global_init_mem.pdf
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
.\" nroff -man [file]
.\" $Id$
.\"
-.TH curl_global_init 3 "13 Nov 2001" "libcurl 7.9.1" "libcurl Manual"
+.TH curl_global_init 3 "11 May 2004" "libcurl 7.12" "libcurl Manual"
.SH NAME
curl_global_init - Global libcurl initialisation
.SH SYNOPSIS
If this function returns non-zero, something went wrong and you cannot use the
other curl functions.
.SH "SEE ALSO"
+.BR curl_global_init_mem "(3), "
.BR curl_global_cleanup "(3), "
-
-
char *buffer,
int buflen);
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively. Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
/* the kind of data that is passed to information_callback*/
typedef enum {
CURLINFO_TEXT = 0,
*/
CURLcode curl_global_init(long flags);
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl. This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions. Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc. User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURLcode curl_global_init_mem(long flags,
+ curl_malloc_callback m,
+ curl_free_callback f,
+ curl_realloc_callback r,
+ curl_strdup_callback s,
+ curl_calloc_callback c);
+
/*
* NAME curl_global_cleanup()
*
telnet.h getinfo.h strequal.h security.h krb4.h memdebug.h \
inet_ntoa_r.h http_chunks.h strtok.h connect.h llist.h hash.h \
content_encoding.h share.h md5.h http_digest.h http_negotiate.h \
- http_ntlm.hca-bundle.h inet_pton.h strtoofft.h strerror.h \
- inet_ntop.h curlx.h
+ http_ntlm.h ca-bundle.h inet_pton.h strtoofft.h strerror.h \
+ inet_ntop.h curlx.h memory.h
CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
#include <curl/mprintf.h>
#include "base64.h"
+#include "memory.h"
-#ifdef CURLDEBUG
+/* include memdebug.h last */
#include "memdebug.h"
-#endif
+
static void decodeQuantum(unsigned char *dest, const char *src)
{
#include "if2ip.h"
#include "strerror.h"
#include "connect.h"
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
static bool verifyconnect(curl_socket_t sockfd);
#include <curl/curl.h>
#include "sendf.h"
#include "content_encoding.h"
+#include "memory.h"
+
+#include "memdebug.h"
#define DSIZ 0x10000 /* buffer size for decompressed data */
#include "strequal.h"
#include "strtok.h"
#include "sendf.h"
+#include "memory.h"
/* The last #include file should be: */
#ifdef CURLDEBUG
#include "getinfo.h"
#include "hostip.h"
#include "share.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
static unsigned int initialized = 0;
static long init_flags = 0;
+/*
+ * If a memory-using function (like curl_getenv) is used before
+ * curl_global_init() is called, we need to have these pointers set already.
+ */
+curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
+curl_free_callback Curl_cfree = (curl_free_callback)free;
+curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
+curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
+curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
+
/**
* curl_global_init() globally initializes cURL given a bitwise set of the
* different features of what to initialize.
if (initialized)
return CURLE_OK;
+ /* Setup the default memory functions here (again) */
+ Curl_cmalloc = (curl_malloc_callback)malloc;
+ Curl_cfree = (curl_free_callback)free;
+ Curl_crealloc = (curl_realloc_callback)realloc;
+ Curl_cstrdup = (curl_strdup_callback)strdup;
+ Curl_ccalloc = (curl_calloc_callback)calloc;
+
if (flags & CURL_GLOBAL_SSL)
Curl_SSL_init();
return CURLE_OK;
}
+/*
+ * curl_global_init_mem() globally initializes cURL and also registers the
+ * user provided callback routines.
+ */
+CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
+ curl_free_callback f, curl_realloc_callback r,
+ curl_strdup_callback s, curl_calloc_callback c)
+{
+ CURLcode code = CURLE_OK;
+
+ /* Invalid input, return immediately */
+ if (!m || !f || !r || !s || !c)
+ return CURLE_FAILED_INIT;
+
+ /* Already initialized, don't do it again */
+ if ( initialized )
+ return CURLE_OK;
+
+ /* Call the actual init function first */
+ code = curl_global_init(flags);
+ if (code == CURLE_OK) {
+ Curl_cmalloc = m;
+ Curl_cfree = f;
+ Curl_cstrdup = s;
+ Curl_crealloc = r;
+ Curl_ccalloc = c;
+ }
+
+ return code;
+}
+
/**
* curl_global_cleanup() globally cleanups cURL, uses the value of
* "init_flags" to determine what needs to be cleaned up and what doesn't.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
char *curl_escape(const char *string, int length)
{
#include <fcntl.h>
#endif
-
#endif
#include "urldata.h"
#include "speedcheck.h"
#include "getinfo.h"
#include "transfer.h" /* for Curl_readwrite_init() */
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/*
* Curl_file_connect() gets called from Curl_protocol_connect() to allow us to
#include "ssluse.h"
#include "connect.h"
#include "strerror.h"
+#include "memory.h"
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
# include <string.h>
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef MALLOCDEBUG
#include "memdebug.h"
-#endif
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 0
#endif
#include <curl/curl.h>
+#include "memory.h"
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
static
char *GetEnv(const char *variable)
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
-
-#ifdef VMS
-#include <stdlib.h>
-#endif
+#include <stdlib.h>
+#include "memory.h"
/* Make this the last #include */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#else
-#include <stdlib.h>
-#endif
/*
* This is supposed to be called in the beginning of a permform() session
#include "hash.h"
#include "llist.h"
+#include "memory.h"
-#ifdef CURLDEBUG
/* this must be the last include file */
#include "memdebug.h"
-#endif
-
static unsigned long
hash_str(const char *key, size_t key_length)
#include "inet_ntoa_r.h"
#endif
+#include "memory.h"
+
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/***********************************************************************
* Only for ares-enabled builds
#include "inet_ntoa_r.h"
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/***********************************************************************
* Only for builds using asynchronous name resolves
#include "inet_ntoa_r.h"
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/*
* hostip.c explained
#include "inet_ntoa_r.h"
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/***********************************************************************
* Only for plain-ipv4 builds
#include "inet_ntoa_r.h"
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/***********************************************************************
* Only for ipv6-enabled builds
#include "inet_ntoa_r.h"
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/***********************************************************************
* Only for builds using synchronous name resolves
#include "inet_ntop.h"
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/***********************************************************************
* Only for Windows threaded name resolves builds
#include <sys/select.h>
#endif
-
#endif
#include "urldata.h"
#include "share.h"
#include "hostip.h"
#include "http.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/*
* checkheaders() checks the linked list of custom HTTP headers for a
#include "content_encoding.h" /* 08/29/02 jhrg */
#include "http.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/*
* Chunk format (simplified):
#include "http_digest.h"
#include "strtok.h"
#include "url.h" /* for Curl_safefree() */
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/* Test example headers:
#include "strequal.h"
#include "base64.h"
#include "http_negotiate.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
static int
get_gss_name(struct connectdata *conn, gss_name_t *server)
#include "base64.h"
#include "http_ntlm.h"
#include "url.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#endif
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/* Define this to make the type-3 message include the NT response message */
#define USE_NTRESPONSES 1
#endif
#include "if2ip.h"
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#define SYS_ERROR -1
#include "ftp.h"
#include "sendf.h"
#include "krb4.h"
+#include "memory.h"
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
#endif
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#define LOCAL_ADDR (&conn->local_addr)
#define REMOTE_ADDR (&conn->serv_addr)
#include "strequal.h"
#include "strtok.h"
#include "ldap.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/* WLdap32.dll functions are *not* stdcall. Must call these via __cdecl
* pointers in case libcurl was compiled as fastcall (-Gr).
#include <stdlib.h>
#include "llist.h"
+#include "memory.h"
-#ifdef CURLDEBUG
/* this must be the last include file */
#include "memdebug.h"
-#endif
+
void
Curl_llist_init(curl_llist *l, curl_llist_dtor dtor)
{
#endif
#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
+#include "memory.h"
#include "memdebug.h"
struct memdebug {
/* alloc at least 64 bytes */
size = sizeof(struct memdebug)+wantedsize;
- mem=(struct memdebug *)(malloc)(size);
+ mem=(struct memdebug *)(Curl_cmalloc)(size);
if(mem) {
/* fill memory with junk */
memset(mem->mem, 0xA5, wantedsize);
user_size = wanted_size * wanted_elements;
size = sizeof(struct memdebug) + user_size;
- mem = (struct memdebug *)(malloc)(size);
+ mem = (struct memdebug *)(Curl_cmalloc)(size);
if(mem) {
/* fill memory with zeroes */
memset(mem->mem, 0, user_size);
if(ptr)
mem = (struct memdebug *)((char *)ptr - offsetof(struct memdebug, mem));
- mem=(struct memdebug *)(realloc)(mem, size);
+ mem=(struct memdebug *)(Curl_crealloc)(mem, size);
if(logfile)
fprintf(logfile, "MEM %s:%d realloc(0x%x, %zd) = %p\n",
source, line, ptr, wantedsize, mem?mem->mem:NULL);
memset(mem->mem, 0x13, mem->size);
/* free for real */
- (free)(mem);
+ (Curl_cfree)(mem);
if(logfile)
fprintf(logfile, "MEM %s:%d free(%p)\n", source, line, ptr);
#define ENABLE_64BIT
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
#define MAX_PARAMETERS 128 /* lame static limit */
#include "url.h"
#include "connect.h"
#include "progress.h"
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
struct Curl_message {
/* the 'CURLMsg' is the part that is visible to the external user */
#include "strequal.h"
#include "strtok.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/* Debug this single source file with:
'make netrc' then run './netrc'!
#include <nks/thread.h>\r
#include <nks/synch.h>\r
\r
+#include "memory.h"\r
+#include "memdebug.h"\r
\r
typedef struct\r
{\r
- int _errno;\r
- void *twentybytes;\r
+ int _errno;\r
+ void *twentybytes;\r
} libthreaddata_t;\r
\r
typedef struct\r
{\r
- int x;\r
- int y;\r
- int z;\r
- void *tenbytes;\r
- NXKey_t perthreadkey; /* if -1, no key obtained... */\r
- NXMutex_t *lock;\r
+ int x;\r
+ int y;\r
+ int z;\r
+ void *tenbytes;\r
+ NXKey_t perthreadkey; /* if -1, no key obtained... */\r
+ NXMutex_t *lock;\r
} libdata_t;\r
\r
int gLibId = -1;\r
int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );\r
\r
\r
-int _NonAppStart\r
-(\r
- void *NLMHandle,\r
- void *errorScreen,\r
- const char *cmdLine,\r
- const char *loadDirPath,\r
- size_t uninitializedDataLength,\r
- void *NLMFileHandle,\r
- int (*readRoutineP)( int conn, void *fileHandle, size_t offset,\r
- size_t nbytes, size_t *bytesRead, void *buffer ),\r
- size_t customDataOffset,\r
- size_t customDataSize,\r
- int messageCount,\r
- const char **messages\r
-)\r
+int _NonAppStart( void *NLMHandle,\r
+ void *errorScreen,\r
+ const char *cmdLine,\r
+ const char *loadDirPath,\r
+ size_t uninitializedDataLength,\r
+ void *NLMFileHandle,\r
+ int (*readRoutineP)( int conn,\r
+ void *fileHandle, size_t offset,\r
+ size_t nbytes,\r
+ size_t *bytesRead,\r
+ void *buffer ),\r
+ size_t customDataOffset,\r
+ size_t customDataSize,\r
+ int messageCount,\r
+ const char **messages )\r
{\r
- NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);\r
-\r
+ NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);\r
+ \r
#ifndef __GNUC__\r
#pragma unused(cmdLine)\r
#pragma unused(loadDirPath)\r
** to accept calls into us. If we succeed, we return non-zero and the NetWare\r
** Loader will leave us up, otherwise we fail to load and get dumped.\r
*/\r
- gAllocTag = AllocateResourceTag(NLMHandle,\r
- "<library-name> memory allocations", AllocSignature);\r
+ gAllocTag = AllocateResourceTag(NLMHandle,\r
+ "<library-name> memory allocations",\r
+ AllocSignature);\r
\r
- if (!gAllocTag)\r
- {\r
- OutputToScreen(errorScreen, "Unable to allocate resource tag for "\r
- "library memory allocations.\n");\r
- return -1;\r
- }\r
+ if (!gAllocTag) {\r
+ OutputToScreen(errorScreen, "Unable to allocate resource tag for "\r
+ "library memory allocations.\n");\r
+ return -1;\r
+ }\r
\r
- gLibId = register_library(DisposeLibraryData);\r
+ gLibId = register_library(DisposeLibraryData);\r
\r
- if (gLibId < -1)\r
- {\r
- OutputToScreen(errorScreen, "Unable to register library with kernel.\n");\r
- return -1;\r
- }\r
+ if (gLibId < -1) {\r
+ OutputToScreen(errorScreen, "Unable to register library with kernel.\n");\r
+ return -1;\r
+ }\r
\r
- gLibHandle = NLMHandle;\r
+ gLibHandle = NLMHandle;\r
\r
- gLibLock = NXMutexAlloc(0, 0, &liblock);\r
-\r
- if (!gLibLock)\r
- {\r
- OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");\r
- return -1;\r
- }\r
+ gLibLock = NXMutexAlloc(0, 0, &liblock);\r
+ \r
+ if (!gLibLock) {\r
+ OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");\r
+ return -1;\r
+ }\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
/*\r
*/\r
void _NonAppStop( void )\r
{\r
- (void) unregister_library(gLibId);\r
- NXMutexFree(gLibLock);\r
+ (void) unregister_library(gLibId);\r
+ NXMutexFree(gLibLock);\r
}\r
\r
/*\r
return 0;\r
}\r
\r
-int GetOrSetUpData\r
-(\r
- int id,\r
- libdata_t **appData,\r
- libthreaddata_t **threadData\r
-)\r
+int GetOrSetUpData(int id, libdata_t **appData,\r
+ libthreaddata_t **threadData )\r
{\r
- int err;\r
- libdata_t *app_data;\r
- libthreaddata_t *thread_data;\r
- NXKey_t key;\r
- NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);\r
+ int err;\r
+ libdata_t *app_data;\r
+ libthreaddata_t *thread_data;\r
+ NXKey_t key;\r
+ NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);\r
\r
- err = 0;\r
- thread_data = (libthreaddata_t *) NULL;\r
+ err = 0;\r
+ thread_data = (libthreaddata_t *) NULL;\r
\r
/*\r
** Attempt to get our data for the application calling us. This is where we\r
** store whatever application-specific information we need to carry in support\r
** of calling applications.\r
*/\r
- app_data = (libdata_t *) get_app_data(id);\r
+ app_data = (libdata_t *) get_app_data(id);\r
\r
- if (!app_data)\r
- {\r
+ if (!app_data) {\r
/*\r
** This application hasn't called us before; set up application AND per-thread\r
** data. Of course, just in case a thread from this same application is calling\r
** that other thread that was too late to create the data and the first thread\r
** in will have created it.\r
*/\r
- NXLock(gLibLock);\r
-\r
- if (!(app_data = (libdata_t *) get_app_data(id)))\r
- {\r
- app_data = (libdata_t *) malloc(sizeof(libdata_t));\r
-\r
- if (app_data)\r
- {\r
- memset(app_data, 0, sizeof(libdata_t));\r
-\r
- app_data->tenbytes = malloc(10);\r
- app_data->lock = NXMutexAlloc(0, 0, &liblock);\r
-\r
- if (!app_data->tenbytes || !app_data->lock)\r
- {\r
- if (app_data->lock)\r
- NXMutexFree(app_data->lock);\r
-\r
- free(app_data);\r
- app_data = (libdata_t *) NULL;\r
- err = ENOMEM;\r
- }\r
-\r
- if (app_data)\r
- {\r
+ NXLock(gLibLock);\r
+\r
+ if (!(app_data = (libdata_t *) get_app_data(id))) {\r
+ app_data = (libdata_t *) malloc(sizeof(libdata_t));\r
+\r
+ if (app_data) {\r
+ memset(app_data, 0, sizeof(libdata_t));\r
+ \r
+ app_data->tenbytes = malloc(10);\r
+ app_data->lock = NXMutexAlloc(0, 0, &liblock);\r
+ \r
+ if (!app_data->tenbytes || !app_data->lock) {\r
+ if (app_data->lock)\r
+ NXMutexFree(app_data->lock);\r
+ \r
+ free(app_data);\r
+ app_data = (libdata_t *) NULL;\r
+ err = ENOMEM;\r
+ }\r
+ \r
+ if (app_data) {\r
/*\r
** Here we burn in the application data that we were trying to get by calling\r
** get_app_data(). Next time we call the first function, we'll get this data\r
** for the calling thread, something we'll have to do on each application\r
** thread the first time it calls us.\r
*/\r
- err = set_app_data(gLibId, app_data);\r
-\r
- if (err)\r
- {\r
- free(app_data);\r
- app_data = (libdata_t *) NULL;\r
- err = ENOMEM;\r
- }\r
- else\r
- {\r
- /* create key for thread-specific data... */\r
- err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);\r
-\r
- if (err) /* (no more keys left?) */\r
- key = -1;\r
-\r
- app_data->perthreadkey = key;\r
- }\r
- }\r
- }\r
+ err = set_app_data(gLibId, app_data);\r
+ \r
+ if (err) {\r
+ free(app_data);\r
+ app_data = (libdata_t *) NULL;\r
+ err = ENOMEM;\r
+ }\r
+ else {\r
+ /* create key for thread-specific data... */\r
+ err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);\r
+ \r
+ if (err) /* (no more keys left?) */\r
+ key = -1;\r
+ \r
+ app_data->perthreadkey = key;\r
+ }\r
}\r
-\r
- NXUnlock(gLibLock);\r
+ }\r
}\r
-\r
- if (app_data)\r
- {\r
- key = app_data->perthreadkey;\r
-\r
- if ( key != -1 /* couldn't create a key? no thread data */\r
- && !(err = NXKeyGetValue(key, (void **) &thread_data))\r
- && !thread_data)\r
- {\r
+ \r
+ NXUnlock(gLibLock);\r
+ }\r
+\r
+ if (app_data) {\r
+ key = app_data->perthreadkey;\r
+ \r
+ if (key != -1 /* couldn't create a key? no thread data */\r
+ && !(err = NXKeyGetValue(key, (void **) &thread_data))\r
+ && !thread_data) {\r
/*\r
** Allocate the per-thread data for the calling thread. Regardless of whether\r
** there was already application data or not, this may be the first call by a\r
** important, this just helps to demonstrate that we can have arbitrarily\r
** complex per-thread data.\r
*/\r
- thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));\r
-\r
- if (thread_data)\r
- {\r
- thread_data->_errno = 0;\r
- thread_data->twentybytes = malloc(20);\r
-\r
- if (!thread_data->twentybytes)\r
- {\r
- free(thread_data);\r
- thread_data = (libthreaddata_t *) NULL;\r
- err = ENOMEM;\r
- }\r
-\r
- if ((err = NXKeySetValue(key, thread_data)))\r
- {\r
- free(thread_data->twentybytes);\r
- free(thread_data);\r
- thread_data = (libthreaddata_t *) NULL;\r
- }\r
- }\r
+ thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));\r
+ \r
+ if (thread_data) {\r
+ thread_data->_errno = 0;\r
+ thread_data->twentybytes = malloc(20);\r
+ \r
+ if (!thread_data->twentybytes) {\r
+ free(thread_data);\r
+ thread_data = (libthreaddata_t *) NULL;\r
+ err = ENOMEM;\r
+ }\r
+ \r
+ if ((err = NXKeySetValue(key, thread_data))) {\r
+ free(thread_data->twentybytes);\r
+ free(thread_data);\r
+ thread_data = (libthreaddata_t *) NULL;\r
}\r
+ }\r
}\r
+ }\r
\r
- if (appData)\r
- *appData = app_data;\r
+ if (appData)\r
+ *appData = app_data;\r
\r
- if (threadData)\r
- *threadData = thread_data;\r
+ if (threadData)\r
+ *threadData = thread_data;\r
\r
- return err;\r
+ return err;\r
}\r
\r
-int DisposeLibraryData\r
-(\r
- void *data\r
-)\r
+int DisposeLibraryData( void *data)\r
{\r
- if (data)\r
- {\r
- void *tenbytes = ((libdata_t *) data)->tenbytes;\r
-\r
- if (tenbytes)\r
- free(tenbytes);\r
-\r
- free(data);\r
- }\r
-\r
- return 0;\r
+ if (data) {\r
+ void *tenbytes = ((libdata_t *) data)->tenbytes;\r
+ \r
+ if (tenbytes)\r
+ free(tenbytes);\r
+ \r
+ free(data);\r
+ }\r
+\r
+ return 0;\r
}\r
\r
-void DisposeThreadData\r
-(\r
- void *data\r
-)\r
+void DisposeThreadData(void *data)\r
{\r
- if (data)\r
- {\r
- void *twentybytes = ((libthreaddata_t *) data)->twentybytes;\r
-\r
- if (twentybytes)\r
- free(twentybytes);\r
-\r
- free(data);\r
- }\r
+ if (data) {\r
+ void *twentybytes = ((libthreaddata_t *) data)->twentybytes;\r
+ \r
+ if (twentybytes)\r
+ free(twentybytes);\r
+ \r
+ free(data);\r
+ }\r
}\r
-\r
-\r
#include "base64.h"
#include "sendf.h"
#include "ftp.h"
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#define min(a, b) ((a) < (b) ? (a) : (b))
#include "security.h"
#endif
#include <string.h>
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/* returns last node in linked list */
static struct curl_slist *slist_get_last(struct curl_slist *list)
#include <curl/curl.h>
#include "urldata.h"
#include "share.h"
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
CURLSH *
curl_share_init(void)
#include <openssl/rand.h>
#include <openssl/x509v3.h>
+#include "memory.h"
+
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#if OPENSSL_VERSION_NUMBER >= 0x0090581fL
#define HAVE_SSL_GET1_SESSION 1
#define TELCMDS
#include "arpa_telnet.h"
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#define SUBBUFSIZE 512
#include "http_ntlm.h"
#include "http_negotiate.h"
#include "share.h"
+#include "memory.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
#define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */
#ifdef HAVE_KRB4
#include "security.h"
#endif
+#include "memory.h"
/* The last #include file should be: */
-#ifdef CURLDEBUG
#include "memdebug.h"
-#endif
/* Local static prototypes */
static int ConnectionKillOne(struct SessionHandle *data);
my $curl;
my $libcurl;
- my @version=`$CURL -V 2>/dev/null`;
+ my @version=`strace $CURL --version 2>fump`;
for(@version) {
chomp;
}
}
if(!$curl) {
- die "couldn't run curl!"
+ die "couldn't run '$CURL'"
}
my $hostname=`hostname`;