File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / compat / dlopen.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:11 2013 UTC (11 years ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, v1_8_7p0, v1_8_7, HEAD
1.8.7

    1: /*
    2:  * Copyright (c) 2010, 2012-2013 Todd C. Miller <Todd.Miller@courtesan.com>
    3:  *
    4:  * Permission to use, copy, modify, and distribute this software for any
    5:  * purpose with or without fee is hereby granted, provided that the above
    6:  * copyright notice and this permission notice appear in all copies.
    7:  *
    8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   15:  */
   16: 
   17: #include <config.h>
   18: 
   19: #ifndef HAVE_DLOPEN
   20: 
   21: #include <sys/types.h>
   22: 
   23: #include <stdio.h>
   24: #ifdef STDC_HEADERS
   25: # include <stdlib.h>
   26: # include <stddef.h>
   27: #else
   28: # ifdef HAVE_STDLIB_H
   29: #  include <stdlib.h>
   30: # endif
   31: #endif /* STDC_HEADERS */
   32: #ifdef HAVE_STRING_H
   33: # include <string.h>
   34: #endif /* HAVE_STRING_H */
   35: #ifdef HAVE_STRINGS_H
   36: # include <strings.h>
   37: #endif /* HAVE_STRINGS_H */
   38: #include <errno.h>
   39: 
   40: #include "compat/dlfcn.h"
   41: #include "missing.h"
   42: 
   43: #ifdef HAVE_SHL_LOAD
   44: /*
   45:  * Emulate dlopen() using shl_load().
   46:  */
   47: #include <dl.h>
   48: 
   49: #ifndef DYNAMIC_PATH
   50: # define DYNAMIC_PATH	0
   51: #endif
   52: 
   53: void *
   54: sudo_dlopen(const char *path, int mode)
   55: {
   56:     int flags = DYNAMIC_PATH | BIND_VERBOSE;
   57: 
   58:     if (mode == 0)
   59: 	mode = RTLD_LAZY;	/* default behavior */
   60: 
   61:     /* We don't support RTLD_GLOBAL or RTLD_LOCAL yet. */
   62:     if (ISSET(mode, RTLD_LAZY))
   63: 	flags |= BIND_DEFERRED;
   64:     if (ISSET(mode, RTLD_NOW))
   65: 	flags |= BIND_IMMEDIATE;
   66: 
   67:     return (void *)shl_load(path, flags, 0L);
   68: }
   69: 
   70: int
   71: sudo_dlclose(void *handle)
   72: {
   73:     return shl_unload((shl_t)handle);
   74: }
   75: 
   76: void *
   77: sudo_dlsym(void *vhandle, const char *symbol)
   78: {
   79:     shl_t handle = vhandle;
   80:     void *value = NULL;
   81: 
   82:     /*
   83:      * Note that the behavior of of RTLD_NEXT and RTLD_SELF 
   84:      * differs from most implementations when called from
   85:      * a shared library.
   86:      */
   87:     if (vhandle == RTLD_NEXT) {
   88: 	/* Iterate over all shared libs looking for symbol. */
   89: 	struct shl_descriptor *desc;
   90: 	int idx = 0;
   91: 	while (shl_get(idx++, &desc) == 0) {
   92: 	    if (shl_findsym(&desc->handle, symbol, TYPE_UNDEFINED, &value) == 0)
   93: 		break;
   94: 	}
   95:     } else {
   96: 	if (vhandle == RTLD_DEFAULT)
   97: 	    handle = NULL;
   98: 	else if (vhandle == RTLD_SELF)
   99: 	    handle = PROG_HANDLE;
  100: 	(void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value);
  101:     }
  102: 
  103:     return value;
  104: }
  105: 
  106: char *
  107: sudo_dlerror(void)
  108: {
  109:     return strerror(errno);
  110: }
  111: 
  112: #else /* !HAVE_SHL_LOAD */
  113: 
  114: /*
  115:  * Emulate dlopen() using a static list of symbols compiled into sudo.
  116:  */
  117: 
  118: struct sudo_preload_table {
  119:     const char *name;
  120:     void *address;
  121: };
  122: extern struct sudo_preload_table sudo_preload_table[];
  123: 
  124: void *
  125: sudo_dlopen(const char *path, int mode)
  126: {
  127:     return (void *)path;
  128: }
  129: 
  130: int
  131: sudo_dlclose(void *handle)
  132: {
  133:     return 0;
  134: }
  135: 
  136: void *
  137: sudo_dlsym(void *handle, const char *symbol)
  138: {
  139:     struct sudo_preload_table *sym;
  140: 
  141:     if (symbol != RTLD_NEXT && symbol != RTLD_DEFAULT && symbol != RTLD_SELF) {
  142: 	for (sym = sudo_preload_table; sym->name != NULL; sym++) {
  143: 	    if (strcmp(symbol, sym->name) == 0)
  144: 		return sym->address;
  145: 	}
  146:     }
  147:     return NULL;
  148: }
  149: 
  150: char *
  151: sudo_dlerror(void)
  152: {
  153:     return strerror(errno);
  154: }
  155: #endif /* HAVE_SHL_LOAD */
  156: #endif /* HAVE_DLOPEN */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>