stdlib.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #include <AK/AKString.h>
  2. #include <AK/Assertions.h>
  3. #include <AK/HashMap.h>
  4. #include <AK/StdLibExtras.h>
  5. #include <AK/Types.h>
  6. #include <Kernel/Syscall.h>
  7. #include <alloca.h>
  8. #include <assert.h>
  9. #include <ctype.h>
  10. #include <errno.h>
  11. #include <signal.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <sys/mman.h>
  16. #include <sys/wait.h>
  17. #include <unistd.h>
  18. extern "C" {
  19. typedef void(*__atexit_handler)();
  20. static int __atexit_handler_count = 0;
  21. static __atexit_handler __atexit_handlers[32];
  22. void exit(int status)
  23. {
  24. for (int i = 0; i < __atexit_handler_count; ++i)
  25. __atexit_handlers[i]();
  26. extern void _fini();
  27. _fini();
  28. fflush(stdout);
  29. fflush(stderr);
  30. _exit(status);
  31. ASSERT_NOT_REACHED();
  32. }
  33. int atexit(void (*handler)())
  34. {
  35. ASSERT(__atexit_handler_count < 32);
  36. __atexit_handlers[__atexit_handler_count++] = handler;
  37. return 0;
  38. }
  39. void abort()
  40. {
  41. raise(SIGABRT);
  42. }
  43. static HashTable<char*> s_malloced_environment_variables;
  44. static void free_environment_variable_if_needed(const char* var)
  45. {
  46. if (!s_malloced_environment_variables.contains((char*)var))
  47. return;
  48. free((void*)var);
  49. s_malloced_environment_variables.remove((char*)var);
  50. }
  51. char* getenv(const char* name)
  52. {
  53. size_t vl = strlen(name);
  54. for (size_t i = 0; environ[i]; ++i) {
  55. const char* decl = environ[i];
  56. char* eq = strchr(decl, '=');
  57. if (!eq)
  58. continue;
  59. size_t varLength = eq - decl;
  60. if (vl != varLength)
  61. continue;
  62. if (strncmp(decl, name, varLength) == 0) {
  63. return eq + 1;
  64. }
  65. }
  66. return nullptr;
  67. }
  68. int unsetenv(const char* name)
  69. {
  70. auto new_var_len = strlen(name);
  71. size_t environ_size = 0;
  72. size_t skip = -1;
  73. for (; environ[environ_size]; ++environ_size) {
  74. char* old_var = environ[environ_size];
  75. char* old_eq = strchr(old_var, '=');
  76. ASSERT(old_eq);
  77. auto old_var_len = old_eq - old_var;
  78. if (new_var_len != old_var_len)
  79. continue; // can't match
  80. if (strncmp(name, old_var, new_var_len) == 0)
  81. skip = environ_size;
  82. }
  83. if (skip == -1)
  84. return 0; // not found: no failure.
  85. // Shuffle the existing array down by one.
  86. memmove(&environ[skip], &environ[skip+1], ((environ_size-1)-skip) * sizeof(environ[0]));
  87. environ[environ_size-1] = nullptr;
  88. free_environment_variable_if_needed(name);
  89. return 0;
  90. }
  91. int setenv(const char* name, const char* value, int overwrite)
  92. {
  93. if (!overwrite && !getenv(name))
  94. return 0;
  95. auto length = strlen(name) + strlen(value) + 2;
  96. auto* var = (char*)malloc(length);
  97. snprintf(var, length, "%s=%s", name, value);
  98. s_malloced_environment_variables.set(var);
  99. return putenv(var);
  100. }
  101. int putenv(char* new_var)
  102. {
  103. char* new_eq = strchr(new_var, '=');
  104. if (!new_eq)
  105. return unsetenv(new_var);
  106. auto new_var_len = new_eq - new_var;
  107. size_t environ_size = 0;
  108. for (; environ[environ_size]; ++environ_size) {
  109. char* old_var = environ[environ_size];
  110. char* old_eq = strchr(old_var, '=');
  111. ASSERT(old_eq);
  112. auto old_var_len = old_eq - old_var;
  113. if (new_var_len != old_var_len)
  114. continue; // can't match
  115. if (strncmp(new_var, old_var, new_var_len) == 0) {
  116. free_environment_variable_if_needed(old_var);
  117. environ[environ_size] = new_var;
  118. return 0;
  119. }
  120. }
  121. // At this point, we need to append the new var.
  122. // 2 here: one for the new var, one for the sentinel value.
  123. char **new_environ = (char**)malloc((environ_size + 2) * sizeof(char*));
  124. if (new_environ == nullptr) {
  125. errno = ENOMEM;
  126. return -1;
  127. }
  128. for (size_t i = 0; environ[i]; ++i) {
  129. new_environ[i] = environ[i];
  130. }
  131. new_environ[environ_size] = new_var;
  132. new_environ[environ_size + 1] = nullptr;
  133. // swap new and old
  134. // note that the initial environ is not heap allocated!
  135. extern bool __environ_is_malloced;
  136. if (__environ_is_malloced)
  137. free(environ);
  138. __environ_is_malloced = true;
  139. environ = new_environ;
  140. return 0;
  141. }
  142. double strtod(const char* str, char** endptr)
  143. {
  144. (void)str;
  145. (void)endptr;
  146. dbgprintf("LibC: strtod: '%s'\n", str);
  147. ASSERT_NOT_REACHED();
  148. }
  149. float strtof(const char* str, char** endptr)
  150. {
  151. (void)str;
  152. (void)endptr;
  153. dbgprintf("LibC: strtof: '%s'\n", str);
  154. ASSERT_NOT_REACHED();
  155. }
  156. double atof(const char* str)
  157. {
  158. dbgprintf("LibC: atof: '%s'\n", str);
  159. ASSERT_NOT_REACHED();
  160. }
  161. int atoi(const char* str)
  162. {
  163. size_t len = strlen(str);
  164. int value = 0;
  165. bool isNegative = false;
  166. for (size_t i = 0; i < len; ++i) {
  167. if (i == 0 && str[0] == '-') {
  168. isNegative = true;
  169. continue;
  170. }
  171. if (str[i] < '0' || str[i] > '9')
  172. return value;
  173. value = value * 10;
  174. value += str[i] - '0';
  175. }
  176. return isNegative ? -value : value;
  177. }
  178. long atol(const char* str)
  179. {
  180. static_assert(sizeof(int) == sizeof(long));
  181. return atoi(str);
  182. }
  183. long long atoll(const char* str)
  184. {
  185. dbgprintf("FIXME(Libc): atoll('%s') passing through to atol()\n", str);
  186. return atol(str);
  187. }
  188. static char ptsname_buf[32];
  189. char* ptsname(int fd)
  190. {
  191. if (ptsname_r(fd, ptsname_buf, sizeof(ptsname_buf)) < 0)
  192. return nullptr;
  193. return ptsname_buf;
  194. }
  195. int ptsname_r(int fd, char* buffer, size_t size)
  196. {
  197. int rc = syscall(SC_ptsname_r, fd, buffer, size);
  198. __RETURN_WITH_ERRNO(rc, rc, -1);
  199. }
  200. static unsigned long s_next_rand = 1;
  201. int rand()
  202. {
  203. s_next_rand = s_next_rand * 1103515245 + 12345;
  204. return((unsigned)(s_next_rand/((RAND_MAX + 1) * 2)) % (RAND_MAX + 1));
  205. }
  206. void srand(unsigned seed)
  207. {
  208. s_next_rand = seed;
  209. }
  210. int abs(int i)
  211. {
  212. return i < 0 ? -i : i;
  213. }
  214. long int random()
  215. {
  216. return rand();
  217. }
  218. void srandom(unsigned seed)
  219. {
  220. srand(seed);
  221. }
  222. int system(const char* command)
  223. {
  224. auto child = fork();
  225. if (!child) {
  226. int rc = execl("/bin/sh", "sh", "-c", command, nullptr);
  227. if (rc < 0)
  228. perror("execl");
  229. exit(0);
  230. }
  231. int wstatus;
  232. waitpid(child, &wstatus, 0);
  233. return WEXITSTATUS(wstatus);
  234. }
  235. char* mktemp(char* pattern)
  236. {
  237. int length = strlen(pattern);
  238. // FIXME: Check for an invalid template pattern and return EINVAL.
  239. if (length < 6) {
  240. pattern[0] = '\0';
  241. errno = EINVAL;
  242. return pattern;
  243. }
  244. int start = length - 6;
  245. static constexpr char random_characters[] = "abcdefghijklmnopqrstuvwxyz0123456789";
  246. for (int attempt = 0; attempt < 100; ++attempt) {
  247. for (int i = 0; i < 6; ++i)
  248. pattern[start + i] = random_characters[(rand() % sizeof(random_characters))];
  249. struct stat st;
  250. int rc = lstat(pattern, &st);
  251. if (rc < 0 && errno == ENOENT)
  252. return pattern;
  253. }
  254. pattern[0] = '\0';
  255. errno = EEXIST;
  256. return pattern;
  257. }
  258. void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
  259. {
  260. dbgprintf("FIXME(LibC): bsearch(%p, %p, %u, %u, %p)\n", key, base, nmemb, size, compar);
  261. ASSERT_NOT_REACHED();
  262. }
  263. div_t div(int numerator, int denominator)
  264. {
  265. div_t result;
  266. result.quot = numerator / denominator;
  267. result.rem = numerator % denominator;
  268. return result;
  269. }
  270. ldiv_t ldiv(long numerator, long denominator)
  271. {
  272. ldiv_t result;
  273. result.quot = numerator / denominator;
  274. result.rem = numerator % denominator;
  275. return result;
  276. }
  277. size_t mbstowcs(wchar_t*, const char*, size_t)
  278. {
  279. ASSERT_NOT_REACHED();
  280. }
  281. long strtol(const char* str, char** endptr, int base)
  282. {
  283. const char* s = str;
  284. unsigned long acc;
  285. int c;
  286. unsigned long cutoff;
  287. int neg = 0;
  288. int any;
  289. int cutlim;
  290. do {
  291. c = *s++;
  292. } while (isspace(c));
  293. if (c == '-') {
  294. neg = 1;
  295. c = *s++;
  296. } else if (c == '+')
  297. c = *s++;
  298. if ((base == 0 || base == 16) &&
  299. c == '0' && (*s == 'x' || *s == 'X')) {
  300. c = s[1];
  301. s += 2;
  302. base = 16;
  303. }
  304. if (base == 0)
  305. base = c == '0' ? 8 : 10;
  306. cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
  307. cutlim = cutoff % (unsigned long)base;
  308. cutoff /= (unsigned long)base;
  309. for (acc = 0, any = 0;; c = *s++) {
  310. if (isdigit(c))
  311. c -= '0';
  312. else if (isalpha(c))
  313. c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  314. else
  315. break;
  316. if (c >= base)
  317. break;
  318. if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
  319. any = -1;
  320. else {
  321. any = 1;
  322. acc *= base;
  323. acc += c;
  324. }
  325. }
  326. if (any < 0) {
  327. acc = neg ? LONG_MIN : LONG_MAX;
  328. errno = ERANGE;
  329. } else if (neg)
  330. acc = -acc;
  331. if (endptr)
  332. *endptr = const_cast<char*>((any ? s - 1 : str));
  333. return acc;
  334. }
  335. unsigned long strtoul(const char* str, char** endptr, int base)
  336. {
  337. auto value = strtol(str, endptr, base);
  338. ASSERT(value >= 0);
  339. return value;
  340. }
  341. }