1 #ifndef _GNU_SOURCE
2 #define _GNU_SOURCE
3 #endif
4
5 #include <sys/types.h>
6 #include <errno.h>
7 #include <stdio.h>
8 #include <dirent.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <sys/mman.h>
12 #include <sys/time.h>
13 #include <ctype.h>
14
15 #include "../linux/glob.h"
16
17 #include "../qcommon/qcommon.h"
18
19 #ifndef __linux__
20 #include <machine/param.h>
21 #endif
22
23 //===============================================================================
24
25 byte *membase;
26 int maxhunksize;
27 int curhunksize;
28
29 #ifdef __FreeBSD__
30 #define MMAP_ANON MAP_ANON
31 #else
32 #define MMAP_ANON MAP_ANONYMOUS
33 #endif
34
Hunk_Begin(int maxsize,int precommit)35 void *Hunk_Begin (int maxsize, int precommit)
36 {
37 // reserve a huge chunk of memory, but don't commit any yet
38 maxhunksize = maxsize + sizeof(int);
39 curhunksize = 0;
40 membase = mmap(0, maxhunksize, PROT_READ|PROT_WRITE,
41 MAP_PRIVATE|MMAP_ANON, -1, 0);
42 if (membase == NULL || membase == (byte *)-1)
43 Sys_Error("unable to virtual allocate %d bytes", maxsize);
44
45 *((int *)membase) = curhunksize;
46
47 return membase + sizeof(int);
48 }
49
Hunk_Alloc(int size)50 void *Hunk_Alloc (int size)
51 {
52 byte *buf;
53
54 // round to cacheline
55 size = (size+31)&~31;
56 if (curhunksize + size > maxhunksize)
57 Sys_Error("Hunk_Alloc overflow");
58 buf = membase + sizeof(int) + curhunksize;
59 curhunksize += size;
60 return buf;
61 }
62
Hunk_End(void)63 int Hunk_End (void)
64 {
65 byte *n;
66
67 #ifndef __linux__
68 size_t old_size = maxhunksize;
69 size_t new_size = curhunksize + sizeof(int);
70 void * unmap_base;
71 size_t unmap_len;
72
73 new_size = round_page(new_size);
74 old_size = round_page(old_size);
75 if (new_size > old_size)
76 n = 0; /* error */
77 else if (new_size < old_size) {
78 unmap_base = (caddr_t)(membase + new_size);
79 unmap_len = old_size - new_size;
80 n = munmap(unmap_base, unmap_len) + membase;
81 }
82 #else
83 n = mremap(membase, maxhunksize, curhunksize + sizeof(int), 0);
84 #endif
85 if (n != membase)
86 Sys_Error("Hunk_End: Could not remap virtual block (%d)", errno);
87 *((int *)membase) = curhunksize + sizeof(int);
88
89 return curhunksize;
90 }
91
Hunk_Free(void * base)92 void Hunk_Free (void *base)
93 {
94 byte *m;
95
96 if (base) {
97 m = ((byte *)base) - sizeof(int);
98 if (munmap(m, *((int *)m)))
99 Sys_Error("Hunk_Free: munmap failed (%d)", errno);
100 }
101 }
102
103 //===============================================================================
104
105
106 /*
107 ================
108 Sys_Milliseconds
109 ================
110 */
111 unsigned int curtime;
Sys_Milliseconds(void)112 unsigned int Sys_Milliseconds (void)
113 {
114 struct timeval tp;
115 struct timezone tzp;
116 static unsigned int secbase;
117
118 gettimeofday(&tp, &tzp);
119
120 if (!secbase)
121 {
122 secbase = tp.tv_sec;
123 return tp.tv_usec/1000;
124 }
125
126 curtime = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
127
128 return curtime;
129 }
130
Sys_DebugBreak(void)131 void Sys_DebugBreak (void)
132 {
133 #ifdef __i386__
134 __asm ("int $3");
135 #endif
136 }
137
Sys_Mkdir(char * path)138 void Sys_Mkdir (char *path)
139 {
140 mkdir (path, 0755);
141 }
142
strlwr(char * s)143 void strlwr (char *s)
144 {
145 while (*s) {
146 *s = tolower(*s);
147 s++;
148 }
149 }
150
151 //============================================
152
153 static char findbase[MAX_OSPATH];
154 static char findpath[MAX_OSPATH];
155 static char findpattern[MAX_OSPATH];
156 static DIR *fdir;
157
CompareAttributes(char * path,char * name,unsigned musthave,unsigned canthave)158 static qboolean CompareAttributes(char *path, char *name,
159 unsigned musthave, unsigned canthave )
160 {
161 struct stat st;
162 char fn[MAX_OSPATH];
163
164 // . and .. never match
165 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
166 return false;
167
168 sprintf(fn, "%s/%s", path, name);
169 if (stat(fn, &st) == -1)
170 return false; // shouldn't happen
171
172 if ( ( st.st_mode & S_IFDIR ) && ( canthave & SFF_SUBDIR ) )
173 return false;
174
175 if ( ( musthave & SFF_SUBDIR ) && !( st.st_mode & S_IFDIR ) )
176 return false;
177
178 return true;
179 }
180
Sys_FindFirst(char * path,unsigned musthave,unsigned canhave)181 char *Sys_FindFirst (char *path, unsigned musthave, unsigned canhave)
182 {
183 struct dirent *d;
184 char *p;
185
186 if (fdir)
187 Sys_Error ("Sys_BeginFind without close");
188
189 // COM_FilePath (path, findbase);
190 strcpy(findbase, path);
191
192 if ((p = strrchr(findbase, '/')) != NULL) {
193 *p = 0;
194 strcpy(findpattern, p + 1);
195 } else
196 strcpy(findpattern, "*");
197
198 if (strcmp(findpattern, "*.*") == 0)
199 strcpy(findpattern, "*");
200
201 if ((fdir = opendir(findbase)) == NULL)
202 return NULL;
203 while ((d = readdir(fdir)) != NULL) {
204 if (!*findpattern || glob_match(findpattern, d->d_name)) {
205 // if (*findpattern)
206 // printf("%s matched %s\n", findpattern, d->d_name);
207 if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
208 sprintf (findpath, "%s/%s", findbase, d->d_name);
209 return findpath;
210 }
211 }
212 }
213 return NULL;
214 }
215
Sys_FindNext(unsigned musthave,unsigned canhave)216 char *Sys_FindNext (unsigned musthave, unsigned canhave)
217 {
218 struct dirent *d;
219
220 if (fdir == NULL)
221 return NULL;
222 while ((d = readdir(fdir)) != NULL) {
223 if (!*findpattern || glob_match(findpattern, d->d_name)) {
224 // if (*findpattern)
225 // printf("%s matched %s\n", findpattern, d->d_name);
226 if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
227 sprintf (findpath, "%s/%s", findbase, d->d_name);
228 return findpath;
229 }
230 }
231 }
232 return NULL;
233 }
234
Sys_FindClose(void)235 void Sys_FindClose (void)
236 {
237 if (fdir != NULL)
238 closedir(fdir);
239 fdir = NULL;
240 }
241
242
243 //============================================
244
245