stdlib.cpp 9.6 KB

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