Skip to content

Latest commit

 

History

History
323 lines (247 loc) · 7.93 KB

unix.c

File metadata and controls

323 lines (247 loc) · 7.93 KB
 
Jul 7, 2001
Jul 7, 2001
1
2
3
4
5
6
7
8
/*
* Unix support routines for PhysicsFS.
*
* Please see the file LICENSE in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
May 10, 2002
May 10, 2002
9
10
11
12
#if HAVE_CONFIG_H
# include <config.h>
#endif
Jul 10, 2002
Jul 10, 2002
13
14
/* BeOS uses beos.cpp and posix.c ... Cygwin and such use win32.c ... */
#if ((!defined __BEOS__) && (!defined WIN32))
Jun 29, 2002
Jun 29, 2002
15
Jul 7, 2001
Jul 7, 2001
16
17
#include <stdio.h>
#include <stdlib.h>
Jul 8, 2001
Jul 8, 2001
18
19
#include <string.h>
#include <ctype.h>
Jul 7, 2001
Jul 7, 2001
20
#include <pthread.h>
Jul 8, 2001
Jul 8, 2001
21
22
23
24
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <sys/stat.h>
Jul 16, 2001
Jul 16, 2001
25
#include <sys/param.h>
Jul 8, 2001
Jul 8, 2001
26
27
28
#include <dirent.h>
#include <time.h>
#include <errno.h>
Jul 20, 2002
Jul 20, 2002
29
#include <sys/mount.h>
Mar 5, 2002
Mar 5, 2002
30
Jul 20, 2002
Jul 20, 2002
31
32
33
34
35
#ifdef PHYSFS_HAVE_SYS_UCRED_H
# ifdef PHYSFS_HAVE_MNTENT_H
# undef PHYSFS_HAVE_MNTENT_H /* don't do both... */
# endif
# include <sys/ucred.h>
Mar 5, 2002
Mar 5, 2002
36
#endif
Jul 7, 2001
Jul 7, 2001
37
Jul 20, 2002
Jul 20, 2002
38
39
40
#ifdef PHYSFS_HAVE_MNTENT_H
#include <mntent.h>
#endif
Apr 6, 2002
Apr 6, 2002
41
Jul 7, 2001
Jul 7, 2001
42
43
44
45
46
47
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
const char *__PHYSFS_platformDirSeparator = "/";
Mar 5, 2002
Mar 5, 2002
48
Mar 24, 2002
Mar 24, 2002
49
50
51
52
53
54
55
56
57
58
59
60
int __PHYSFS_platformInit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformInit */
int __PHYSFS_platformDeinit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformDeinit */
Jul 25, 2002
Jul 25, 2002
61
62
63
64
65
66
67
68
69
70
71
72
73
#ifdef PHYSFS_NO_CDROM_SUPPORT
/* Stub version for platforms without CD-ROM support. */
char **__PHYSFS_platformDetectAvailableCDs(void)
{
char **retval = (char **) malloc(sizeof (char *));
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
*retval = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#else
Mar 24, 2002
Mar 24, 2002
74
Jul 20, 2002
Jul 20, 2002
75
#ifdef PHYSFS_HAVE_SYS_UCRED_H
Mar 5, 2002
Mar 5, 2002
76
77
78
79
80
char **__PHYSFS_platformDetectAvailableCDs(void)
{
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
Jul 25, 2002
Jul 25, 2002
81
struct statfs *mntbufp = NULL;
Mar 5, 2002
Mar 5, 2002
82
int mounts;
Jul 25, 2002
Jul 25, 2002
83
int i;
Mar 5, 2002
Mar 5, 2002
84
Apr 5, 2002
Apr 5, 2002
85
86
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
Jul 25, 2002
Jul 25, 2002
87
mounts = getmntinfo(&mntbufp, MNT_WAIT);
Mar 5, 2002
Mar 5, 2002
88
Jul 25, 2002
Jul 25, 2002
89
90
for (i = 0; i < mounts; i++)
{
Mar 5, 2002
Mar 5, 2002
91
92
int add_it = 0;
Jul 25, 2002
Jul 25, 2002
93
if (strcmp(mntbufp[i].f_fstypename, "iso9660") == 0)
Mar 5, 2002
Mar 5, 2002
94
add_it = 1;
Jul 25, 2002
Jul 25, 2002
95
else if (strcmp( mntbufp[i].f_fstypename, "cd9660") == 0)
Apr 6, 2002
Apr 6, 2002
96
add_it = 1;
May 21, 2002
May 21, 2002
97
98
/* add other mount types here */
Mar 5, 2002
Mar 5, 2002
99
100
101
if (add_it)
{
Jun 29, 2002
Jun 29, 2002
102
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
Mar 5, 2002
Mar 5, 2002
103
104
105
if (tmp)
{
retval = tmp;
Jun 29, 2002
Jun 29, 2002
106
retval[cd_count - 1] = (char *)
Jul 25, 2002
Jul 25, 2002
107
malloc(strlen(mntbufp[i].f_mntonname) + 1);
Jun 29, 2002
Jun 29, 2002
108
if (retval[cd_count - 1])
Mar 5, 2002
Mar 5, 2002
109
{
Jul 25, 2002
Jul 25, 2002
110
strcpy(retval[cd_count - 1], mntbufp[i].f_mntonname);
Mar 5, 2002
Mar 5, 2002
111
112
113
114
cd_count++;
} /* if */
} /* if */
} /* if */
Jul 25, 2002
Jul 25, 2002
115
} /* for */
Mar 5, 2002
Mar 5, 2002
116
117
118
119
120
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
Jul 20, 2002
Jul 20, 2002
121
#endif
Mar 5, 2002
Mar 5, 2002
122
123
Jul 20, 2002
Jul 20, 2002
124
#ifdef PHYSFS_HAVE_MNTENT_H
Mar 5, 2002
Mar 5, 2002
125
Jul 7, 2001
Jul 7, 2001
126
127
char **__PHYSFS_platformDetectAvailableCDs(void)
{
Aug 7, 2001
Aug 7, 2001
128
129
130
131
132
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
FILE *mounts = NULL;
struct mntent *ent = NULL;
Apr 5, 2002
Apr 5, 2002
133
134
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
Aug 7, 2001
Aug 7, 2001
135
136
137
138
139
140
141
142
143
*retval = NULL;
mounts = setmntent("/etc/mtab", "r");
BAIL_IF_MACRO(mounts == NULL, ERR_IO_ERROR, retval);
while ( (ent = getmntent(mounts)) != NULL )
{
int add_it = 0;
if (strcmp(ent->mnt_type, "iso9660") == 0)
add_it = 1;
May 21, 2002
May 21, 2002
144
145
/* add other mount types here */
Aug 7, 2001
Aug 7, 2001
146
147
148
if (add_it)
{
Jun 29, 2002
Jun 29, 2002
149
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
Aug 7, 2001
Aug 7, 2001
150
151
152
153
if (tmp)
{
retval = tmp;
retval[cd_count-1] = (char *) malloc(strlen(ent->mnt_dir) + 1);
Jun 29, 2002
Jun 29, 2002
154
if (retval[cd_count - 1])
Aug 7, 2001
Aug 7, 2001
155
{
Jun 29, 2002
Jun 29, 2002
156
strcpy(retval[cd_count - 1], ent->mnt_dir);
Aug 7, 2001
Aug 7, 2001
157
158
159
160
161
162
163
cd_count++;
} /* if */
} /* if */
} /* if */
} /* while */
endmntent(mounts);
Jul 8, 2001
Jul 8, 2001
164
Aug 7, 2001
Aug 7, 2001
165
retval[cd_count - 1] = NULL;
Jul 8, 2001
Jul 8, 2001
166
return(retval);
Mar 5, 2002
Mar 5, 2002
167
168
169
} /* __PHYSFS_platformDetectAvailableCDs */
#endif
Jul 7, 2001
Jul 7, 2001
170
Jul 25, 2002
Jul 25, 2002
171
172
#endif /* !PHYSFS_NO_CDROM_SUPPORT */
Jul 7, 2001
Jul 7, 2001
173
May 24, 2002
May 24, 2002
174
175
/* this is in posix.c ... */
extern char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname);
Jul 8, 2001
Jul 8, 2001
176
177
May 21, 2002
May 21, 2002
178
179
180
181
182
183
184
185
186
187
/*
* See where program (bin) resides in the $PATH specified by (envr).
* returns a copy of the first element in envr that contains it, or NULL
* if it doesn't exist or there were other problems. PHYSFS_SetError() is
* called if we have a problem.
*
* (envr) will be scribbled over, and you are expected to free() the
* return value when you're done with it.
*/
static char *findBinaryInPath(const char *bin, char *envr)
Jul 8, 2001
Jul 8, 2001
188
{
May 21, 2002
May 21, 2002
189
190
191
size_t alloc_size = 0;
char *exe = NULL;
char *start = envr;
Jul 8, 2001
Jul 8, 2001
192
193
char *ptr;
May 21, 2002
May 21, 2002
194
195
BAIL_IF_MACRO(bin == NULL, ERR_INVALID_ARGUMENT, NULL);
BAIL_IF_MACRO(envr == NULL, ERR_INVALID_ARGUMENT, NULL);
Jul 8, 2001
Jul 8, 2001
196
197
198
do
{
May 21, 2002
May 21, 2002
199
200
size_t size;
ptr = strchr(start, ':'); /* find next $PATH separator. */
Jul 8, 2001
Jul 8, 2001
201
202
203
if (ptr)
*ptr = '\0';
May 21, 2002
May 21, 2002
204
205
size = strlen(start) + strlen(bin) + 2;
if (size > alloc_size)
Jul 8, 2001
Jul 8, 2001
206
{
May 21, 2002
May 21, 2002
207
208
209
210
211
212
213
214
215
216
char *x = (char *) realloc(exe, size);
if (x == NULL)
{
if (exe != NULL)
free(exe);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
alloc_size = size;
exe = x;
Jul 8, 2001
Jul 8, 2001
217
} /* if */
May 21, 2002
May 21, 2002
218
219
/* build full binary path... */
Jul 8, 2001
Jul 8, 2001
220
strcpy(exe, start);
Aug 29, 2001
Aug 29, 2001
221
222
if (exe[strlen(exe) - 1] != '/')
strcat(exe, "/");
May 21, 2002
May 21, 2002
223
224
225
strcat(exe, bin);
if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */
Jul 8, 2001
Jul 8, 2001
226
{
May 21, 2002
May 21, 2002
227
228
229
strcpy(exe, start); /* i'm lazy. piss off. */
return(exe);
} /* if */
Jul 8, 2001
Jul 8, 2001
230
May 21, 2002
May 21, 2002
231
start = ptr + 1; /* start points to beginning of next element. */
Jul 8, 2001
Jul 8, 2001
232
233
} while (ptr != NULL);
May 21, 2002
May 21, 2002
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
if (exe != NULL)
free(exe);
return(NULL); /* doesn't exist in path. */
} /* findBinaryInPath */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
/* If there isn't a path on argv0, then look through the $PATH for it. */
char *retval;
char *envr;
if (strchr(argv0, '/') != NULL) /* default behaviour can handle this. */
return(NULL);
May 24, 2002
May 24, 2002
251
envr = __PHYSFS_platformCopyEnvironmentVariable("PATH");
May 21, 2002
May 21, 2002
252
253
BAIL_IF_MACRO(!envr, NULL, NULL);
retval = findBinaryInPath(argv0, envr);
Jul 8, 2001
Jul 8, 2001
254
255
256
257
258
free(envr);
return(retval);
} /* __PHYSFS_platformCalcBaseDir */
Mar 24, 2002
Mar 24, 2002
259
PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
Jul 7, 2001
Jul 7, 2001
260
{
Jul 25, 2002
Jul 25, 2002
261
return((PHYSFS_uint64) pthread_self());
Jul 7, 2001
Jul 7, 2001
262
263
264
} /* __PHYSFS_platformGetThreadID */
Jul 8, 2001
Jul 8, 2001
265
266
267
/* Much like my college days, try to sleep for 10 milliseconds at a time... */
void __PHYSFS_platformTimeslice(void)
{
Mar 5, 2002
Mar 5, 2002
268
usleep( 10 * 1000 ); /* don't care if it fails. */
Jul 8, 2001
Jul 8, 2001
269
270
271
} /* __PHYSFS_platformTimeslice */
Jul 16, 2001
Jul 16, 2001
272
273
274
275
276
277
278
char *__PHYSFS_platformRealPath(const char *path)
{
char resolved_path[MAXPATHLEN];
char *retval = NULL;
errno = 0;
BAIL_IF_MACRO(!realpath(path, resolved_path), strerror(errno), NULL);
May 24, 2002
May 24, 2002
279
retval = (char *) malloc(strlen(resolved_path) + 1);
Jul 16, 2001
Jul 16, 2001
280
281
282
283
284
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
strcpy(retval, resolved_path);
return(retval);
} /* __PHYSFS_platformRealPath */
Aug 23, 2001
Aug 23, 2001
285
Mar 30, 2002
Mar 30, 2002
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
void *__PHYSFS_platformCreateMutex(void)
{
int rc;
pthread_mutex_t *m = (pthread_mutex_t *) malloc(sizeof (pthread_mutex_t));
BAIL_IF_MACRO(m == NULL, ERR_OUT_OF_MEMORY, NULL);
rc = pthread_mutex_init(m, NULL);
if (rc != 0)
{
free(m);
BAIL_MACRO(strerror(rc), NULL);
} /* if */
return((void *) m);
} /* __PHYSFS_platformCreateMutex */
void __PHYSFS_platformDestroyMutex(void *mutex)
{
pthread_mutex_destroy((pthread_mutex_t *) mutex);
free(mutex);
} /* __PHYSFS_platformDestroyMutex */
int __PHYSFS_platformGrabMutex(void *mutex)
{
return(pthread_mutex_lock((pthread_mutex_t *) mutex) == 0);
} /* __PHYSFS_platformGrabMutex */
void __PHYSFS_platformReleaseMutex(void *mutex)
{
pthread_mutex_unlock((pthread_mutex_t *) mutex);
} /* __PHYSFS_platformReleaseMutex */
Jul 11, 2002
Jul 11, 2002
320
#endif /* !defined __BEOS__ && !defined WIN32 */
May 24, 2002
May 24, 2002
321
Jul 7, 2001
Jul 7, 2001
322
/* end of unix.c ... */