Coverage Report

Created: 2023-05-28 06:42

/src/netcdf-c/libncpoco/cp_unix.c
Line
Count
Source (jump to first uncovered line)
1
/*********************************************************************
2
 *   Copyright 1993, UCAR/Unidata
3
 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4
 *   Derived from poco library from Boost Software: see nccpoco/LICENSE file.
5
 *********************************************************************/
6
7
#include "config.h"
8
#include <stdlib.h>
9
#include <stdio.h>
10
#include <string.h>
11
#ifdef HAVE_DLFCN_H
12
#include <dlfcn.h>
13
#endif
14
#ifdef USE_MUTEX
15
#include <pthread.h>
16
#endif
17
18
#include "netcdf.h"
19
#include "ncpoco.h"
20
#include "ncpathmgr.h"
21
22
#undef DEBUG
23
24
/* Note: cygwin is missing RTLD_LOCAL, set it to 0 */
25
#if !defined(RTLD_LOCAL)
26
#define RTLD_LOCAL 0
27
#endif
28
29
#if !defined(RTLD_GLOBAL)
30
#define RTLD_GLOBAL 0
31
#endif
32
33
#if !defined(RTLD_LAZY)
34
#define RTLD_LAZY 1
35
#endif
36
37
#if !defined(RTLD_NOW)
38
#define RTLD_NOW 2
39
#endif
40
41
#ifdef USE_MUTEX
42
static pthread_mutex_t mutex;
43
#endif
44
45
static void
46
ncperr(const char* fcn, NCPSharedLib* lib)
47
0
{
48
0
    const char* msg = dlerror();
49
0
    lib->err.msg[0] = '\0';
50
0
    if(msg != NULL) {
51
0
  strlcat(lib->err.msg,fcn,sizeof(lib->err.msg));
52
0
  strlcat(lib->err.msg,": ",sizeof(lib->err.msg));
53
0
  strlcat(lib->err.msg,msg,sizeof(lib->err.msg));
54
#ifdef DEBUG
55
  fprintf(stderr,">>> %s\n",lib->err.msg);
56
#endif
57
0
    }
58
0
}
59
60
int
61
ncp_unix_initialize(void)
62
0
{
63
0
    int ret = 1;
64
#ifdef USE_MUTEX
65
    pthread_mutexattr_t attr;
66
    pthread_mutexattr_init(&attr);
67
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
68
    if(pthread_mutex_init(&mutex, &attr)) {
69
  fprintf(stderr,"cp_unix: Cannot create mutext\n");
70
  ret = 1;
71
    }
72
    pthread_mutexattr_destroy(&attr);
73
#endif
74
0
    return ret;
75
0
}
76
77
int
78
ncp_unix_finalize(void)
79
0
{
80
#ifdef USE_MUTEX
81
    pthread_mutex_destroy(&mutex);
82
#endif
83
0
    return 1;
84
0
}
85
86
/**************************************************/
87
88
#ifdef USE_MUTEX
89
static void lock(void) {pthread_mutex_lock(&mutex);}
90
#else
91
#define lock()
92
#endif
93
94
#ifdef USE_MUTEX
95
static void unlock(void) {pthread_mutex_unlock(&mutex);}
96
#else
97
#define unlock()
98
#endif
99
100
/**************************************************/
101
102
static int
103
init(NCPSharedLib* lib)
104
0
{
105
0
    int ret = NC_NOERR;
106
0
    return ret;
107
0
}
108
109
static int
110
reclaim(NCPSharedLib* lib)
111
0
{
112
0
    int ret = NC_NOERR;
113
0
    return ret;
114
0
}
115
116
static int
117
load(NCPSharedLib* lib , const char* path0, int flags)
118
0
{
119
0
    int ret = NC_NOERR;
120
0
    int realflags = RTLD_LAZY; /* versus RTLD_NOW which does not appear to work */
121
0
    char* path = NULL;
122
123
0
    if((path = NCpathcvt(path0))==NULL) {ret = NC_ENOMEM; goto done;}
124
125
0
    lock();
126
0
    if(lib->state.handle != NULL)
127
0
  {ret = NC_EEXIST; goto ldone;}
128
0
    lib->path = nulldup(path);
129
0
    lib->flags = flags;
130
0
    if(flags & NCP_LOCAL)
131
0
  realflags |= RTLD_LOCAL;
132
0
    else
133
0
  realflags |= RTLD_GLOBAL;
134
0
    lib->state.flags = realflags;
135
0
    lib->state.handle = dlopen(lib->path, lib->state.flags);
136
0
    if(lib->state.handle == NULL) {
137
0
  ncperr("dlopen",lib);
138
0
  ret = NC_ENOTFOUND;
139
0
  goto ldone;
140
0
    }
141
0
ldone:
142
0
    unlock();
143
0
done:
144
0
    nullfree(path);
145
0
    return ret;
146
0
}
147
148
static int
149
unload(NCPSharedLib* lib)
150
0
{
151
0
    int ret = NC_NOERR;
152
0
    lock();
153
0
    if(lib->state.handle != NULL) {
154
0
  dlclose(lib->state.handle);
155
0
  lib->state.handle = NULL;
156
0
    }
157
0
    unlock();
158
0
    return ret;
159
0
}
160
161
static int
162
isLoaded(NCPSharedLib* lib)
163
0
{
164
0
    return lib->state.handle != NULL;
165
0
}
166
167
static void*
168
getsymbol(NCPSharedLib* lib, const char* name)
169
0
{
170
0
    void* result = NULL;
171
0
    lock();
172
0
    if(lib->state.handle != NULL) {
173
0
  result = dlsym(lib->state.handle, name);
174
0
  if(result == NULL) {
175
0
      ncperr("dlsym",lib);
176
0
  }
177
0
    }
178
0
    unlock();
179
0
    return result;
180
0
}
181
182
static const char*
183
getpath(NCPSharedLib* lib)
184
0
{
185
0
    return lib->path;
186
0
}
187
188
struct NCPAPI ncp_unix_api = {
189
  init,
190
  reclaim,
191
  load,
192
  unload,
193
  isLoaded,
194
  getsymbol,
195
  getpath,
196
};