My Project  debian-1:4.1.1-p2+ds-4
mod_raw.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5  * ABSTRACT: machine depend code for dynamic modules
6  *
7  * Provides: dynl_check_opened()
8  * dynl_open()
9  * dynl_sym()
10  * dynl_error()
11  * dynl_close()
12 */
13 
14 #include <stdio.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <sys/stat.h>
18 #include <errno.h>
19 #include <unistd.h>
20 
21 
22 
23 
24 
25 #include "misc/auxiliary.h"
26 
27 #include "omalloc/omalloc.h"
28 
29 #include "reporter/reporter.h"
30 
31 #include "resources/feResource.h"
32 
33 #include "mod_raw.h"
34 
35 #ifdef HAVE_STATIC
36 #undef HAVE_DL
37 #endif
38 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
39 #if defined(HAVE_DL)
40 
41 /*****************************************************************************
42  *
43  * General section
44  * These are just wrappers around the repsective dynl_* calls
45  * which look for the binary in the bin_dir of Singular and ommit warnings if
46  * somethings goes wrong
47  *
48  *****************************************************************************/
50 static BOOLEAN warn_proc = FALSE;
51 #ifndef DL_TAIL
52 #define DL_TAIL ".so"
53 //#define DL_TAIL "_g.so"
54 #endif
55 
56 void* dynl_open_binary_warn(const char* binary_name, const char* msg)
57 {
58  void* handle = NULL;
59  char* binary_name_so=NULL;
61 
62  // try P_PROCS_DIR (%P)
63  char* proc_path = feGetResource('P');
64  if (proc_path != NULL)
65  {
66  char *p;
67  char *q;
68  p=proc_path;
69  int binary_name_so_length = 3 + strlen(DL_TAIL) + strlen(binary_name) + strlen(DIR_SEPP) + strlen(proc_path);
70  binary_name_so = (char *)omAlloc0( binary_name_so_length * sizeof(char) );
71  while((p!=NULL)&&(*p!='\0'))
72  {
73  q=strchr(p,fePathSep);
74  if (q!=NULL) *q='\0';
75  strcpy(binary_name_so,p);
76  if (q!=NULL) *q=fePathSep;
77  strcat(binary_name_so,DIR_SEPP);
78  strcat(binary_name_so,binary_name);
79  strcat(binary_name_so,DL_TAIL);
80  if(!access(binary_name_so, R_OK)) { found=TRUE; break; }
81  if (q!=NULL) p=q+1; else p=NULL;
82  }
83  if (found) handle = dynl_open(binary_name_so);
84  }
85 
86  if (handle == NULL && ! warn_handle)
87  {
88  Warn("Could not find dynamic library: %s%s (path %s)",
89  binary_name, DL_TAIL,proc_path);
90  if (found) Warn("Error message from system: %s", dynl_error());
91  if (msg != NULL) Warn("%s", msg);
92  WarnS("See the INSTALL section in the Singular manual for details.");
93  warn_handle = TRUE;
94  }
95  omfree((ADDRESS)binary_name_so );
96 
97  return handle;
98 }
99 
100 void* dynl_sym_warn(void* handle, const char* proc, const char* msg)
101 {
102  void *proc_ptr = NULL;
103  if (handle != NULL)
104  {
105  proc_ptr = dynl_sym(handle, proc);
106  if (proc_ptr == NULL && ! warn_proc)
107  {
108  WarnS("Could load a procedure from a dynamic library");
109  Warn("Error message from system: %s", dynl_error());
110  if (msg != NULL) Warn("%s", msg);
111  WarnS("See the INSTALL section in the Singular manual for details.");
112  warn_proc = TRUE;
113  }
114  }
115  return proc_ptr;
116 }
117 
118 #ifdef __cplusplus
119 extern "C" {
120 #endif
121 
122 /*****************************************************************************
123  * SECTION generic ELF: ix86-linux / alpha-linux / IA64-linux /x86_64_Linux *
124  * SunOS-5 / IRIX-6 / ppcMac-Darwin / FreeeBSD *
125  *****************************************************************************/
126 // relying on gcc to define __ELF__, check with cpp -dM /dev/null
127 #if defined(__ELF__)
128 #define HAVE_ELF_SYSTEM
129 #endif
130 
131 // Mac OsX is an ELF system, but does not define __ELF__
132 #if (defined(__APPLE__) && defined(__MACH__)) && (!defined(HAVE_ELF_SYSTEM))
133 #define HAVE_ELF_SYSTEM
134 #endif
135 
136 // Solaris is an ELF system, but does not define __ELF__
137 #if defined(__sun) && defined(__SVR4)
138 #define HAVE_ELF_SYSTEM
139 #endif
140 
141 #if defined(HAVE_ELF_SYSTEM)
142 #include <dlfcn.h>
143 #define DL_IMPLEMENTED
144 
145 static void* kernel_handle = NULL;
147  char *filename /* I: filename to check */
148  )
149 {
150  return dlopen(filename,RTLD_NOW|RTLD_NOLOAD) != NULL;
151 }
152 
153 void *dynl_open(
154  char *filename /* I: filename to load */
155  )
156 {
157 // glibc 2.2:
158  if ((filename==NULL) || (dlopen(filename,RTLD_NOW|RTLD_NOLOAD)==NULL))
159  return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
160  else
161  Werror("module %s already loaded",filename);
162  return NULL;
163 // alternative
164 // return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
165 }
166 
167 void *dynl_sym(void *handle, const char *symbol)
168 {
169  if (handle == DYNL_KERNEL_HANDLE)
170  {
171  if (kernel_handle == NULL)
173  handle = kernel_handle;
174  }
175  return(dlsym(handle, symbol));
176 }
177 
178 int dynl_close (void *handle)
179 {
180  return(dlclose (handle));
181 }
182 
183 const char *dynl_error()
184 {
185  return(dlerror());
186 }
187 #endif /* ELF_SYSTEM */
188 
189 /*****************************************************************************
190  * SECTION HPUX-9/10 *
191  *****************************************************************************/
192 #if defined(HPUX_9) || defined(HPUX_10)
193 #define DL_IMPLEMENTED
194 #include <dl.h>
195 
196 typedef char *((*func_ptr) ());
197 
198 int dynl_check_opened( /* NOTE: untested */
199  char *filename /* I: filename to check */
200  )
201 {
202  struct shl_descriptor *desc;
203  for (int idx = 0; shl_get(idx, &desc) != -1; ++idx)
204  {
205  if (strcmp(filename, desc->filename) == 0) return TRUE;
206  }
207  return FALSE;
208 }
209 
210 void *dynl_open(char *filename)
211 {
212  shl_t handle = shl_load(filename, BIND_DEFERRED, 0);
213 
214  return ((void *) handle);
215 }
216 
217 void *dynl_sym(void *handle, const char *symbol)
218 {
219  func_ptr f;
220 
221  if (handle == DYNL_KERNEL_HANDLE)
222  handle = PROG_HANDLE;
223 
224  if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &f) == -1)
225  {
226  if (shl_findsym((shl_t *) & handle, symbol, TYPE_UNDEFINED, &f) == -1)
227  {
228  f = (func_ptr) NULL;
229  }
230  }
231  return ((void *)f);
232 }
233 
234 int dynl_close (void *handle)
235 {
236  shl_unload((shl_t) handle);
237  return(0);
238 }
239 
240 const char *dynl_error()
241 {
242  static char errmsg[] = "shl_load failed";
243 
244  return errmsg;
245 }
246 #endif /* HPUX_9 or HPUX_10 */
247 
248 /*****************************************************************************
249  * SECTION generic: dynamic madules not available
250  *****************************************************************************/
251 #ifndef DL_IMPLEMENTED
252 
253 int dynl_check_opened(char *filename)
254 {
255  return FALSE;
256 }
257 
258 void *dynl_open(char *filename)
259 {
260  return(NULL);
261 }
262 
263 void *dynl_sym(void *handle, const char *symbol)
264 {
265  return(NULL);
266 }
267 
268 int dynl_close (void *handle)
269 {
270  return(0);
271 }
272 
273 const char *dynl_error()
274 {
275  static char errmsg[] = "support for dynamic loading not implemented";
276  return errmsg;
277 }
278 #endif
279 
280 #ifdef __cplusplus
281 }
282 #endif
283 
284 #endif /* HAVE_DL */
dynl_close
int dynl_close(void *handle)
Definition: mod_raw.cc:176
FALSE
#define FALSE
Definition: auxiliary.h:94
mod_raw.h
omalloc.h
f
FILE * f
Definition: checklibs.c:9
fePathSep
const char fePathSep
Definition: feResource.h:56
ADDRESS
void * ADDRESS
Definition: auxiliary.h:133
auxiliary.h
dynl_sym_warn
void * dynl_sym_warn(void *handle, const char *proc, const char *msg)
Definition: mod_raw.cc:99
reporter.h
dynl_error
const char * dynl_error()
Definition: mod_raw.cc:181
found
bool found
Definition: facFactorize.cc:56
warn_proc
static BOOLEAN warn_proc
Definition: mod_raw.cc:49
TRUE
#define TRUE
Definition: auxiliary.h:98
DIR_SEPP
#define DIR_SEPP
Definition: feResource.h:7
BOOLEAN
int BOOLEAN
Definition: auxiliary.h:85
dynl_open
void * dynl_open(char *filename)
Definition: mod_raw.cc:151
kernel_handle
static void * kernel_handle
Definition: mod_raw.cc:143
Werror
void Werror(const char *fmt,...)
Definition: reporter.cc:188
warn_handle
static BOOLEAN warn_handle
Definition: mod_raw.cc:48
DL_TAIL
#define DL_TAIL
Definition: mod_raw.cc:51
dynl_sym
void * dynl_sym(void *handle, const char *symbol)
Definition: mod_raw.cc:165
WarnS
#define WarnS
Definition: emacs.cc:77
dynl_open_binary_warn
void * dynl_open_binary_warn(const char *binary_name, const char *msg)
Definition: mod_raw.cc:55
NULL
#define NULL
Definition: omList.c:9
DYNL_KERNEL_HANDLE
#define DYNL_KERNEL_HANDLE
Definition: mod_raw.h:31
feGetResource
char * feGetResource(const char id, int warn)
Definition: feResource.cc:152
Warn
#define Warn
Definition: emacs.cc:76
feResource.h
p
int p
Definition: cfModGcd.cc:4019
dynl_check_opened
int dynl_check_opened(char *filename)
Definition: mod_raw.cc:144
proc
unsigned char * proc[NUM_PROC]
Definition: checklibs.c:16
omAlloc0
#define omAlloc0(size)
Definition: omAllocDecl.h:209
omfree
#define omfree(addr)
Definition: omAllocDecl.h:235