make DP compile with C++ again
[divverent/darkplaces.git] / sys_shared.c
1 #include "quakedef.h"
2 # include <time.h>
3 #ifndef WIN32
4 # include <unistd.h>
5 # include <fcntl.h>
6 # include <dlfcn.h>
7 #endif
8
9 static char sys_timestring[128];
10 char *Sys_TimeString(const char *timeformat)
11 {
12         time_t mytime = time(NULL);
13 #if _MSC_VER >= 1400
14         struct tm mytm;
15         localtime_s(&mytm, &mytime);
16         strftime(sys_timestring, sizeof(sys_timestring), timeformat, &mytm);
17 #else
18         strftime(sys_timestring, sizeof(sys_timestring), timeformat, localtime(&mytime));
19 #endif
20         return sys_timestring;
21 }
22
23
24 extern qboolean host_shuttingdown;
25 void Sys_Quit (int returnvalue)
26 {
27         if (COM_CheckParm("-profilegameonly"))
28                 Sys_AllowProfiling(false);
29         host_shuttingdown = true;
30         Host_Shutdown();
31         exit(returnvalue);
32 }
33
34 #if defined(__linux__) || defined(__FreeBSD__)
35 #ifdef __cplusplus
36 extern "C"
37 #endif
38 int moncontrol(int);
39 #endif
40
41 void Sys_AllowProfiling(qboolean enable)
42 {
43 #if defined(__linux__) || defined(__FreeBSD__)
44         moncontrol(enable);
45 #endif
46 }
47
48
49 /*
50 ===============================================================================
51
52 DLL MANAGEMENT
53
54 ===============================================================================
55 */
56
57 qboolean Sys_LoadLibrary (const char** dllnames, dllhandle_t* handle, const dllfunction_t *fcts)
58 {
59         const dllfunction_t *func;
60         dllhandle_t dllhandle = 0;
61         unsigned int i;
62
63         if (handle == NULL)
64                 return false;
65
66 #ifndef WIN32
67 #ifdef PREFER_PRELOAD
68         dllhandle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
69         if(dllhandle)
70         {
71                 for (func = fcts; func && func->name != NULL; func++)
72                         if (!(*func->funcvariable = (void *) Sys_GetProcAddress (dllhandle, func->name)))
73                         {
74                                 dlclose(dllhandle);
75                                 goto notfound;
76                         }
77                 Con_Printf ("All of %s's functions were already linked in! Not loading dynamically...\n", dllnames[0]);
78                 *handle = dllhandle;
79                 return true;
80         }
81 notfound:
82 #endif
83 #endif
84
85         // Initializations
86         for (func = fcts; func && func->name != NULL; func++)
87                 *func->funcvariable = NULL;
88
89         // Try every possible name
90         Con_Printf ("Trying to load library...");
91         for (i = 0; dllnames[i] != NULL; i++)
92         {
93                 Con_Printf (" \"%s\"", dllnames[i]);
94 #ifdef WIN32
95                 dllhandle = LoadLibrary (dllnames[i]);
96 #else
97                 dllhandle = dlopen (dllnames[i], RTLD_LAZY | RTLD_GLOBAL);
98 #endif
99                 if (dllhandle)
100                         break;
101         }
102
103         // see if the names can be loaded relative to the executable path
104         // (this is for Mac OSX which does not check next to the executable)
105         if (!dllhandle && strrchr(com_argv[0], '/'))
106         {
107                 char path[MAX_OSPATH];
108                 strlcpy(path, com_argv[0], sizeof(path));
109                 strrchr(path, '/')[1] = 0;
110                 for (i = 0; dllnames[i] != NULL; i++)
111                 {
112                         char temp[MAX_OSPATH];
113                         strlcpy(temp, path, sizeof(temp));
114                         strlcat(temp, dllnames[i], sizeof(temp));
115                         Con_Printf (" \"%s\"", temp);
116 #ifdef WIN32
117                         dllhandle = LoadLibrary (temp);
118 #else
119                         dllhandle = dlopen (temp, RTLD_LAZY | RTLD_GLOBAL);
120 #endif
121                         if (dllhandle)
122                                 break;
123                 }
124         }
125
126         // No DLL found
127         if (! dllhandle)
128         {
129                 Con_Printf(" - failed.\n");
130                 return false;
131         }
132
133         Con_Printf(" - loaded.\n");
134
135         // Get the function adresses
136         for (func = fcts; func && func->name != NULL; func++)
137                 if (!(*func->funcvariable = (void *) Sys_GetProcAddress (dllhandle, func->name)))
138                 {
139                         Con_Printf ("Missing function \"%s\" - broken library!\n", func->name);
140                         Sys_UnloadLibrary (&dllhandle);
141                         return false;
142                 }
143
144         *handle = dllhandle;
145         return true;
146 }
147
148 void Sys_UnloadLibrary (dllhandle_t* handle)
149 {
150         if (handle == NULL || *handle == NULL)
151                 return;
152
153 #ifdef WIN32
154         FreeLibrary (*handle);
155 #else
156         dlclose (*handle);
157 #endif
158
159         *handle = NULL;
160 }
161
162 void* Sys_GetProcAddress (dllhandle_t handle, const char* name)
163 {
164 #ifdef WIN32
165         return (void *)GetProcAddress (handle, name);
166 #else
167         return (void *)dlsym (handle, name);
168 #endif
169 }
170