source: git/libpolys/polys/mod_raw.cc @ 763c4d

spielwiese
Last change on this file since 763c4d was 394d507, checked in by Hans Schoenemann <hannes@…>, 10 years ago
chg: use LIBEXEC_DIR/PREFIX for resources
  • Property mode set to 100644
File size: 6.7 KB
Line 
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#ifdef HAVE_CONFIG_H
23#include "libpolysconfig.h"
24#endif /* HAVE_CONFIG_H */
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 *****************************************************************************/
49static BOOLEAN warn_handle = FALSE;
50static BOOLEAN warn_proc = FALSE;
51#ifndef DL_TAIL
52#ifdef NDEBUG
53#define DL_TAIL ".so"
54#else
55#define DL_TAIL ".so"
56//#define DL_TAIL "_g.so"
57#endif
58#endif
59
60void* dynl_open_binary_warn(const char* binary_name, const char* msg)
61{
62  void* handle = NULL;
63  char* binary_name_so=NULL;
64  BOOLEAN found=FALSE;
65
66  // try P_PROCS_DIR (%P)
67  char* proc_path = feGetResource('P');
68  if (proc_path != NULL)
69  {
70    char *p;
71    char *q;
72    p=proc_path;
73    int binary_name_so_length = 3 + strlen(DL_TAIL) + strlen(binary_name) + strlen(DIR_SEPP) + strlen(proc_path);
74    binary_name_so = (char *)omAlloc0( binary_name_so_length * sizeof(char) );
75    while((p!=NULL)&&(*p!='\0'))
76    {
77      q=strchr(p,fePathSep);
78      if (q!=NULL) *q='\0';
79      strcpy(binary_name_so,p);
80      if (q!=NULL) *q=fePathSep;
81      strcat(binary_name_so,DIR_SEPP);
82      strcat(binary_name_so,binary_name);
83      strcat(binary_name_so,DL_TAIL);
84      if(!access(binary_name_so, R_OK)) { found=TRUE; break; }
85      if (q!=NULL) p=q+1; else p=NULL;
86    }
87    if (found) handle = dynl_open(binary_name_so);
88  }
89
90  if (handle == NULL && ! warn_handle)
91  {
92    Warn("Could not find dynamic library: %s%s (path %s)",
93            binary_name, DL_TAIL,proc_path);
94    if (found) Warn("Error message from system: %s", dynl_error());
95    if (msg != NULL) Warn("%s", msg);
96    Warn("See the INSTALL section in the Singular manual for details.");
97    warn_handle = TRUE;
98  }
99  omfree((ADDRESS)binary_name_so );
100
101  return  handle;
102}
103
104void* dynl_sym_warn(void* handle, const char* proc, const char* msg)
105{
106  void *proc_ptr = NULL;
107  if (handle != NULL)
108  {
109    proc_ptr = dynl_sym(handle, proc);
110    if (proc_ptr == NULL && ! warn_proc)
111    {
112      Warn("Could load a procedure from a dynamic library");
113      Warn("Error message from system: %s", dynl_error());
114      if (msg != NULL) Warn("%s", msg);
115      Warn("See the INSTALL section in the Singular manual for details.");
116      warn_proc = TRUE;
117    }
118  }
119  return proc_ptr;
120}
121
122#ifdef __cplusplus
123extern "C" {
124#endif
125
126/*****************************************************************************
127 * SECTION generic ELF: ix86-linux / alpha-linux / IA64-linux /x86_64_Linux  *
128 *                      SunOS-5 / IRIX-6 / ppcMac-Darwin / FreeeBSD          *
129 *****************************************************************************/
130// relying on gcc to define __ELF__, check with cpp -dM /dev/null
131#if defined(__ELF__)
132#define HAVE_ELF_SYSTEM
133#endif
134
135// Mac OsX is an ELF system, but does not define __ELF__
136#if (defined(__APPLE__) && defined(__MACH__)) && (!defined(HAVE_ELF_SYSTEM))
137#define HAVE_ELF_SYSTEM
138#endif
139
140// Solaris is an ELF system, but does not define __ELF__
141#if defined(__sun) && defined(__SVR4)
142#define HAVE_ELF_SYSTEM
143#endif
144
145#if defined(HAVE_ELF_SYSTEM)
146#include <dlfcn.h>
147#define DL_IMPLEMENTED
148
149static void* kernel_handle = NULL;
150int dynl_check_opened(
151  char *filename    /* I: filename to check */
152  )
153{
154  return dlopen(filename,RTLD_NOW|RTLD_NOLOAD) != NULL;
155}
156
157void *dynl_open(
158  char *filename    /* I: filename to load */
159  )
160{
161// glibc 2.2:
162  if ((filename==NULL) || (dlopen(filename,RTLD_NOW|RTLD_NOLOAD)==NULL))
163    return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
164  else
165    Werror("module %s already loaded",filename);
166  return NULL;
167// alternative
168//    return(dlopen(filename, RTLD_NOW|RTLD_GLOBAL));
169}
170
171void *dynl_sym(void *handle, const char *symbol)
172{
173  if (handle == DYNL_KERNEL_HANDLE)
174  {
175    if (kernel_handle == NULL)
176      kernel_handle = dynl_open(NULL);
177    handle = kernel_handle;
178  }
179  return(dlsym(handle, symbol));
180}
181
182int dynl_close (void *handle)
183{
184  return(dlclose (handle));
185}
186
187const char *dynl_error()
188{
189  return(dlerror());
190}
191#endif /* ELF_SYSTEM */
192
193/*****************************************************************************
194 * SECTION HPUX-9/10                                                         *
195 *****************************************************************************/
196#if defined(HPUX_9) || defined(HPUX_10)
197#define DL_IMPLEMENTED
198#include <dl.h>
199
200typedef char *((*func_ptr) ());
201
202int dynl_check_opened(    /* NOTE: untested */
203  char *filename    /* I: filename to check */
204  )
205{
206  struct shl_descriptor *desc;
207  for (int idx = 0; shl_get(idx, &desc) != -1; ++idx)
208  {
209    if (strcmp(filename, desc->filename) == 0) return TRUE;
210  }
211  return FALSE;
212}
213
214void *dynl_open(char *filename)
215{
216  shl_t           handle = shl_load(filename, BIND_DEFERRED, 0);
217
218  return ((void *) handle);
219}
220
221void *dynl_sym(void *handle, const char *symbol)
222{
223  func_ptr        f;
224
225  if (handle == DYNL_KERNEL_HANDLE)
226    handle = PROG_HANDLE;
227
228  if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &f) == -1)
229  {
230    if (shl_findsym((shl_t *) & handle, symbol, TYPE_UNDEFINED, &f) == -1)
231    {
232      f = (func_ptr) NULL;
233    }
234  }
235  return ((void *)f);
236}
237
238int dynl_close (void *handle)
239{
240  shl_unload((shl_t) handle);
241  return(0);
242}
243
244const char *dynl_error()
245{
246  static char errmsg[] = "shl_load failed";
247
248  return errmsg;
249}
250#endif /* HPUX_9  or HPUX_10 */
251
252/*****************************************************************************
253 * SECTION generic: dynamic madules not available
254 *****************************************************************************/
255#ifndef DL_IMPLEMENTED
256
257int dynl_check_opened(char *filename)
258{
259  return FALSE;
260}
261
262void *dynl_open(char *filename)
263{
264  return(NULL);
265}
266
267void *dynl_sym(void *handle, const char *symbol)
268{
269  return(NULL);
270}
271
272int dynl_close (void *handle)
273{
274  return(0);
275}
276
277const char *dynl_error()
278{
279  static char errmsg[] = "support for dynamic loading not implemented";
280  return errmsg;
281}
282#endif
283
284#ifdef __cplusplus
285}
286#endif
287
288#endif /* HAVE_DL */
Note: See TracBrowser for help on using the repository browser.