Postfix3.3.1
load_lib.c
[詳解]
1 /*++
2 /* NAME
3 /* load_lib 3
4 /* SUMMARY
5 /* library loading wrappers
6 /* SYNOPSIS
7 /* #include <load_lib.h>
8 /*
9 /* void load_library_symbols(const char *, LIB_FN *, LIB_DP *);
10 /* const char *libname;
11 /* LIB_FN *libfuncs;
12 /* LIB_DP *libdata;
13 /* DESCRIPTION
14 /* load_library_symbols() loads the specified shared object
15 /* and looks up the function or data pointers for the specified
16 /* symbols. All errors are fatal.
17 /*
18 /* Arguments:
19 /* .IP libname
20 /* shared-library pathname.
21 /* .IP libfuncs
22 /* Array of LIB_FN strucures. The last name member must be null.
23 /* .IP libdata
24 /* Array of LIB_DP strucures. The last name member must be null.
25 /* SEE ALSO
26 /* msg(3) diagnostics interface
27 /* DIAGNOSTICS
28 /* Problems are reported via the msg(3) diagnostics routines:
29 /* library not found, symbols not found, other fatal errors.
30 /* LICENSE
31 /* .ad
32 /* .fi
33 /* The Secure Mailer license must be distributed with this software.
34 /* AUTHOR(S)
35 /* LaMont Jones
36 /* Hewlett-Packard Company
37 /* 3404 Harmony Road
38 /* Fort Collins, CO 80528, USA
39 /*
40 /* Wietse Venema
41 /* IBM T.J. Watson Research
42 /* P.O. Box 704
43 /* Yorktown Heights, NY 10598, USA
44 /*--*/
45 
46  /*
47  * System libraries.
48  */
49 #include "sys_defs.h"
50 #include <stdlib.h>
51 #include <stddef.h>
52 #include <string.h>
53 #ifdef USE_DYNAMIC_MAPS
54 #if defined(HAS_DLOPEN)
55 #include <dlfcn.h>
56 #elif defined(HAS_SHL_LOAD)
57 #include <dl.h>
58 #else
59 #error "USE_DYNAMIC_LIBS requires HAS_DLOPEN or HAS_SHL_LOAD"
60 #endif
61 
62  /*
63  * Utility library.
64  */
65 #include <msg.h>
66 #include <load_lib.h>
67 
68 /* load_library_symbols - load shared library and look up symbols */
69 
70 void load_library_symbols(const char *libname, LIB_FN *libfuncs,
71  LIB_DP *libdata)
72 {
73  static const char myname[] = "load_library_symbols";
74  LIB_FN *fn;
75  LIB_DP *dp;
76 
77 #if defined(HAS_DLOPEN)
78  void *handle;
79  char *emsg;
80 
81  /*
82  * XXX This is basically how FreeBSD dlfunc() silences a compiler warning
83  * about a data/function pointer conversion. The solution below is non-
84  * portable: it assumes that both data and function pointers are the same
85  * in size, and that both have the same representation.
86  */
87  union {
88  void *dptr; /* data pointer */
89  void (*fptr) (void); /* function pointer */
90  } non_portable_union;
91 
92  if ((handle = dlopen(libname, RTLD_NOW)) == 0) {
93  emsg = dlerror();
94  msg_fatal("%s: dlopen failure loading %s: %s", myname, libname,
95  emsg ? emsg : "don't know why");
96  }
97  if (libfuncs) {
98  for (fn = libfuncs; fn->name; fn++) {
99  if ((non_portable_union.dptr = dlsym(handle, fn->name)) == 0) {
100  emsg = dlerror();
101  msg_fatal("%s: dlsym failure looking up %s in %s: %s", myname,
102  fn->name, libname, emsg ? emsg : "don't know why");
103  }
104  fn->fptr = non_portable_union.fptr;
105  if (msg_verbose > 1)
106  msg_info("loaded %s = %p", fn->name, non_portable_union.dptr);
107  }
108  }
109  if (libdata) {
110  for (dp = libdata; dp->name; dp++) {
111  if ((dp->dptr = dlsym(handle, dp->name)) == 0) {
112  emsg = dlerror();
113  msg_fatal("%s: dlsym failure looking up %s in %s: %s", myname,
114  dp->name, libname, emsg ? emsg : "don't know why");
115  }
116  if (msg_verbose > 1)
117  msg_info("loaded %s = %p", dp->name, dp->dptr);
118  }
119  }
120 #elif defined(HAS_SHL_LOAD)
121  shl_t handle;
122 
123  handle = shl_load(libname, BIND_IMMEDIATE, 0);
124 
125  if (libfuncs) {
126  for (fn = libfuncs; fn->name; fn++) {
127  if (shl_findsym(&handle, fn->name, TYPE_PROCEDURE, &fn->fptr) != 0)
128  msg_fatal("%s: shl_findsym failure looking up %s in %s: %m",
129  myname, fn->name, libname);
130  if (msg_verbose > 1)
131  msg_info("loaded %s = %p", fn->name, (void *) fn->fptr);
132  }
133  }
134  if (libdata) {
135  for (dp = libdata; dp->name; dp++) {
136  if (shl_findsym(&handle, dp->name, TYPE_DATA, &dp->dptr) != 0)
137  msg_fatal("%s: shl_findsym failure looking up %s in %s: %m",
138  myname, dp->name, libname);
139  if (msg_verbose > 1)
140  msg_info("loaded %s = %p", dp->name, dp->dptr);
141  }
142  }
143 #endif
144 }
145 
146 #endif
int msg_verbose
Definition: msg.c:177
const char * name
Definition: load_lib.h:24
void load_library_symbols(const char *, LIB_FN *, LIB_DP *)
void(* fptr)(void)
Definition: load_lib.h:20
const char * name
Definition: load_lib.h:19
void * dptr
Definition: load_lib.h:25
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
void msg_info(const char *fmt,...)
Definition: msg.c:199