Skip to content

Latest commit

 

History

History
309 lines (235 loc) · 7.56 KB

unix.c

File metadata and controls

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