q_shlinux.c 4.0 KB

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