stdio.cpp 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright notice,
  13. * this list of conditions and the following disclaimer in the documentation
  14. * and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  24. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include <AK/LogStream.h>
  28. #include <AK/PrintfImplementation.h>
  29. #include <AK/ScopedValueRollback.h>
  30. #include <AK/StdLibExtras.h>
  31. #include <AK/kmalloc.h>
  32. #include <Kernel/Syscall.h>
  33. #include <assert.h>
  34. #include <errno.h>
  35. #include <fcntl.h>
  36. #include <stdarg.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <sys/types.h>
  41. #include <sys/wait.h>
  42. #include <unistd.h>
  43. struct FILE {
  44. public:
  45. FILE(int fd, int mode)
  46. : m_fd(fd)
  47. , m_mode(mode)
  48. {
  49. }
  50. ~FILE();
  51. static FILE* create(int fd, int mode);
  52. void setbuf(u8* data, int mode, size_t size) { m_buffer.setbuf(data, mode, size); }
  53. bool flush();
  54. bool close();
  55. int fileno() const { return m_fd; }
  56. bool eof() const { return m_eof; }
  57. int error() const { return m_error; }
  58. void clear_err() { m_error = 0; }
  59. size_t read(u8*, size_t);
  60. size_t write(const u8*, size_t);
  61. bool gets(u8*, size_t);
  62. bool ungetc(u8 byte) { return m_buffer.enqueue_front(byte); }
  63. int seek(long offset, int whence);
  64. long tell();
  65. pid_t popen_child() { return m_popen_child; }
  66. void set_popen_child(pid_t child_pid) { m_popen_child = child_pid; }
  67. private:
  68. struct Buffer {
  69. // A ringbuffer that also transparently implements ungetc().
  70. public:
  71. ~Buffer();
  72. int mode() const { return m_mode; }
  73. void setbuf(u8* data, int mode, size_t size);
  74. // Make sure to call realize() before enqueuing any data.
  75. // Dequeuing can be attempted without it.
  76. void realize(int fd);
  77. void drop();
  78. bool may_use() const { return m_ungotten || m_mode != _IONBF; }
  79. bool is_not_empty() const { return m_ungotten || !m_empty; }
  80. const u8* begin_dequeue(size_t& available_size) const;
  81. void did_dequeue(size_t actual_size);
  82. u8* begin_enqueue(size_t& available_size) const;
  83. void did_enqueue(size_t actual_size);
  84. bool enqueue_front(u8 byte);
  85. private:
  86. // Note: the fields here are arranged this way
  87. // to make sizeof(Buffer) smaller.
  88. u8* m_data { nullptr };
  89. size_t m_capacity { BUFSIZ };
  90. size_t m_begin { 0 };
  91. size_t m_end { 0 };
  92. int m_mode { -1 };
  93. u8 m_unget_buffer { 0 };
  94. bool m_ungotten : 1 { false };
  95. bool m_data_is_malloced : 1 { false };
  96. // When m_begin == m_end, we want to distinguish whether
  97. // the buffer is full or empty.
  98. bool m_empty : 1 { true };
  99. };
  100. // Read or write using the underlying fd, bypassing the buffer.
  101. ssize_t do_read(u8*, size_t);
  102. ssize_t do_write(const u8*, size_t);
  103. // Read some data into the buffer.
  104. bool read_into_buffer();
  105. // Flush *some* data from the buffer.
  106. bool write_from_buffer();
  107. int m_fd { -1 };
  108. int m_mode { 0 };
  109. int m_error { 0 };
  110. bool m_eof { false };
  111. pid_t m_popen_child { -1 };
  112. Buffer m_buffer;
  113. };
  114. FILE::~FILE()
  115. {
  116. bool already_closed = m_fd == -1;
  117. ASSERT(already_closed);
  118. }
  119. FILE* FILE::create(int fd, int mode)
  120. {
  121. void* file = calloc(1, sizeof(FILE));
  122. new (file) FILE(fd, mode);
  123. return (FILE*)file;
  124. }
  125. bool FILE::close()
  126. {
  127. bool flush_ok = flush();
  128. int rc = ::close(m_fd);
  129. m_fd = -1;
  130. if (!flush_ok) {
  131. // Restore the original error from flush().
  132. errno = m_error;
  133. }
  134. return flush_ok && rc == 0;
  135. }
  136. bool FILE::flush()
  137. {
  138. if (m_mode & O_WRONLY && m_buffer.may_use()) {
  139. // When open for writing, write out all the buffered data.
  140. while (m_buffer.is_not_empty()) {
  141. bool ok = write_from_buffer();
  142. if (!ok)
  143. return false;
  144. }
  145. }
  146. if (m_mode & O_RDONLY) {
  147. // When open for reading, just drop the buffered data.
  148. m_buffer.drop();
  149. }
  150. return true;
  151. }
  152. ssize_t FILE::do_read(u8* data, size_t size)
  153. {
  154. int nread = ::read(m_fd, data, size);
  155. if (nread < 0) {
  156. m_error = errno;
  157. } else if (nread == 0) {
  158. m_eof = true;
  159. }
  160. return nread;
  161. }
  162. ssize_t FILE::do_write(const u8* data, size_t size)
  163. {
  164. int nwritten = ::write(m_fd, data, size);
  165. if (nwritten < 0)
  166. m_error = errno;
  167. return nwritten;
  168. }
  169. bool FILE::read_into_buffer()
  170. {
  171. m_buffer.realize(m_fd);
  172. size_t available_size;
  173. u8* data = m_buffer.begin_enqueue(available_size);
  174. // If we want to read, the buffer must have some space!
  175. ASSERT(available_size);
  176. ssize_t nread = do_read(data, available_size);
  177. if (nread <= 0)
  178. return false;
  179. m_buffer.did_enqueue(nread);
  180. return true;
  181. }
  182. bool FILE::write_from_buffer()
  183. {
  184. size_t size;
  185. const u8* data = m_buffer.begin_dequeue(size);
  186. // If we want to write, the buffer must have something in it!
  187. ASSERT(size);
  188. ssize_t nwritten = do_write(data, size);
  189. if (nwritten < 0)
  190. return false;
  191. m_buffer.did_dequeue(nwritten);
  192. return true;
  193. }
  194. size_t FILE::read(u8* data, size_t size)
  195. {
  196. size_t total_read = 0;
  197. while (size > 0) {
  198. size_t actual_size;
  199. if (m_buffer.may_use()) {
  200. // Let's see if the buffer has something queued for us.
  201. size_t queued_size;
  202. const u8* queued_data = m_buffer.begin_dequeue(queued_size);
  203. if (queued_size == 0) {
  204. // Nothing buffered; we're going to have to read some.
  205. bool read_some_more = read_into_buffer();
  206. if (read_some_more) {
  207. // Great, now try this again.
  208. continue;
  209. }
  210. return total_read;
  211. }
  212. actual_size = min(size, queued_size);
  213. memcpy(data, queued_data, actual_size);
  214. m_buffer.did_dequeue(actual_size);
  215. } else {
  216. // Read directly into the user buffer.
  217. ssize_t nread = do_read(data, size);
  218. if (nread <= 0)
  219. return total_read;
  220. actual_size = nread;
  221. }
  222. total_read += actual_size;
  223. data += actual_size;
  224. size -= actual_size;
  225. }
  226. return total_read;
  227. }
  228. size_t FILE::write(const u8* data, size_t size)
  229. {
  230. size_t total_written = 0;
  231. while (size > 0) {
  232. size_t actual_size;
  233. if (m_buffer.may_use()) {
  234. m_buffer.realize(m_fd);
  235. // Try writing into the buffer.
  236. size_t available_size;
  237. u8* buffer_data = m_buffer.begin_enqueue(available_size);
  238. if (available_size == 0) {
  239. // There's no space in the buffer; we're going to free some.
  240. bool freed_some_space = write_from_buffer();
  241. if (freed_some_space) {
  242. // Great, now try this again.
  243. continue;
  244. }
  245. return total_written;
  246. }
  247. actual_size = min(size, available_size);
  248. memcpy(buffer_data, data, actual_size);
  249. m_buffer.did_enqueue(actual_size);
  250. // See if we have to flush it.
  251. if (m_buffer.mode() == _IOLBF) {
  252. bool includes_newline = memchr(data, '\n', actual_size);
  253. if (includes_newline)
  254. flush();
  255. }
  256. } else {
  257. // Write directly from the user buffer.
  258. ssize_t nwritten = do_write(data, size);
  259. if (nwritten < 0)
  260. return total_written;
  261. actual_size = nwritten;
  262. }
  263. total_written += actual_size;
  264. data += actual_size;
  265. size -= actual_size;
  266. }
  267. return total_written;
  268. }
  269. bool FILE::gets(u8* data, size_t size)
  270. {
  271. // gets() is a lot like read(), but it is different enough in how it
  272. // processes newlines and null-terminates the buffer that it deserves a
  273. // separate implementation.
  274. size_t total_read = 0;
  275. if (size == 0)
  276. return false;
  277. while (size > 1) {
  278. if (m_buffer.may_use()) {
  279. // Let's see if the buffer has something queued for us.
  280. size_t queued_size;
  281. const u8* queued_data = m_buffer.begin_dequeue(queued_size);
  282. if (queued_size == 0) {
  283. // Nothing buffered; we're going to have to read some.
  284. bool read_some_more = read_into_buffer();
  285. if (read_some_more) {
  286. // Great, now try this again.
  287. continue;
  288. }
  289. *data = 0;
  290. return total_read > 0;
  291. }
  292. size_t actual_size = min(size - 1, queued_size);
  293. u8* newline = reinterpret_cast<u8*>(memchr(queued_data, '\n', actual_size));
  294. if (newline)
  295. actual_size = newline - queued_data + 1;
  296. memcpy(data, queued_data, actual_size);
  297. m_buffer.did_dequeue(actual_size);
  298. total_read += actual_size;
  299. data += actual_size;
  300. size -= actual_size;
  301. if (newline)
  302. break;
  303. } else {
  304. // Sadly, we have to actually read these characters one by one.
  305. u8 byte;
  306. ssize_t nread = do_read(&byte, 1);
  307. if (nread <= 0) {
  308. *data = 0;
  309. return total_read > 0;
  310. }
  311. ASSERT(nread == 1);
  312. *data = byte;
  313. total_read++;
  314. data++;
  315. size--;
  316. if (byte == '\n')
  317. break;
  318. }
  319. }
  320. *data = 0;
  321. return total_read > 0;
  322. }
  323. int FILE::seek(long offset, int whence)
  324. {
  325. bool ok = flush();
  326. if (!ok)
  327. return -1;
  328. off_t off = lseek(m_fd, offset, whence);
  329. if (off < 0) {
  330. // Note: do not set m_error.
  331. return off;
  332. }
  333. m_eof = false;
  334. return 0;
  335. }
  336. long FILE::tell()
  337. {
  338. bool ok = flush();
  339. if (!ok)
  340. return -1;
  341. return lseek(m_fd, 0, SEEK_CUR);
  342. }
  343. FILE::Buffer::~Buffer()
  344. {
  345. if (m_data_is_malloced)
  346. free(m_data);
  347. }
  348. void FILE::Buffer::realize(int fd)
  349. {
  350. if (m_mode == -1)
  351. m_mode = isatty(fd) ? _IOLBF : _IOFBF;
  352. if (m_mode != _IONBF && m_data == nullptr) {
  353. m_data = reinterpret_cast<u8*>(malloc(m_capacity));
  354. m_data_is_malloced = true;
  355. }
  356. }
  357. void FILE::Buffer::setbuf(u8* data, int mode, size_t size)
  358. {
  359. drop();
  360. m_mode = mode;
  361. if (data != nullptr) {
  362. m_data = data;
  363. m_capacity = size;
  364. }
  365. }
  366. void FILE::Buffer::drop()
  367. {
  368. if (m_data_is_malloced) {
  369. free(m_data);
  370. m_data = nullptr;
  371. m_data_is_malloced = false;
  372. }
  373. m_begin = m_end = 0;
  374. m_empty = true;
  375. m_ungotten = false;
  376. }
  377. const u8* FILE::Buffer::begin_dequeue(size_t& available_size) const
  378. {
  379. if (m_ungotten) {
  380. available_size = 1;
  381. return &m_unget_buffer;
  382. }
  383. if (m_empty) {
  384. available_size = 0;
  385. return nullptr;
  386. }
  387. if (m_begin < m_end)
  388. available_size = m_end - m_begin;
  389. else
  390. available_size = m_capacity - m_begin;
  391. return &m_data[m_begin];
  392. }
  393. void FILE::Buffer::did_dequeue(size_t actual_size)
  394. {
  395. ASSERT(actual_size > 0);
  396. if (m_ungotten) {
  397. ASSERT(actual_size == 1);
  398. m_ungotten = false;
  399. return;
  400. }
  401. m_begin += actual_size;
  402. ASSERT(m_begin <= m_capacity);
  403. if (m_begin == m_capacity) {
  404. // Wrap around.
  405. m_begin = 0;
  406. }
  407. if (m_begin == m_end) {
  408. m_empty = true;
  409. // As an optimization, move both pointers to the beginning of the
  410. // buffer, so that more consecutive space is available next time.
  411. m_begin = m_end = 0;
  412. }
  413. }
  414. u8* FILE::Buffer::begin_enqueue(size_t& available_size) const
  415. {
  416. ASSERT(m_data != nullptr);
  417. if (m_begin < m_end || m_empty)
  418. available_size = m_capacity - m_end;
  419. else
  420. available_size = m_begin - m_end;
  421. return const_cast<u8*>(&m_data[m_end]);
  422. }
  423. void FILE::Buffer::did_enqueue(size_t actual_size)
  424. {
  425. ASSERT(m_data != nullptr);
  426. ASSERT(actual_size > 0);
  427. m_end += actual_size;
  428. ASSERT(m_end <= m_capacity);
  429. if (m_end == m_capacity) {
  430. // Wrap around.
  431. m_end = 0;
  432. }
  433. m_empty = false;
  434. }
  435. bool FILE::Buffer::enqueue_front(u8 byte)
  436. {
  437. if (m_ungotten) {
  438. // Sorry, the place is already taken!
  439. return false;
  440. }
  441. m_ungotten = true;
  442. m_unget_buffer = byte;
  443. return true;
  444. }
  445. extern "C" {
  446. static u8 default_streams[3][sizeof(FILE)];
  447. FILE* stdin = reinterpret_cast<FILE*>(&default_streams[0]);
  448. FILE* stdout = reinterpret_cast<FILE*>(&default_streams[1]);
  449. FILE* stderr = reinterpret_cast<FILE*>(&default_streams[2]);
  450. void __stdio_init()
  451. {
  452. new (stdin) FILE(0, O_RDONLY);
  453. new (stdout) FILE(1, O_WRONLY);
  454. new (stderr) FILE(2, O_WRONLY);
  455. stderr->setbuf(nullptr, _IONBF, 0);
  456. }
  457. int setvbuf(FILE* stream, char* buf, int mode, size_t size)
  458. {
  459. ASSERT(stream);
  460. if (mode != _IONBF && mode != _IOLBF && mode != _IOFBF) {
  461. errno = EINVAL;
  462. return -1;
  463. }
  464. stream->setbuf(reinterpret_cast<u8*>(buf), mode, size);
  465. return 0;
  466. }
  467. void setbuf(FILE* stream, char* buf)
  468. {
  469. setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
  470. }
  471. void setlinebuf(FILE* stream)
  472. {
  473. setvbuf(stream, nullptr, _IOLBF, 0);
  474. }
  475. int fileno(FILE* stream)
  476. {
  477. ASSERT(stream);
  478. return stream->fileno();
  479. }
  480. int feof(FILE* stream)
  481. {
  482. ASSERT(stream);
  483. return stream->eof();
  484. }
  485. int fflush(FILE* stream)
  486. {
  487. if (!stream) {
  488. dbg() << "FIXME: fflush(nullptr) should flush all open streams";
  489. return 0;
  490. }
  491. return stream->flush() ? 0 : EOF;
  492. }
  493. char* fgets(char* buffer, int size, FILE* stream)
  494. {
  495. ASSERT(stream);
  496. bool ok = stream->gets(reinterpret_cast<u8*>(buffer), size);
  497. return ok ? buffer : nullptr;
  498. }
  499. int fgetc(FILE* stream)
  500. {
  501. ASSERT(stream);
  502. char ch;
  503. size_t nread = fread(&ch, sizeof(char), 1, stream);
  504. if (nread == 1)
  505. return ch;
  506. return EOF;
  507. }
  508. int getc(FILE* stream)
  509. {
  510. return fgetc(stream);
  511. }
  512. int getc_unlocked(FILE* stream)
  513. {
  514. return fgetc(stream);
  515. }
  516. int getchar()
  517. {
  518. return getc(stdin);
  519. }
  520. ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* stream)
  521. {
  522. char *ptr, *eptr;
  523. if (*lineptr == nullptr || *n == 0) {
  524. *n = BUFSIZ;
  525. if ((*lineptr = static_cast<char*>(malloc(*n))) == nullptr) {
  526. return -1;
  527. }
  528. }
  529. for (ptr = *lineptr, eptr = *lineptr + *n;;) {
  530. int c = fgetc(stream);
  531. if (c == -1) {
  532. if (feof(stream)) {
  533. *ptr = '\0';
  534. return ptr == *lineptr ? -1 : ptr - *lineptr;
  535. } else {
  536. return -1;
  537. }
  538. }
  539. *ptr++ = c;
  540. if (c == delim) {
  541. *ptr = '\0';
  542. return ptr - *lineptr;
  543. }
  544. if (ptr + 2 >= eptr) {
  545. char* nbuf;
  546. size_t nbuf_sz = *n * 2;
  547. ssize_t d = ptr - *lineptr;
  548. if ((nbuf = static_cast<char*>(realloc(*lineptr, nbuf_sz))) == nullptr) {
  549. return -1;
  550. }
  551. *lineptr = nbuf;
  552. *n = nbuf_sz;
  553. eptr = nbuf + nbuf_sz;
  554. ptr = nbuf + d;
  555. }
  556. }
  557. }
  558. ssize_t getline(char** lineptr, size_t* n, FILE* stream)
  559. {
  560. return getdelim(lineptr, n, '\n', stream);
  561. }
  562. int ungetc(int c, FILE* stream)
  563. {
  564. ASSERT(stream);
  565. bool ok = stream->ungetc(c);
  566. return ok ? c : EOF;
  567. }
  568. int fputc(int ch, FILE* stream)
  569. {
  570. ASSERT(stream);
  571. u8 byte = ch;
  572. size_t nwritten = stream->write(&byte, 1);
  573. if (nwritten == 0)
  574. return EOF;
  575. ASSERT(nwritten == 1);
  576. return byte;
  577. }
  578. int putc(int ch, FILE* stream)
  579. {
  580. return fputc(ch, stream);
  581. }
  582. int putchar(int ch)
  583. {
  584. return putc(ch, stdout);
  585. }
  586. int fputs(const char* s, FILE* stream)
  587. {
  588. ASSERT(stream);
  589. size_t len = strlen(s);
  590. size_t nwritten = stream->write(reinterpret_cast<const u8*>(s), len);
  591. if (nwritten < len)
  592. return EOF;
  593. return 1;
  594. }
  595. int puts(const char* s)
  596. {
  597. int rc = fputs(s, stdout);
  598. if (rc == EOF)
  599. return EOF;
  600. return fputc('\n', stdout);
  601. }
  602. void clearerr(FILE* stream)
  603. {
  604. ASSERT(stream);
  605. stream->clear_err();
  606. }
  607. int ferror(FILE* stream)
  608. {
  609. ASSERT(stream);
  610. return stream->error();
  611. }
  612. size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
  613. {
  614. ASSERT(stream);
  615. ASSERT(!Checked<size_t>::multiplication_would_overflow(size, nmemb));
  616. size_t nread = stream->read(reinterpret_cast<u8*>(ptr), size * nmemb);
  617. return nread / size;
  618. }
  619. size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream)
  620. {
  621. ASSERT(stream);
  622. ASSERT(!Checked<size_t>::multiplication_would_overflow(size, nmemb));
  623. size_t nwritten = stream->write(reinterpret_cast<const u8*>(ptr), size * nmemb);
  624. return nwritten / size;
  625. }
  626. int fseek(FILE* stream, long offset, int whence)
  627. {
  628. ASSERT(stream);
  629. return stream->seek(offset, whence);
  630. }
  631. long ftell(FILE* stream)
  632. {
  633. ASSERT(stream);
  634. return stream->tell();
  635. }
  636. int fgetpos(FILE* stream, fpos_t* pos)
  637. {
  638. ASSERT(stream);
  639. ASSERT(pos);
  640. long val = stream->tell();
  641. if (val == -1L)
  642. return 1;
  643. *pos = val;
  644. return 0;
  645. }
  646. int fsetpos(FILE* stream, const fpos_t* pos)
  647. {
  648. ASSERT(stream);
  649. ASSERT(pos);
  650. return stream->seek((long)*pos, SEEK_SET);
  651. }
  652. void rewind(FILE* stream)
  653. {
  654. ASSERT(stream);
  655. int rc = stream->seek(0, SEEK_SET);
  656. ASSERT(rc == 0);
  657. }
  658. int dbgprintf(const char* fmt, ...)
  659. {
  660. va_list ap;
  661. va_start(ap, fmt);
  662. int ret = printf_internal([](char*&, char ch) { dbgputch(ch); }, nullptr, fmt, ap);
  663. va_end(ap);
  664. return ret;
  665. }
  666. ALWAYS_INLINE void stdout_putch(char*&, char ch)
  667. {
  668. putchar(ch);
  669. }
  670. static FILE* __current_stream = nullptr;
  671. ALWAYS_INLINE static void stream_putch(char*&, char ch)
  672. {
  673. fputc(ch, __current_stream);
  674. }
  675. int vfprintf(FILE* stream, const char* fmt, va_list ap)
  676. {
  677. __current_stream = stream;
  678. return printf_internal(stream_putch, nullptr, fmt, ap);
  679. }
  680. int fprintf(FILE* stream, const char* fmt, ...)
  681. {
  682. va_list ap;
  683. va_start(ap, fmt);
  684. int ret = vfprintf(stream, fmt, ap);
  685. va_end(ap);
  686. return ret;
  687. }
  688. int vprintf(const char* fmt, va_list ap)
  689. {
  690. return printf_internal(stdout_putch, nullptr, fmt, ap);
  691. }
  692. int printf(const char* fmt, ...)
  693. {
  694. va_list ap;
  695. va_start(ap, fmt);
  696. int ret = vprintf(fmt, ap);
  697. va_end(ap);
  698. return ret;
  699. }
  700. static void buffer_putch(char*& bufptr, char ch)
  701. {
  702. *bufptr++ = ch;
  703. }
  704. int vsprintf(char* buffer, const char* fmt, va_list ap)
  705. {
  706. int ret = printf_internal(buffer_putch, buffer, fmt, ap);
  707. buffer[ret] = '\0';
  708. return ret;
  709. }
  710. int sprintf(char* buffer, const char* fmt, ...)
  711. {
  712. va_list ap;
  713. va_start(ap, fmt);
  714. int ret = vsprintf(buffer, fmt, ap);
  715. va_end(ap);
  716. return ret;
  717. }
  718. static size_t __vsnprintf_space_remaining;
  719. ALWAYS_INLINE void sized_buffer_putch(char*& bufptr, char ch)
  720. {
  721. if (__vsnprintf_space_remaining) {
  722. *bufptr++ = ch;
  723. --__vsnprintf_space_remaining;
  724. }
  725. }
  726. int vsnprintf(char* buffer, size_t size, const char* fmt, va_list ap)
  727. {
  728. __vsnprintf_space_remaining = size;
  729. int ret = printf_internal(sized_buffer_putch, buffer, fmt, ap);
  730. if (__vsnprintf_space_remaining) {
  731. buffer[ret] = '\0';
  732. }
  733. return ret;
  734. }
  735. int snprintf(char* buffer, size_t size, const char* fmt, ...)
  736. {
  737. va_list ap;
  738. va_start(ap, fmt);
  739. int ret = vsnprintf(buffer, size, fmt, ap);
  740. va_end(ap);
  741. return ret;
  742. }
  743. void perror(const char* s)
  744. {
  745. int saved_errno = errno;
  746. dbg() << "perror(): " << s << ": " << strerror(saved_errno);
  747. fprintf(stderr, "%s: %s\n", s, strerror(saved_errno));
  748. }
  749. static int parse_mode(const char* mode)
  750. {
  751. int flags = 0;
  752. // NOTE: rt is a non-standard mode which opens a file for read, explicitly
  753. // specifying that it's a text file
  754. if (!strcmp(mode, "r") || !strcmp(mode, "rb") || !strcmp(mode, "rt"))
  755. flags = O_RDONLY;
  756. else if (!strcmp(mode, "r+") || !strcmp(mode, "rb+"))
  757. flags = O_RDWR;
  758. else if (!strcmp(mode, "w") || !strcmp(mode, "wb"))
  759. flags = O_WRONLY | O_CREAT | O_TRUNC;
  760. else if (!strcmp(mode, "w+") || !strcmp(mode, "wb+"))
  761. flags = O_RDWR | O_CREAT | O_TRUNC;
  762. else if (!strcmp(mode, "a") || !strcmp(mode, "ab"))
  763. flags = O_WRONLY | O_APPEND | O_CREAT;
  764. else if (!strcmp(mode, "a+") || !strcmp(mode, "ab+"))
  765. flags = O_RDWR | O_APPEND | O_CREAT;
  766. else {
  767. dbg() << "Unexpected mode _" << mode << "_";
  768. ASSERT_NOT_REACHED();
  769. }
  770. return flags;
  771. }
  772. FILE* fopen(const char* pathname, const char* mode)
  773. {
  774. int flags = parse_mode(mode);
  775. int fd = open(pathname, flags, 0666);
  776. if (fd < 0)
  777. return nullptr;
  778. return FILE::create(fd, flags);
  779. }
  780. FILE* freopen(const char* pathname, const char* mode, FILE* stream)
  781. {
  782. (void)pathname;
  783. (void)mode;
  784. (void)stream;
  785. ASSERT_NOT_REACHED();
  786. }
  787. FILE* fdopen(int fd, const char* mode)
  788. {
  789. int flags = parse_mode(mode);
  790. // FIXME: Verify that the mode matches how fd is already open.
  791. if (fd < 0)
  792. return nullptr;
  793. return FILE::create(fd, flags);
  794. }
  795. static inline bool is_default_stream(FILE* stream)
  796. {
  797. return stream == stdin || stream == stdout || stream == stderr;
  798. }
  799. int fclose(FILE* stream)
  800. {
  801. ASSERT(stream);
  802. bool ok = stream->close();
  803. ScopedValueRollback errno_restorer(errno);
  804. stream->~FILE();
  805. if (!is_default_stream(stream))
  806. free(stream);
  807. return ok ? 0 : EOF;
  808. }
  809. int rename(const char* oldpath, const char* newpath)
  810. {
  811. if (!oldpath || !newpath) {
  812. errno = EFAULT;
  813. return -1;
  814. }
  815. Syscall::SC_rename_params params { { oldpath, strlen(oldpath) }, { newpath, strlen(newpath) } };
  816. int rc = syscall(SC_rename, &params);
  817. __RETURN_WITH_ERRNO(rc, rc, -1);
  818. }
  819. void dbgputch(char ch)
  820. {
  821. syscall(SC_dbgputch, ch);
  822. }
  823. int dbgputstr(const char* characters, int length)
  824. {
  825. int rc = syscall(SC_dbgputstr, characters, length);
  826. __RETURN_WITH_ERRNO(rc, rc, -1);
  827. }
  828. char* tmpnam(char*)
  829. {
  830. ASSERT_NOT_REACHED();
  831. }
  832. FILE* popen(const char* command, const char* type)
  833. {
  834. if (!type || (*type != 'r' && *type != 'w')) {
  835. errno = EINVAL;
  836. return nullptr;
  837. }
  838. int pipe_fds[2];
  839. int rc = pipe(pipe_fds);
  840. if (rc < 0) {
  841. ScopedValueRollback rollback(errno);
  842. perror("pipe");
  843. return nullptr;
  844. }
  845. pid_t child_pid = fork();
  846. if (child_pid < 0) {
  847. ScopedValueRollback rollback(errno);
  848. perror("fork");
  849. close(pipe_fds[0]);
  850. close(pipe_fds[1]);
  851. return nullptr;
  852. } else if (child_pid == 0) {
  853. if (*type == 'r') {
  854. int rc = dup2(pipe_fds[1], STDOUT_FILENO);
  855. if (rc < 0) {
  856. perror("dup2");
  857. exit(1);
  858. }
  859. close(pipe_fds[0]);
  860. close(pipe_fds[1]);
  861. } else if (*type == 'w') {
  862. int rc = dup2(pipe_fds[0], STDIN_FILENO);
  863. if (rc < 0) {
  864. perror("dup2");
  865. exit(1);
  866. }
  867. close(pipe_fds[0]);
  868. close(pipe_fds[1]);
  869. }
  870. int rc = execl("/bin/sh", "sh", "-c", command, nullptr);
  871. if (rc < 0)
  872. perror("execl");
  873. exit(1);
  874. }
  875. FILE* file = nullptr;
  876. if (*type == 'r') {
  877. file = FILE::create(pipe_fds[0], O_RDONLY);
  878. close(pipe_fds[1]);
  879. } else if (*type == 'w') {
  880. file = FILE::create(pipe_fds[1], O_WRONLY);
  881. close(pipe_fds[0]);
  882. }
  883. file->set_popen_child(child_pid);
  884. return file;
  885. }
  886. int pclose(FILE* stream)
  887. {
  888. ASSERT(stream);
  889. ASSERT(stream->popen_child() != 0);
  890. int wstatus = 0;
  891. int rc = waitpid(stream->popen_child(), &wstatus, 0);
  892. if (rc < 0)
  893. return rc;
  894. return wstatus;
  895. }
  896. int remove(const char* pathname)
  897. {
  898. int rc = unlink(pathname);
  899. if (rc < 0 && errno != EISDIR)
  900. return -1;
  901. return rmdir(pathname);
  902. }
  903. int scanf(const char* fmt, ...)
  904. {
  905. va_list ap;
  906. va_start(ap, fmt);
  907. int count = vfscanf(stdin, fmt, ap);
  908. va_end(ap);
  909. return count;
  910. }
  911. int fscanf(FILE* stream, const char* fmt, ...)
  912. {
  913. va_list ap;
  914. va_start(ap, fmt);
  915. int count = vfscanf(stream, fmt, ap);
  916. va_end(ap);
  917. return count;
  918. }
  919. int sscanf(const char* buffer, const char* fmt, ...)
  920. {
  921. va_list ap;
  922. va_start(ap, fmt);
  923. int count = vsscanf(buffer, fmt, ap);
  924. va_end(ap);
  925. return count;
  926. }
  927. int vfscanf(FILE* stream, const char* fmt, va_list ap)
  928. {
  929. char buffer[BUFSIZ];
  930. if (!fgets(buffer, sizeof(buffer) - 1, stream))
  931. return -1;
  932. return vsscanf(buffer, fmt, ap);
  933. }
  934. void flockfile(FILE* filehandle)
  935. {
  936. (void)filehandle;
  937. dbgprintf("FIXME: Implement flockfile()\n");
  938. }
  939. void funlockfile(FILE* filehandle)
  940. {
  941. (void)filehandle;
  942. dbgprintf("FIXME: Implement funlockfile()\n");
  943. }
  944. FILE* tmpfile()
  945. {
  946. char tmp_path[] = "/tmp/XXXXXX";
  947. if (__generate_unique_filename(tmp_path) < 0)
  948. return nullptr;
  949. int fd = open(tmp_path, O_CREAT | O_EXCL | O_RDWR, S_IWUSR | S_IRUSR);
  950. if (fd < 0)
  951. return nullptr;
  952. // FIXME: instead of using this hack, implement with O_TMPFILE or similar
  953. unlink(tmp_path);
  954. return fdopen(fd, "rw");
  955. }
  956. }