Skip to content

Latest commit

 

History

History
310 lines (235 loc) · 7.5 KB

unix.c

File metadata and controls

310 lines (235 loc) · 7.5 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
May 24, 2002
May 24, 2002
13
14
#if (!defined __BEOS__) /* BeOS uses beos.cpp and posix.c ... */
Mar 5, 2002
Mar 5, 2002
15
16
17
18
19
20
#if ((defined __APPLE__) && (defined __MACH__))
# if (!defined __DARWIN__)
# define __DARWIN__
# endif
#endif
Jul 7, 2001
Jul 7, 2001
21
22
#include <stdio.h>
#include <stdlib.h>
Jul 8, 2001
Jul 8, 2001
23
24
#include <string.h>
#include <ctype.h>
Jul 7, 2001
Jul 7, 2001
25
#include <pthread.h>
Jul 8, 2001
Jul 8, 2001
26
27
28
29
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <sys/stat.h>
Jul 16, 2001
Jul 16, 2001
30
#include <sys/param.h>
Jul 8, 2001
Jul 8, 2001
31
32
33
#include <dirent.h>
#include <time.h>
#include <errno.h>
Mar 5, 2002
Mar 5, 2002
34
Apr 6, 2002
Apr 6, 2002
35
36
37
#if (!defined __DARWIN__)
#include <mntent.h>
#else
Mar 5, 2002
Mar 5, 2002
38
39
#include <sys/ucred.h>
#endif
Jul 7, 2001
Jul 7, 2001
40
Apr 6, 2002
Apr 6, 2002
41
42
43
#include <sys/mount.h>
Jul 7, 2001
Jul 7, 2001
44
45
46
47
48
49
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
const char *__PHYSFS_platformDirSeparator = "/";
Mar 5, 2002
Mar 5, 2002
50
Mar 24, 2002
Mar 24, 2002
51
52
53
54
55
56
57
58
59
60
61
62
63
int __PHYSFS_platformInit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformInit */
int __PHYSFS_platformDeinit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformDeinit */
Mar 5, 2002
Mar 5, 2002
64
65
66
67
68
69
70
71
72
73
#if (defined __DARWIN__)
char **__PHYSFS_platformDetectAvailableCDs(void)
{
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
struct statfs* mntbufp = NULL;
int mounts;
int ii;
Apr 5, 2002
Apr 5, 2002
74
75
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
Mar 5, 2002
Mar 5, 2002
76
77
78
79
80
81
82
mounts = getmntinfo( &mntbufp, MNT_WAIT );
for ( ii=0; ii < mounts; ++ii ) {
int add_it = 0;
if ( strcmp( mntbufp[ii].f_fstypename, "iso9660") == 0 )
add_it = 1;
Apr 6, 2002
Apr 6, 2002
83
84
else if ( strcmp( mntbufp[ii].f_fstypename, "cd9660") == 0 )
add_it = 1;
May 21, 2002
May 21, 2002
85
86
/* add other mount types here */
Mar 5, 2002
Mar 5, 2002
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
if (add_it)
{
char **tmp = realloc(retval, sizeof (char *) * cd_count + 1);
if (tmp)
{
retval = tmp;
retval[cd_count-1] = (char *)
malloc(strlen(mntbufp[ ii ].f_mntonname) + 1);
if (retval[cd_count-1])
{
strcpy(retval[cd_count-1], mntbufp[ ii ].f_mntonname);
cd_count++;
} /* if */
} /* if */
} /* if */
}
free( mntbufp );
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#else /* non-Darwin implementation... */
Jul 7, 2001
Jul 7, 2001
115
116
char **__PHYSFS_platformDetectAvailableCDs(void)
{
Aug 7, 2001
Aug 7, 2001
117
118
119
120
121
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
122
123
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
Aug 7, 2001
Aug 7, 2001
124
125
126
127
128
129
130
131
132
*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
133
134
/* add other mount types here */
Aug 7, 2001
Aug 7, 2001
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
if (add_it)
{
char **tmp = realloc(retval, sizeof (char *) * cd_count + 1);
if (tmp)
{
retval = tmp;
retval[cd_count-1] = (char *) malloc(strlen(ent->mnt_dir) + 1);
if (retval[cd_count-1])
{
strcpy(retval[cd_count-1], ent->mnt_dir);
cd_count++;
} /* if */
} /* if */
} /* if */
} /* while */
endmntent(mounts);
Jul 8, 2001
Jul 8, 2001
153
Aug 7, 2001
Aug 7, 2001
154
retval[cd_count - 1] = NULL;
Jul 8, 2001
Jul 8, 2001
155
return(retval);
Mar 5, 2002
Mar 5, 2002
156
157
158
} /* __PHYSFS_platformDetectAvailableCDs */
#endif
Jul 7, 2001
Jul 7, 2001
159
160
May 24, 2002
May 24, 2002
161
162
/* this is in posix.c ... */
extern char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname);
Jul 8, 2001
Jul 8, 2001
163
164
May 21, 2002
May 21, 2002
165
166
167
168
169
170
171
172
173
174
/*
* 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
175
{
May 21, 2002
May 21, 2002
176
177
178
size_t alloc_size = 0;
char *exe = NULL;
char *start = envr;
Jul 8, 2001
Jul 8, 2001
179
180
char *ptr;
May 21, 2002
May 21, 2002
181
182
BAIL_IF_MACRO(bin == NULL, ERR_INVALID_ARGUMENT, NULL);
BAIL_IF_MACRO(envr == NULL, ERR_INVALID_ARGUMENT, NULL);
Jul 8, 2001
Jul 8, 2001
183
184
185
do
{
May 21, 2002
May 21, 2002
186
187
size_t size;
ptr = strchr(start, ':'); /* find next $PATH separator. */
Jul 8, 2001
Jul 8, 2001
188
189
190
if (ptr)
*ptr = '\0';
May 21, 2002
May 21, 2002
191
192
size = strlen(start) + strlen(bin) + 2;
if (size > alloc_size)
Jul 8, 2001
Jul 8, 2001
193
{
May 21, 2002
May 21, 2002
194
195
196
197
198
199
200
201
202
203
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
204
} /* if */
May 21, 2002
May 21, 2002
205
206
/* build full binary path... */
Jul 8, 2001
Jul 8, 2001
207
strcpy(exe, start);
Aug 29, 2001
Aug 29, 2001
208
209
if (exe[strlen(exe) - 1] != '/')
strcat(exe, "/");
May 21, 2002
May 21, 2002
210
211
212
strcat(exe, bin);
if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */
Jul 8, 2001
Jul 8, 2001
213
{
May 21, 2002
May 21, 2002
214
215
216
strcpy(exe, start); /* i'm lazy. piss off. */
return(exe);
} /* if */
Jul 8, 2001
Jul 8, 2001
217
May 21, 2002
May 21, 2002
218
start = ptr + 1; /* start points to beginning of next element. */
Jul 8, 2001
Jul 8, 2001
219
220
} while (ptr != NULL);
May 21, 2002
May 21, 2002
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
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
238
envr = __PHYSFS_platformCopyEnvironmentVariable("PATH");
May 21, 2002
May 21, 2002
239
240
BAIL_IF_MACRO(!envr, NULL, NULL);
retval = findBinaryInPath(argv0, envr);
Jul 8, 2001
Jul 8, 2001
241
242
243
244
245
free(envr);
return(retval);
} /* __PHYSFS_platformCalcBaseDir */
Mar 24, 2002
Mar 24, 2002
246
PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
Jul 7, 2001
Jul 7, 2001
247
{
Apr 6, 2002
Apr 6, 2002
248
return((PHYSFS_uint64) ((PHYSFS_uint32) pthread_self()));
Jul 7, 2001
Jul 7, 2001
249
250
251
} /* __PHYSFS_platformGetThreadID */
Jul 8, 2001
Jul 8, 2001
252
253
254
/* Much like my college days, try to sleep for 10 milliseconds at a time... */
void __PHYSFS_platformTimeslice(void)
{
Mar 5, 2002
Mar 5, 2002
255
usleep( 10 * 1000 ); /* don't care if it fails. */
Jul 8, 2001
Jul 8, 2001
256
257
258
} /* __PHYSFS_platformTimeslice */
Jul 16, 2001
Jul 16, 2001
259
260
261
262
263
264
265
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
266
retval = (char *) malloc(strlen(resolved_path) + 1);
Jul 16, 2001
Jul 16, 2001
267
268
269
270
271
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
strcpy(retval, resolved_path);
return(retval);
} /* __PHYSFS_platformRealPath */
Aug 23, 2001
Aug 23, 2001
272
Mar 30, 2002
Mar 30, 2002
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
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 */
May 24, 2002
May 24, 2002
307
308
#endif /* !defined __BEOS__ */
Jul 7, 2001
Jul 7, 2001
309
/* end of unix.c ... */