Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

q_shlinux.c (4121B)


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