File: module.c

package info (click to toggle)
tcng 10b-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 3,632 kB
  • ctags: 2,515
  • sloc: ansic: 19,038; pascal: 4,640; yacc: 2,619; sh: 1,908; perl: 1,546; lex: 772; makefile: 755
file content (86 lines) | stat: -rw-r--r-- 1,914 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
 * module.c - Load "kernel modules"
 *
 * Written 2001,2002 by Werner Almesberger
 * Copyright 2001 EPFL-ICA, Network Robots
 * Copyright 2002 Werner Almesberger
 */
 

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>

#include <memutil.h>

#include "tcsim.h"


void *tc_module(char prefix,const char *name); /* extern in ulib */

void *tc_module(char prefix,const char *name)
{
    char *symbol,*path;
    void *handle,*util;

    /*
     * dlopen keeps track of what we've loaded, so it's actually safe to call
     * it whenever we need that element. Caching the new elements, like
     * iproute2/tc does, is of course more efficient.
     */
    symbol = alloc_sprintf("%s_util",name);
    handle = dlopen(NULL,RTLD_NOW); /* preloaded ? */
    if (handle) {
	util = dlsym(handle,symbol);
	if (util) {
	    free(symbol);
	    return util;
	}
    }
    path = alloc_sprintf("%c_%s.so",prefix,name);
    handle = dlopen(path,RTLD_NOW);
    if (!handle) {
	free(path);
	free(symbol);
	return NULL;
    }
    util = dlsym(handle,symbol);
    if (util) {
	free(path);
	free(symbol);
	return util;
    }
    errorf("%s does not define %s",path,symbol);
    return NULL; /* not reached */
}


void preload_tc_module(const char *path)
{
    void *handle;

    handle = dlopen(path,RTLD_NOW | RTLD_GLOBAL);
    if (!handle) errorf("%s",dlerror());
}


/*
 * Buglet: libc seems to have its own init_module, which is found if our @@@
 * module doesn't have one. Very irritating ...
 */

void kernel_module(const char *path)
{
    void *handle;
    int (*init_module)(void);
    int error;

    handle = dlopen(path,RTLD_NOW);
    if (!handle) errorf("%s",dlerror());
    init_module = dlsym(handle,"init_module");
    if (!init_module) errorf("module %s: symbol init_module not found");
    error = init_module();
    if (!error) return;
    yyerrorf("init_module: %s",strerror(error));
}