stdio.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/Format.h>
  8. #include <AK/PrintfImplementation.h>
  9. #include <AK/ScopedValueRollback.h>
  10. #include <AK/StdLibExtras.h>
  11. #include <AK/String.h>
  12. #include <LibC/bits/pthread_integration.h>
  13. #include <assert.h>
  14. #include <errno.h>
  15. #include <fcntl.h>
  16. #include <stdarg.h>
  17. #include <stdio.h>
  18. #include <stdio_ext.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/internals.h>
  22. #include <sys/types.h>
  23. #include <sys/wait.h>
  24. #include <syscall.h>
  25. #include <unistd.h>
  26. struct FILE {
  27. public:
  28. FILE(int fd, int mode)
  29. : m_fd(fd)
  30. , m_mode(mode)
  31. {
  32. __pthread_mutex_init(&m_mutex, nullptr);
  33. }
  34. ~FILE();
  35. static FILE* create(int fd, int mode);
  36. void setbuf(u8* data, int mode, size_t size) { m_buffer.setbuf(data, mode, size); }
  37. bool flush();
  38. bool close();
  39. int fileno() const { return m_fd; }
  40. bool eof() const { return m_eof; }
  41. int mode() const { return m_mode; }
  42. u8 flags() const { return m_flags; }
  43. int error() const { return m_error; }
  44. void clear_err() { m_error = 0; }
  45. size_t read(u8*, size_t);
  46. size_t write(const u8*, size_t);
  47. bool gets(u8*, size_t);
  48. bool ungetc(u8 byte) { return m_buffer.enqueue_front(byte); }
  49. int seek(off_t offset, int whence);
  50. off_t tell();
  51. pid_t popen_child() { return m_popen_child; }
  52. void set_popen_child(pid_t child_pid) { m_popen_child = child_pid; }
  53. void reopen(int fd, int mode);
  54. enum Flags : u8 {
  55. None = 0,
  56. LastRead = 1,
  57. LastWrite = 2,
  58. };
  59. private:
  60. struct Buffer {
  61. // A ringbuffer that also transparently implements ungetc().
  62. public:
  63. ~Buffer();
  64. int mode() const { return m_mode; }
  65. void setbuf(u8* data, int mode, size_t size);
  66. // Make sure to call realize() before enqueuing any data.
  67. // Dequeuing can be attempted without it.
  68. void realize(int fd);
  69. void drop();
  70. bool may_use() const { return m_ungotten || m_mode != _IONBF; }
  71. bool is_not_empty() const { return m_ungotten || !m_empty; }
  72. size_t buffered_size() const;
  73. const u8* begin_dequeue(size_t& available_size) const;
  74. void did_dequeue(size_t actual_size);
  75. u8* begin_enqueue(size_t& available_size) const;
  76. void did_enqueue(size_t actual_size);
  77. bool enqueue_front(u8 byte);
  78. private:
  79. // Note: the fields here are arranged this way
  80. // to make sizeof(Buffer) smaller.
  81. u8* m_data { nullptr };
  82. size_t m_capacity { BUFSIZ };
  83. size_t m_begin { 0 };
  84. size_t m_end { 0 };
  85. int m_mode { -1 };
  86. u8 m_unget_buffer { 0 };
  87. bool m_ungotten : 1 { false };
  88. bool m_data_is_malloced : 1 { false };
  89. // When m_begin == m_end, we want to distinguish whether
  90. // the buffer is full or empty.
  91. bool m_empty : 1 { true };
  92. };
  93. // Read or write using the underlying fd, bypassing the buffer.
  94. ssize_t do_read(u8*, size_t);
  95. ssize_t do_write(const u8*, size_t);
  96. // Read some data into the buffer.
  97. bool read_into_buffer();
  98. // Flush *some* data from the buffer.
  99. bool write_from_buffer();
  100. void lock();
  101. void unlock();
  102. int m_fd { -1 };
  103. int m_mode { 0 };
  104. u8 m_flags { Flags::None };
  105. int m_error { 0 };
  106. bool m_eof { false };
  107. pid_t m_popen_child { -1 };
  108. Buffer m_buffer;
  109. __pthread_mutex_t m_mutex;
  110. friend class ScopedFileLock;
  111. };
  112. FILE::~FILE()
  113. {
  114. bool already_closed = m_fd == -1;
  115. VERIFY(already_closed);
  116. }
  117. FILE* FILE::create(int fd, int mode)
  118. {
  119. void* file = calloc(1, sizeof(FILE));
  120. new (file) FILE(fd, mode);
  121. return (FILE*)file;
  122. }
  123. bool FILE::close()
  124. {
  125. bool flush_ok = flush();
  126. int rc = ::close(m_fd);
  127. m_fd = -1;
  128. if (!flush_ok) {
  129. // Restore the original error from flush().
  130. errno = m_error;
  131. }
  132. return flush_ok && rc == 0;
  133. }
  134. bool FILE::flush()
  135. {
  136. if (m_mode & O_WRONLY && m_buffer.may_use()) {
  137. // When open for writing, write out all the buffered data.
  138. while (m_buffer.is_not_empty()) {
  139. bool ok = write_from_buffer();
  140. if (!ok)
  141. return false;
  142. }
  143. }
  144. if (m_mode & O_RDONLY) {
  145. // When open for reading, just drop the buffered data.
  146. VERIFY(m_buffer.buffered_size() <= NumericLimits<off_t>::max());
  147. off_t had_buffered = m_buffer.buffered_size();
  148. m_buffer.drop();
  149. // Attempt to reset the underlying file position to what the user
  150. // expects.
  151. if (lseek(m_fd, -had_buffered, SEEK_CUR) < 0) {
  152. if (errno == ESPIPE) {
  153. // We can't set offset on this file; oh well, the user will just
  154. // have to cope.
  155. errno = 0;
  156. } else {
  157. return false;
  158. }
  159. }
  160. }
  161. return true;
  162. }
  163. ssize_t FILE::do_read(u8* data, size_t size)
  164. {
  165. int nread = ::read(m_fd, data, size);
  166. if (nread < 0) {
  167. m_error = errno;
  168. } else if (nread == 0) {
  169. m_eof = true;
  170. }
  171. return nread;
  172. }
  173. ssize_t FILE::do_write(const u8* data, size_t size)
  174. {
  175. int nwritten = ::write(m_fd, data, size);
  176. if (nwritten < 0)
  177. m_error = errno;
  178. return nwritten;
  179. }
  180. bool FILE::read_into_buffer()
  181. {
  182. m_buffer.realize(m_fd);
  183. size_t available_size;
  184. u8* data = m_buffer.begin_enqueue(available_size);
  185. // If we want to read, the buffer must have some space!
  186. VERIFY(available_size);
  187. ssize_t nread = do_read(data, available_size);
  188. if (nread <= 0)
  189. return false;
  190. m_buffer.did_enqueue(nread);
  191. return true;
  192. }
  193. bool FILE::write_from_buffer()
  194. {
  195. size_t size;
  196. const u8* data = m_buffer.begin_dequeue(size);
  197. // If we want to write, the buffer must have something in it!
  198. VERIFY(size);
  199. ssize_t nwritten = do_write(data, size);
  200. if (nwritten < 0)
  201. return false;
  202. m_buffer.did_dequeue(nwritten);
  203. return true;
  204. }
  205. size_t FILE::read(u8* data, size_t size)
  206. {
  207. size_t total_read = 0;
  208. m_flags |= Flags::LastRead;
  209. m_flags &= ~Flags::LastWrite;
  210. while (size > 0) {
  211. size_t actual_size;
  212. if (m_buffer.may_use()) {
  213. // Let's see if the buffer has something queued for us.
  214. size_t queued_size;
  215. const u8* queued_data = m_buffer.begin_dequeue(queued_size);
  216. if (queued_size == 0) {
  217. // Nothing buffered; we're going to have to read some.
  218. bool read_some_more = read_into_buffer();
  219. if (read_some_more) {
  220. // Great, now try this again.
  221. continue;
  222. }
  223. return total_read;
  224. }
  225. actual_size = min(size, queued_size);
  226. memcpy(data, queued_data, actual_size);
  227. m_buffer.did_dequeue(actual_size);
  228. } else {
  229. // Read directly into the user buffer.
  230. ssize_t nread = do_read(data, size);
  231. if (nread <= 0)
  232. return total_read;
  233. actual_size = nread;
  234. }
  235. total_read += actual_size;
  236. data += actual_size;
  237. size -= actual_size;
  238. }
  239. return total_read;
  240. }
  241. size_t FILE::write(const u8* data, size_t size)
  242. {
  243. size_t total_written = 0;
  244. m_flags &= ~Flags::LastRead;
  245. m_flags |= Flags::LastWrite;
  246. while (size > 0) {
  247. size_t actual_size;
  248. if (m_buffer.may_use()) {
  249. m_buffer.realize(m_fd);
  250. // Try writing into the buffer.
  251. size_t available_size;
  252. u8* buffer_data = m_buffer.begin_enqueue(available_size);
  253. if (available_size == 0) {
  254. // There's no space in the buffer; we're going to free some.
  255. bool freed_some_space = write_from_buffer();
  256. if (freed_some_space) {
  257. // Great, now try this again.
  258. continue;
  259. }
  260. return total_written;
  261. }
  262. actual_size = min(size, available_size);
  263. memcpy(buffer_data, data, actual_size);
  264. m_buffer.did_enqueue(actual_size);
  265. // See if we have to flush it.
  266. if (m_buffer.mode() == _IOLBF) {
  267. bool includes_newline = memchr(data, '\n', actual_size);
  268. if (includes_newline)
  269. flush();
  270. }
  271. } else {
  272. // Write directly from the user buffer.
  273. ssize_t nwritten = do_write(data, size);
  274. if (nwritten < 0)
  275. return total_written;
  276. actual_size = nwritten;
  277. }
  278. total_written += actual_size;
  279. data += actual_size;
  280. size -= actual_size;
  281. }
  282. return total_written;
  283. }
  284. bool FILE::gets(u8* data, size_t size)
  285. {
  286. // gets() is a lot like read(), but it is different enough in how it
  287. // processes newlines and null-terminates the buffer that it deserves a
  288. // separate implementation.
  289. size_t total_read = 0;
  290. if (size == 0)
  291. return false;
  292. m_flags |= Flags::LastRead;
  293. m_flags &= ~Flags::LastWrite;
  294. while (size > 1) {
  295. if (m_buffer.may_use()) {
  296. // Let's see if the buffer has something queued for us.
  297. size_t queued_size;
  298. const u8* queued_data = m_buffer.begin_dequeue(queued_size);
  299. if (queued_size == 0) {
  300. // Nothing buffered; we're going to have to read some.
  301. bool read_some_more = read_into_buffer();
  302. if (read_some_more) {
  303. // Great, now try this again.
  304. continue;
  305. }
  306. *data = 0;
  307. return total_read > 0;
  308. }
  309. size_t actual_size = min(size - 1, queued_size);
  310. u8* newline = reinterpret_cast<u8*>(memchr(queued_data, '\n', actual_size));
  311. if (newline)
  312. actual_size = newline - queued_data + 1;
  313. memcpy(data, queued_data, actual_size);
  314. m_buffer.did_dequeue(actual_size);
  315. total_read += actual_size;
  316. data += actual_size;
  317. size -= actual_size;
  318. if (newline)
  319. break;
  320. } else {
  321. // Sadly, we have to actually read these characters one by one.
  322. u8 byte;
  323. ssize_t nread = do_read(&byte, 1);
  324. if (nread <= 0) {
  325. *data = 0;
  326. return total_read > 0;
  327. }
  328. VERIFY(nread == 1);
  329. *data = byte;
  330. total_read++;
  331. data++;
  332. size--;
  333. if (byte == '\n')
  334. break;
  335. }
  336. }
  337. *data = 0;
  338. return total_read > 0;
  339. }
  340. int FILE::seek(off_t offset, int whence)
  341. {
  342. bool ok = flush();
  343. if (!ok)
  344. return -1;
  345. off_t off = lseek(m_fd, offset, whence);
  346. if (off < 0) {
  347. // Note: do not set m_error.
  348. return off;
  349. }
  350. m_eof = false;
  351. return 0;
  352. }
  353. off_t FILE::tell()
  354. {
  355. bool ok = flush();
  356. if (!ok)
  357. return -1;
  358. return lseek(m_fd, 0, SEEK_CUR);
  359. }
  360. void FILE::reopen(int fd, int mode)
  361. {
  362. // Dr. POSIX says: "Failure to flush or close the file descriptor
  363. // successfully shall be ignored"
  364. // and so we ignore any failures these two might have.
  365. flush();
  366. close();
  367. // Just in case flush() and close() didn't drop the buffer.
  368. m_buffer.drop();
  369. m_fd = fd;
  370. m_mode = mode;
  371. m_error = 0;
  372. m_eof = false;
  373. }
  374. FILE::Buffer::~Buffer()
  375. {
  376. if (m_data_is_malloced)
  377. free(m_data);
  378. }
  379. void FILE::Buffer::realize(int fd)
  380. {
  381. if (m_mode == -1)
  382. m_mode = isatty(fd) ? _IOLBF : _IOFBF;
  383. if (m_mode != _IONBF && m_data == nullptr) {
  384. m_data = reinterpret_cast<u8*>(malloc(m_capacity));
  385. m_data_is_malloced = true;
  386. }
  387. }
  388. void FILE::Buffer::setbuf(u8* data, int mode, size_t size)
  389. {
  390. drop();
  391. m_mode = mode;
  392. if (data != nullptr) {
  393. m_data = data;
  394. m_capacity = size;
  395. }
  396. }
  397. void FILE::Buffer::drop()
  398. {
  399. if (m_data_is_malloced) {
  400. free(m_data);
  401. m_data = nullptr;
  402. m_data_is_malloced = false;
  403. }
  404. m_begin = m_end = 0;
  405. m_empty = true;
  406. m_ungotten = false;
  407. }
  408. size_t FILE::Buffer::buffered_size() const
  409. {
  410. // Note: does not include the ungetc() buffer.
  411. if (m_empty)
  412. return 0;
  413. if (m_begin < m_end)
  414. return m_end - m_begin;
  415. else
  416. return m_capacity - (m_begin - m_end);
  417. }
  418. const u8* FILE::Buffer::begin_dequeue(size_t& available_size) const
  419. {
  420. if (m_ungotten) {
  421. available_size = 1;
  422. return &m_unget_buffer;
  423. }
  424. if (m_empty) {
  425. available_size = 0;
  426. return nullptr;
  427. }
  428. if (m_begin < m_end)
  429. available_size = m_end - m_begin;
  430. else
  431. available_size = m_capacity - m_begin;
  432. return &m_data[m_begin];
  433. }
  434. void FILE::Buffer::did_dequeue(size_t actual_size)
  435. {
  436. VERIFY(actual_size > 0);
  437. if (m_ungotten) {
  438. VERIFY(actual_size == 1);
  439. m_ungotten = false;
  440. return;
  441. }
  442. m_begin += actual_size;
  443. VERIFY(m_begin <= m_capacity);
  444. if (m_begin == m_capacity) {
  445. // Wrap around.
  446. m_begin = 0;
  447. }
  448. if (m_begin == m_end) {
  449. m_empty = true;
  450. // As an optimization, move both pointers to the beginning of the
  451. // buffer, so that more consecutive space is available next time.
  452. m_begin = m_end = 0;
  453. }
  454. }
  455. u8* FILE::Buffer::begin_enqueue(size_t& available_size) const
  456. {
  457. VERIFY(m_data != nullptr);
  458. if (m_begin < m_end || m_empty)
  459. available_size = m_capacity - m_end;
  460. else
  461. available_size = m_begin - m_end;
  462. return const_cast<u8*>(&m_data[m_end]);
  463. }
  464. void FILE::Buffer::did_enqueue(size_t actual_size)
  465. {
  466. VERIFY(m_data != nullptr);
  467. VERIFY(actual_size > 0);
  468. m_end += actual_size;
  469. VERIFY(m_end <= m_capacity);
  470. if (m_end == m_capacity) {
  471. // Wrap around.
  472. m_end = 0;
  473. }
  474. m_empty = false;
  475. }
  476. bool FILE::Buffer::enqueue_front(u8 byte)
  477. {
  478. if (m_ungotten) {
  479. // Sorry, the place is already taken!
  480. return false;
  481. }
  482. m_ungotten = true;
  483. m_unget_buffer = byte;
  484. return true;
  485. }
  486. void FILE::lock()
  487. {
  488. __pthread_mutex_lock(&m_mutex);
  489. }
  490. void FILE::unlock()
  491. {
  492. __pthread_mutex_unlock(&m_mutex);
  493. }
  494. class ScopedFileLock {
  495. public:
  496. ScopedFileLock(FILE* file)
  497. : m_file(file)
  498. {
  499. m_file->lock();
  500. }
  501. ~ScopedFileLock()
  502. {
  503. m_file->unlock();
  504. }
  505. private:
  506. FILE* m_file;
  507. };
  508. extern "C" {
  509. static u8 default_streams[3][sizeof(FILE)];
  510. FILE* stdin = reinterpret_cast<FILE*>(&default_streams[0]);
  511. FILE* stdout = reinterpret_cast<FILE*>(&default_streams[1]);
  512. FILE* stderr = reinterpret_cast<FILE*>(&default_streams[2]);
  513. void __stdio_init()
  514. {
  515. new (stdin) FILE(0, O_RDONLY);
  516. new (stdout) FILE(1, O_WRONLY);
  517. new (stderr) FILE(2, O_WRONLY);
  518. stderr->setbuf(nullptr, _IONBF, 0);
  519. __stdio_is_initialized = true;
  520. }
  521. int setvbuf(FILE* stream, char* buf, int mode, size_t size)
  522. {
  523. VERIFY(stream);
  524. ScopedFileLock lock(stream);
  525. if (mode != _IONBF && mode != _IOLBF && mode != _IOFBF) {
  526. errno = EINVAL;
  527. return -1;
  528. }
  529. stream->setbuf(reinterpret_cast<u8*>(buf), mode, size);
  530. return 0;
  531. }
  532. void setbuf(FILE* stream, char* buf)
  533. {
  534. setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
  535. }
  536. void setlinebuf(FILE* stream)
  537. {
  538. setvbuf(stream, nullptr, _IOLBF, 0);
  539. }
  540. int fileno(FILE* stream)
  541. {
  542. VERIFY(stream);
  543. ScopedFileLock lock(stream);
  544. return stream->fileno();
  545. }
  546. int feof(FILE* stream)
  547. {
  548. VERIFY(stream);
  549. ScopedFileLock lock(stream);
  550. return stream->eof();
  551. }
  552. int fflush(FILE* stream)
  553. {
  554. if (!stream) {
  555. dbgln("FIXME: fflush(nullptr) should flush all open streams");
  556. return 0;
  557. }
  558. ScopedFileLock lock(stream);
  559. return stream->flush() ? 0 : EOF;
  560. }
  561. char* fgets(char* buffer, int size, FILE* stream)
  562. {
  563. VERIFY(stream);
  564. ScopedFileLock lock(stream);
  565. bool ok = stream->gets(reinterpret_cast<u8*>(buffer), size);
  566. return ok ? buffer : nullptr;
  567. }
  568. int fgetc(FILE* stream)
  569. {
  570. VERIFY(stream);
  571. char ch;
  572. size_t nread = fread(&ch, sizeof(char), 1, stream);
  573. if (nread == 1)
  574. return ch;
  575. return EOF;
  576. }
  577. int fgetc_unlocked(FILE* stream)
  578. {
  579. VERIFY(stream);
  580. char ch;
  581. size_t nread = fread_unlocked(&ch, sizeof(char), 1, stream);
  582. if (nread == 1)
  583. return ch;
  584. return EOF;
  585. }
  586. int getc(FILE* stream)
  587. {
  588. return fgetc(stream);
  589. }
  590. int getc_unlocked(FILE* stream)
  591. {
  592. return fgetc_unlocked(stream);
  593. }
  594. int getchar()
  595. {
  596. return getc(stdin);
  597. }
  598. ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* stream)
  599. {
  600. if (!lineptr || !n) {
  601. errno = EINVAL;
  602. return -1;
  603. }
  604. if (*lineptr == nullptr || *n == 0) {
  605. *n = BUFSIZ;
  606. if ((*lineptr = static_cast<char*>(malloc(*n))) == nullptr) {
  607. return -1;
  608. }
  609. }
  610. char* ptr;
  611. char* eptr;
  612. for (ptr = *lineptr, eptr = *lineptr + *n;;) {
  613. int c = fgetc(stream);
  614. if (c == -1) {
  615. if (feof(stream)) {
  616. *ptr = '\0';
  617. return ptr == *lineptr ? -1 : ptr - *lineptr;
  618. } else {
  619. return -1;
  620. }
  621. }
  622. *ptr++ = c;
  623. if (c == delim) {
  624. *ptr = '\0';
  625. return ptr - *lineptr;
  626. }
  627. if (ptr + 2 >= eptr) {
  628. char* nbuf;
  629. size_t nbuf_sz = *n * 2;
  630. ssize_t d = ptr - *lineptr;
  631. if ((nbuf = static_cast<char*>(realloc(*lineptr, nbuf_sz))) == nullptr) {
  632. return -1;
  633. }
  634. *lineptr = nbuf;
  635. *n = nbuf_sz;
  636. eptr = nbuf + nbuf_sz;
  637. ptr = nbuf + d;
  638. }
  639. }
  640. }
  641. ssize_t getline(char** lineptr, size_t* n, FILE* stream)
  642. {
  643. return getdelim(lineptr, n, '\n', stream);
  644. }
  645. int ungetc(int c, FILE* stream)
  646. {
  647. VERIFY(stream);
  648. ScopedFileLock lock(stream);
  649. bool ok = stream->ungetc(c);
  650. return ok ? c : EOF;
  651. }
  652. int fputc(int ch, FILE* stream)
  653. {
  654. VERIFY(stream);
  655. u8 byte = ch;
  656. ScopedFileLock lock(stream);
  657. size_t nwritten = stream->write(&byte, 1);
  658. if (nwritten == 0)
  659. return EOF;
  660. VERIFY(nwritten == 1);
  661. return byte;
  662. }
  663. int putc(int ch, FILE* stream)
  664. {
  665. return fputc(ch, stream);
  666. }
  667. int putchar(int ch)
  668. {
  669. return putc(ch, stdout);
  670. }
  671. int fputs(const char* s, FILE* stream)
  672. {
  673. VERIFY(stream);
  674. size_t len = strlen(s);
  675. ScopedFileLock lock(stream);
  676. size_t nwritten = stream->write(reinterpret_cast<const u8*>(s), len);
  677. if (nwritten < len)
  678. return EOF;
  679. return 1;
  680. }
  681. int puts(const char* s)
  682. {
  683. int rc = fputs(s, stdout);
  684. if (rc == EOF)
  685. return EOF;
  686. return fputc('\n', stdout);
  687. }
  688. void clearerr(FILE* stream)
  689. {
  690. VERIFY(stream);
  691. ScopedFileLock lock(stream);
  692. stream->clear_err();
  693. }
  694. int ferror(FILE* stream)
  695. {
  696. VERIFY(stream);
  697. ScopedFileLock lock(stream);
  698. return stream->error();
  699. }
  700. size_t fread_unlocked(void* ptr, size_t size, size_t nmemb, FILE* stream)
  701. {
  702. VERIFY(stream);
  703. VERIFY(!Checked<size_t>::multiplication_would_overflow(size, nmemb));
  704. size_t nread = stream->read(reinterpret_cast<u8*>(ptr), size * nmemb);
  705. if (!nread)
  706. return 0;
  707. return nread / size;
  708. }
  709. size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
  710. {
  711. VERIFY(stream);
  712. ScopedFileLock lock(stream);
  713. return fread_unlocked(ptr, size, nmemb, stream);
  714. }
  715. size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream)
  716. {
  717. VERIFY(stream);
  718. VERIFY(!Checked<size_t>::multiplication_would_overflow(size, nmemb));
  719. ScopedFileLock lock(stream);
  720. size_t nwritten = stream->write(reinterpret_cast<const u8*>(ptr), size * nmemb);
  721. if (!nwritten)
  722. return 0;
  723. return nwritten / size;
  724. }
  725. int fseek(FILE* stream, long offset, int whence)
  726. {
  727. VERIFY(stream);
  728. ScopedFileLock lock(stream);
  729. return stream->seek(offset, whence);
  730. }
  731. int fseeko(FILE* stream, off_t offset, int whence)
  732. {
  733. VERIFY(stream);
  734. ScopedFileLock lock(stream);
  735. return stream->seek(offset, whence);
  736. }
  737. long ftell(FILE* stream)
  738. {
  739. VERIFY(stream);
  740. ScopedFileLock lock(stream);
  741. return stream->tell();
  742. }
  743. off_t ftello(FILE* stream)
  744. {
  745. VERIFY(stream);
  746. ScopedFileLock lock(stream);
  747. return stream->tell();
  748. }
  749. int fgetpos(FILE* stream, fpos_t* pos)
  750. {
  751. VERIFY(stream);
  752. VERIFY(pos);
  753. ScopedFileLock lock(stream);
  754. off_t val = stream->tell();
  755. if (val == -1L)
  756. return 1;
  757. *pos = val;
  758. return 0;
  759. }
  760. int fsetpos(FILE* stream, const fpos_t* pos)
  761. {
  762. VERIFY(stream);
  763. VERIFY(pos);
  764. ScopedFileLock lock(stream);
  765. return stream->seek(*pos, SEEK_SET);
  766. }
  767. void rewind(FILE* stream)
  768. {
  769. fseek(stream, 0, SEEK_SET);
  770. clearerr(stream);
  771. }
  772. ALWAYS_INLINE void stdout_putch(char*&, char ch)
  773. {
  774. putchar(ch);
  775. }
  776. static FILE* __current_stream = nullptr;
  777. ALWAYS_INLINE static void stream_putch(char*&, char ch)
  778. {
  779. fputc(ch, __current_stream);
  780. }
  781. int vfprintf(FILE* stream, const char* fmt, va_list ap)
  782. {
  783. __current_stream = stream;
  784. return printf_internal(stream_putch, nullptr, fmt, ap);
  785. }
  786. int fprintf(FILE* stream, const char* fmt, ...)
  787. {
  788. va_list ap;
  789. va_start(ap, fmt);
  790. int ret = vfprintf(stream, fmt, ap);
  791. va_end(ap);
  792. return ret;
  793. }
  794. int vprintf(const char* fmt, va_list ap)
  795. {
  796. return printf_internal(stdout_putch, nullptr, fmt, ap);
  797. }
  798. int printf(const char* fmt, ...)
  799. {
  800. va_list ap;
  801. va_start(ap, fmt);
  802. int ret = vprintf(fmt, ap);
  803. va_end(ap);
  804. return ret;
  805. }
  806. int vasprintf(char** strp, const char* fmt, va_list ap)
  807. {
  808. StringBuilder builder;
  809. builder.appendvf(fmt, ap);
  810. VERIFY(builder.length() <= NumericLimits<int>::max());
  811. int length = builder.length();
  812. *strp = strdup(builder.to_string().characters());
  813. return length;
  814. }
  815. int asprintf(char** strp, const char* fmt, ...)
  816. {
  817. StringBuilder builder;
  818. va_list ap;
  819. va_start(ap, fmt);
  820. builder.appendvf(fmt, ap);
  821. va_end(ap);
  822. VERIFY(builder.length() <= NumericLimits<int>::max());
  823. int length = builder.length();
  824. *strp = strdup(builder.to_string().characters());
  825. return length;
  826. }
  827. static void buffer_putch(char*& bufptr, char ch)
  828. {
  829. *bufptr++ = ch;
  830. }
  831. int vsprintf(char* buffer, const char* fmt, va_list ap)
  832. {
  833. int ret = printf_internal(buffer_putch, buffer, fmt, ap);
  834. buffer[ret] = '\0';
  835. return ret;
  836. }
  837. int sprintf(char* buffer, const char* fmt, ...)
  838. {
  839. va_list ap;
  840. va_start(ap, fmt);
  841. int ret = vsprintf(buffer, fmt, ap);
  842. va_end(ap);
  843. return ret;
  844. }
  845. static size_t __vsnprintf_space_remaining;
  846. ALWAYS_INLINE void sized_buffer_putch(char*& bufptr, char ch)
  847. {
  848. if (__vsnprintf_space_remaining) {
  849. *bufptr++ = ch;
  850. --__vsnprintf_space_remaining;
  851. }
  852. }
  853. int vsnprintf(char* buffer, size_t size, const char* fmt, va_list ap)
  854. {
  855. if (size) {
  856. __vsnprintf_space_remaining = size - 1;
  857. } else {
  858. __vsnprintf_space_remaining = 0;
  859. }
  860. int ret = printf_internal(sized_buffer_putch, buffer, fmt, ap);
  861. if (__vsnprintf_space_remaining) {
  862. buffer[ret] = '\0';
  863. } else if (size > 0) {
  864. buffer[size - 1] = '\0';
  865. }
  866. return ret;
  867. }
  868. int snprintf(char* buffer, size_t size, const char* fmt, ...)
  869. {
  870. va_list ap;
  871. va_start(ap, fmt);
  872. int ret = vsnprintf(buffer, size, fmt, ap);
  873. va_end(ap);
  874. return ret;
  875. }
  876. void perror(const char* s)
  877. {
  878. int saved_errno = errno;
  879. dbgln("perror(): {}: {}", s, strerror(saved_errno));
  880. warnln("{}: {}", s, strerror(saved_errno));
  881. }
  882. static int parse_mode(const char* mode)
  883. {
  884. int flags = 0;
  885. // NOTE: rt is a non-standard mode which opens a file for read, explicitly
  886. // specifying that it's a text file
  887. for (auto* ptr = mode; *ptr; ++ptr) {
  888. switch (*ptr) {
  889. case 'r':
  890. flags |= O_RDONLY;
  891. break;
  892. case 'w':
  893. flags |= O_WRONLY | O_CREAT | O_TRUNC;
  894. break;
  895. case 'a':
  896. flags |= O_WRONLY | O_APPEND | O_CREAT;
  897. break;
  898. case '+':
  899. flags |= O_RDWR;
  900. break;
  901. case 'e':
  902. flags |= O_CLOEXEC;
  903. break;
  904. case 'b':
  905. // Ok...
  906. break;
  907. case 't':
  908. // Ok...
  909. break;
  910. default:
  911. dbgln("Potentially unsupported fopen mode _{}_ (because of '{}')", mode, *ptr);
  912. }
  913. }
  914. return flags;
  915. }
  916. FILE* fopen(const char* pathname, const char* mode)
  917. {
  918. int flags = parse_mode(mode);
  919. int fd = open(pathname, flags, 0666);
  920. if (fd < 0)
  921. return nullptr;
  922. return FILE::create(fd, flags);
  923. }
  924. FILE* freopen(const char* pathname, const char* mode, FILE* stream)
  925. {
  926. VERIFY(stream);
  927. if (!pathname) {
  928. // FIXME: Someone should probably implement this path.
  929. TODO();
  930. }
  931. int flags = parse_mode(mode);
  932. int fd = open(pathname, flags, 0666);
  933. if (fd < 0)
  934. return nullptr;
  935. stream->reopen(fd, flags);
  936. return stream;
  937. }
  938. FILE* fdopen(int fd, const char* mode)
  939. {
  940. int flags = parse_mode(mode);
  941. // FIXME: Verify that the mode matches how fd is already open.
  942. if (fd < 0)
  943. return nullptr;
  944. return FILE::create(fd, flags);
  945. }
  946. static inline bool is_default_stream(FILE* stream)
  947. {
  948. return stream == stdin || stream == stdout || stream == stderr;
  949. }
  950. int fclose(FILE* stream)
  951. {
  952. VERIFY(stream);
  953. bool ok;
  954. {
  955. ScopedFileLock lock(stream);
  956. ok = stream->close();
  957. }
  958. ScopedValueRollback errno_restorer(errno);
  959. stream->~FILE();
  960. if (!is_default_stream(stream))
  961. free(stream);
  962. return ok ? 0 : EOF;
  963. }
  964. int rename(const char* oldpath, const char* newpath)
  965. {
  966. if (!oldpath || !newpath) {
  967. errno = EFAULT;
  968. return -1;
  969. }
  970. Syscall::SC_rename_params params { { oldpath, strlen(oldpath) }, { newpath, strlen(newpath) } };
  971. int rc = syscall(SC_rename, &params);
  972. __RETURN_WITH_ERRNO(rc, rc, -1);
  973. }
  974. void dbgputch(char ch)
  975. {
  976. syscall(SC_dbgputch, ch);
  977. }
  978. void dbgputstr(const char* characters, size_t length)
  979. {
  980. syscall(SC_dbgputstr, characters, length);
  981. }
  982. char* tmpnam(char*)
  983. {
  984. dbgln("FIXME: Implement tmpnam()");
  985. TODO();
  986. }
  987. FILE* popen(const char* command, const char* type)
  988. {
  989. if (!type || (*type != 'r' && *type != 'w')) {
  990. errno = EINVAL;
  991. return nullptr;
  992. }
  993. int pipe_fds[2];
  994. int rc = pipe(pipe_fds);
  995. if (rc < 0) {
  996. ScopedValueRollback rollback(errno);
  997. perror("pipe");
  998. return nullptr;
  999. }
  1000. pid_t child_pid = fork();
  1001. if (child_pid < 0) {
  1002. ScopedValueRollback rollback(errno);
  1003. perror("fork");
  1004. close(pipe_fds[0]);
  1005. close(pipe_fds[1]);
  1006. return nullptr;
  1007. } else if (child_pid == 0) {
  1008. if (*type == 'r') {
  1009. int rc = dup2(pipe_fds[1], STDOUT_FILENO);
  1010. if (rc < 0) {
  1011. perror("dup2");
  1012. exit(1);
  1013. }
  1014. close(pipe_fds[0]);
  1015. close(pipe_fds[1]);
  1016. } else if (*type == 'w') {
  1017. int rc = dup2(pipe_fds[0], STDIN_FILENO);
  1018. if (rc < 0) {
  1019. perror("dup2");
  1020. exit(1);
  1021. }
  1022. close(pipe_fds[0]);
  1023. close(pipe_fds[1]);
  1024. }
  1025. int rc = execl("/bin/sh", "sh", "-c", command, nullptr);
  1026. if (rc < 0)
  1027. perror("execl");
  1028. exit(1);
  1029. }
  1030. FILE* file = nullptr;
  1031. if (*type == 'r') {
  1032. file = FILE::create(pipe_fds[0], O_RDONLY);
  1033. close(pipe_fds[1]);
  1034. } else if (*type == 'w') {
  1035. file = FILE::create(pipe_fds[1], O_WRONLY);
  1036. close(pipe_fds[0]);
  1037. }
  1038. file->set_popen_child(child_pid);
  1039. return file;
  1040. }
  1041. int pclose(FILE* stream)
  1042. {
  1043. VERIFY(stream);
  1044. VERIFY(stream->popen_child() != 0);
  1045. int wstatus = 0;
  1046. int rc = waitpid(stream->popen_child(), &wstatus, 0);
  1047. if (rc < 0)
  1048. return rc;
  1049. return wstatus;
  1050. }
  1051. int remove(const char* pathname)
  1052. {
  1053. int rc = unlink(pathname);
  1054. if (rc < 0 && errno == EISDIR)
  1055. return rmdir(pathname);
  1056. return rc;
  1057. }
  1058. int scanf(const char* fmt, ...)
  1059. {
  1060. va_list ap;
  1061. va_start(ap, fmt);
  1062. int count = vfscanf(stdin, fmt, ap);
  1063. va_end(ap);
  1064. return count;
  1065. }
  1066. int fscanf(FILE* stream, const char* fmt, ...)
  1067. {
  1068. va_list ap;
  1069. va_start(ap, fmt);
  1070. int count = vfscanf(stream, fmt, ap);
  1071. va_end(ap);
  1072. return count;
  1073. }
  1074. int sscanf(const char* buffer, const char* fmt, ...)
  1075. {
  1076. va_list ap;
  1077. va_start(ap, fmt);
  1078. int count = vsscanf(buffer, fmt, ap);
  1079. va_end(ap);
  1080. return count;
  1081. }
  1082. int vfscanf(FILE* stream, const char* fmt, va_list ap)
  1083. {
  1084. char buffer[BUFSIZ];
  1085. if (!fgets(buffer, sizeof(buffer) - 1, stream))
  1086. return -1;
  1087. return vsscanf(buffer, fmt, ap);
  1088. }
  1089. int vscanf(const char* fmt, va_list ap)
  1090. {
  1091. return vfscanf(stdin, fmt, ap);
  1092. }
  1093. void flockfile([[maybe_unused]] FILE* filehandle)
  1094. {
  1095. dbgln("FIXME: Implement flockfile()");
  1096. }
  1097. void funlockfile([[maybe_unused]] FILE* filehandle)
  1098. {
  1099. dbgln("FIXME: Implement funlockfile()");
  1100. }
  1101. FILE* tmpfile()
  1102. {
  1103. char tmp_path[] = "/tmp/XXXXXX";
  1104. int fd = mkstemp(tmp_path);
  1105. if (fd < 0)
  1106. return nullptr;
  1107. // FIXME: instead of using this hack, implement with O_TMPFILE or similar
  1108. unlink(tmp_path);
  1109. return fdopen(fd, "rw");
  1110. }
  1111. int __freading(FILE* stream)
  1112. {
  1113. ScopedFileLock lock(stream);
  1114. if ((stream->mode() & O_RDWR) == O_RDONLY) {
  1115. return 1;
  1116. }
  1117. return (stream->flags() & FILE::Flags::LastRead);
  1118. }
  1119. int __fwriting(FILE* stream)
  1120. {
  1121. ScopedFileLock lock(stream);
  1122. if ((stream->mode() & O_RDWR) == O_WRONLY) {
  1123. return 1;
  1124. }
  1125. return (stream->flags() & FILE::Flags::LastWrite);
  1126. }
  1127. }