File: dlfcn.c

package info (click to toggle)
xlispstat 3.52.14-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 7,560 kB
  • ctags: 12,676
  • sloc: ansic: 91,357; lisp: 21,759; sh: 1,525; makefile: 521; csh: 1
file content (92 lines) | stat: -rw-r--r-- 2,268 bytes parent folder | download | duplicates (4)
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
87
88
89
90
91
92
#include <stddef.h>
#include <string.h>
#include <dlfcn.h>
#include <stdio.h>

#include <CodeFragments.h>
#include "macutils.h"

static char errbuf[512];

/* Minimal emulation of SysVR4-ELF dynamic loading routines for the Macintosh.
 * Based on code by Bob Stine as Modified by Steve Majewski. */
void *dlopen(const char *name, int mode)
{
  FSSpec fileSpec;
  Str255 errName, libName;
  OSErr err;
  Ptr mainAddr;
  CFragConnectionID connID;

  /* Build a file spec record for GetDiskFragment */
  if (strlen(name) < 254)
    strcpy((char *) libName, name);
  else {
    sprintf(errbuf, "library name too long");
    return NULL;
  }
  CtoPstr((char *) libName);
  err = FSMakeFSSpecFromPath((ConstStr255Param) libName, &fileSpec);
  if (err != noErr) {
    sprintf(errbuf, "error code %d creating file spec for library %s",
            err, name);
    return NULL;
  }

  /* Open the fragment (will not add another copy if loaded, though gives
     new ID) */
  err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, 0, kLoadCFrag,
                        &connID, &mainAddr, errName);
  if (err == noErr)
    return (void *) connID;
  else {
    PtoCstr(errName);
    sprintf(errbuf, "error code %d getting disk fragment %s for library %s",
            err, errName, name);
    return NULL;
  }
}

/* This version does not handle NULL as the library for looking in the
   executable. It also does not check the symbol class. */
void *dlsym(void *lib, const char *name)
{
  CFragConnectionID connID = (CFragConnectionID) lib;
  OSErr err;
  Ptr symAddr;
  CFragSymbolClass symClass;
  Str255 symName;
  
  if (strlen(name) < 254)
    strcpy((char *) symName, name);
  else {
    sprintf(errbuf, "symbol name too long");
    return NULL;
  }
  CtoPstr((char *) symName);
  err = FindSymbol(connID, symName, &symAddr, &symClass);
  if (err == noErr)
    return (void *) symAddr;
  else {
    sprintf(errbuf, "error code %d looking up symbol %s", err, name);
    return NULL;
  }
}

int dlclose(void *lib)
{
  CFragConnectionID connID = (CFragConnectionID) lib;
  OSErr err;
  err = CloseConnection(&connID);
  if (err == noErr)
    return 0;
  else {
    sprintf(errbuf, "error code %d closing library", err);
    return -1;
  }
}

char *dlerror()
{
  return errbuf;
}