Skip to content

Latest commit

 

History

History
308 lines (234 loc) · 7.48 KB

unix.c

File metadata and controls

308 lines (234 loc) · 7.48 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
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 */
}
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#else /* non-Darwin implementation... */
Jul 7, 2001
Jul 7, 2001
113
114
char **__PHYSFS_platformDetectAvailableCDs(void)
{
Aug 7, 2001
Aug 7, 2001
115
116
117
118
119
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
120
121
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
Aug 7, 2001
Aug 7, 2001
122
123
124
125
126
127
128
129
130
*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
131
132
/* add other mount types here */
Aug 7, 2001
Aug 7, 2001
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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
151
Aug 7, 2001
Aug 7, 2001
152
retval[cd_count - 1] = NULL;
Jul 8, 2001
Jul 8, 2001
153
return(retval);
Mar 5, 2002
Mar 5, 2002
154
155
156
} /* __PHYSFS_platformDetectAvailableCDs */
#endif
Jul 7, 2001
Jul 7, 2001
157
158
May 24, 2002
May 24, 2002
159
160
/* this is in posix.c ... */
extern char *__PHYSFS_platformCopyEnvironmentVariable(const char *varname);
Jul 8, 2001
Jul 8, 2001
161
162
May 21, 2002
May 21, 2002
163
164
165
166
167
168
169
170
171
172
/*
* 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
173
{
May 21, 2002
May 21, 2002
174
175
176
size_t alloc_size = 0;
char *exe = NULL;
char *start = envr;
Jul 8, 2001
Jul 8, 2001
177
178
char *ptr;
May 21, 2002
May 21, 2002
179
180
BAIL_IF_MACRO(bin == NULL, ERR_INVALID_ARGUMENT, NULL);
BAIL_IF_MACRO(envr == NULL, ERR_INVALID_ARGUMENT, NULL);
Jul 8, 2001
Jul 8, 2001
181
182
183
do
{
May 21, 2002
May 21, 2002
184
185
size_t size;
ptr = strchr(start, ':'); /* find next $PATH separator. */
Jul 8, 2001
Jul 8, 2001
186
187
188
if (ptr)
*ptr = '\0';
May 21, 2002
May 21, 2002
189
190
size = strlen(start) + strlen(bin) + 2;
if (size > alloc_size)
Jul 8, 2001
Jul 8, 2001
191
{
May 21, 2002
May 21, 2002
192
193
194
195
196
197
198
199
200
201
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
202
} /* if */
May 21, 2002
May 21, 2002
203
204
/* build full binary path... */
Jul 8, 2001
Jul 8, 2001
205
strcpy(exe, start);
Aug 29, 2001
Aug 29, 2001
206
207
if (exe[strlen(exe) - 1] != '/')
strcat(exe, "/");
May 21, 2002
May 21, 2002
208
209
210
strcat(exe, bin);
if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */
Jul 8, 2001
Jul 8, 2001
211
{
May 21, 2002
May 21, 2002
212
213
214
strcpy(exe, start); /* i'm lazy. piss off. */
return(exe);
} /* if */
Jul 8, 2001
Jul 8, 2001
215
May 21, 2002
May 21, 2002
216
start = ptr + 1; /* start points to beginning of next element. */
Jul 8, 2001
Jul 8, 2001
217
218
} while (ptr != NULL);
May 21, 2002
May 21, 2002
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
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
236
envr = __PHYSFS_platformCopyEnvironmentVariable("PATH");
May 21, 2002
May 21, 2002
237
238
BAIL_IF_MACRO(!envr, NULL, NULL);
retval = findBinaryInPath(argv0, envr);
Jul 8, 2001
Jul 8, 2001
239
240
241
242
243
free(envr);
return(retval);
} /* __PHYSFS_platformCalcBaseDir */
Mar 24, 2002
Mar 24, 2002
244
PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
Jul 7, 2001
Jul 7, 2001
245
{
Apr 6, 2002
Apr 6, 2002
246
return((PHYSFS_uint64) ((PHYSFS_uint32) pthread_self()));
Jul 7, 2001
Jul 7, 2001
247
248
249
} /* __PHYSFS_platformGetThreadID */
Jul 8, 2001
Jul 8, 2001
250
251
252
/* Much like my college days, try to sleep for 10 milliseconds at a time... */
void __PHYSFS_platformTimeslice(void)
{
Mar 5, 2002
Mar 5, 2002
253
usleep( 10 * 1000 ); /* don't care if it fails. */
Jul 8, 2001
Jul 8, 2001
254
255
256
} /* __PHYSFS_platformTimeslice */
Jul 16, 2001
Jul 16, 2001
257
258
259
260
261
262
263
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
264
retval = (char *) malloc(strlen(resolved_path) + 1);
Jul 16, 2001
Jul 16, 2001
265
266
267
268
269
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
strcpy(retval, resolved_path);
return(retval);
} /* __PHYSFS_platformRealPath */
Aug 23, 2001
Aug 23, 2001
270
Mar 30, 2002
Mar 30, 2002
271
272
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
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
305
306
#endif /* !defined __BEOS__ */
Jul 7, 2001
Jul 7, 2001
307
/* end of unix.c ... */