OSDN Git Service

Rename hinfo -> dtable. Name the former dtable array 'fdtab'.
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / dlfcn.cc
1 /* dlfcn.cc
2
3    Copyright 1998, 2000 Cygnus Solutions
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <ctype.h>
16 #include "dlfcn.h"
17 #include "dll_init.h"
18
19 #define _dl_error _reent_winsup()->_dl_error
20 #define _dl_buffer _reent_winsup()->_dl_buffer
21
22 static void __stdcall
23 set_dl_error (const char *str)
24 {
25   __small_sprintf (_dl_buffer, "%s: %E", str);
26   _dl_error = 1;
27 }
28
29 /* Check for existence of a file specified by the directory
30    and name components. If successful, return a pointer the
31    full pathname (static buffer), else return 0. */
32 static const char * __stdcall
33 check_access (const char *dir, const char *name)
34 {
35   static char buf[MAX_PATH];
36   const char *ret = 0;
37
38   buf[0] = 0;
39   strcpy (buf, dir);
40   strcat (buf, "\\");
41   strcat (buf, name);
42
43   if (!access (buf, F_OK))
44     ret = buf;
45   return ret;
46 }
47
48 /* Look for an executable file given the name and the environment
49    variable to use for searching (eg., PATH); returns the full
50    pathname (static buffer) if found or NULL if not. */
51 static const char * __stdcall
52 check_path_access (const char *mywinenv, const char *name)
53 {
54   path_conv buf;
55   return find_exec (name, buf, mywinenv, TRUE);
56 }
57
58 /* Simulate the same search as LoadLibary + check environment
59    variable LD_LIBRARY_PATH. If found, return the full pathname
60    (static buffer); if illegal, return the input string unchanged
61    and let the caller deal with it; return NULL otherwise.
62
63    Note that this should never be called with a NULL string, since
64    that is the introspective case, and the caller should not call
65    this function at all.  */
66 static const char * __stdcall
67 get_full_path_of_dll (const char* str)
68 {
69   int len = (str) ? strlen (str) : 0;
70
71   /* NULL or empty string or too long to be legal win32 pathname? */
72   if (len == 0 || len >= MAX_PATH - 1)
73     return str;
74
75   char buf[MAX_PATH];
76   static char name[MAX_PATH];
77   const char *ret = 0;
78
79   strcpy (name, str);
80
81   /* Add extension if necessary, but leave a trailing '.', if any, alone.
82      Files with trailing '.'s are handled differently by win32 API. */
83   if (str[len - 1] != '.')
84     {
85       /* Add .dll only if no extension provided. Handle various cases:
86            ./shlib              -->     ./shlib.dll
87            ./dir/shlib.so       -->     ./dir/shlib.so
88            shlib                -->     shlib.dll
89            shlib.dll            -->     shlib.dll
90            shlib.so             -->     shlib.so */
91       const char *p = strrchr (str, '.');
92       if (!p || isdirsep (p[1]))
93         strcat (name, ".dll");
94     }
95
96   /* Deal with fully qualified filename right away. Do the actual
97      conversion to win32 filename just before returning however. */
98   if (isabspath (str))
99     ret = name;
100
101   /* current directory */
102   if (!ret)
103     {
104       if (GetCurrentDirectory (MAX_PATH, buf) == 0)
105         small_printf ("WARNING: get_full_path_of_dll can't get current directory win32 %E\n");
106       else
107         ret = check_access (buf, name);
108     }
109
110   /* LD_LIBRARY_PATH */
111   if (!ret)
112     ret = check_path_access ("LD_LIBRARY_PATH=", name);
113
114   if (!ret)
115     {
116       if (GetSystemDirectory (buf, MAX_PATH) == 0)
117         small_printf ("WARNING: get_full_path_of_dll can't get system directory win32 %E\n");
118       else
119         ret = check_access (buf, name);
120     }
121
122   /* 16 bits system directory */
123   if (!ret && (os_being_run == winNT))
124     {
125       /* we assume last dir was xxxxx\SYSTEM32, so we remove 32 */
126       len = strlen (buf);
127       buf[len - 2] = 0;
128       ret = check_access (buf, name);
129     }
130
131   /* windows directory */
132   if (!ret)
133     {
134       if (GetWindowsDirectory (buf, MAX_PATH) == 0)
135         small_printf ("WARNING: get_full_path_of_dll can't get Windows directory win32 %E\n");
136       else
137         ret = check_access (buf, name);
138     }
139
140   /* PATH */
141   if (!ret)
142     ret = check_path_access ("PATH=", name);
143
144   /* Now do a final conversion to win32 pathname. This step is necessary
145      to resolve symlinks etc so that win32 API finds the underlying file.  */
146   if (ret)
147     {
148       path_conv real_filename (ret, PC_SYM_FOLLOW | PC_FULL);
149       if (real_filename.error)
150         ret = 0;
151       else
152         {
153           strcpy (name, real_filename.get_win32 ());
154           ret = name;
155         }
156     }
157   return ret;
158 }
159
160 void *
161 dlopen (const char *name, int)
162 {
163   SetResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlopen");
164
165   void *ret = 0;
166
167   if (!name)
168     {
169       /* handle for the current module */
170       ret = (void *) GetModuleHandle (NULL);
171     }
172   else
173     {
174       /* handle for the named library */
175       const char *fullpath = get_full_path_of_dll (name);
176       ret = (void *) LoadLibrary (fullpath);
177     }
178
179   if (!ret)
180     set_dl_error ("dlopen");
181   debug_printf ("ret %p", ret);
182
183   ReleaseResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlopen");
184   return ret;
185 }
186
187 void *
188 dlsym (void *handle, const char *name)
189 {
190   void *ret = (void *) GetProcAddress ((HMODULE) handle, name);
191   if (!ret)
192     set_dl_error ("dlsym");
193   debug_printf ("ret %p", ret);
194   return ret;
195 }
196
197 int
198 dlclose (void *handle)
199 {
200   SetResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlclose");
201
202   int ret = -1;
203   if (FreeLibrary ((HMODULE) handle))
204     ret = 0;
205   if (ret)
206     set_dl_error ("dlclose");
207
208   ReleaseResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlclose");
209   return ret;
210 }
211
212 char *
213 dlerror ()
214 {
215   char *ret = 0;
216   if (_dl_error)
217     ret = _dl_buffer;
218   return ret;
219 }