sgx_file.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "platform_api_vmcore.h"
  6. #include "sgx_error.h"
  7. #include "sgx_file.h"
  8. #ifndef SGX_DISABLE_WASI
  9. #define TRACE_FUNC() os_printf("undefined %s\n", __FUNCTION__)
  10. #define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
  11. /** fd **/
  12. int
  13. ocall_open(int *p_fd, const char *pathname, int flags, bool has_mode,
  14. unsigned mode);
  15. int
  16. ocall_openat(int *p_fd, int dirfd, const char *pathname, int flags,
  17. bool has_mode, unsigned mode);
  18. int
  19. ocall_read(ssize_t *p_ret, int fd, void *buf, size_t read_size);
  20. int
  21. ocall_close(int *p_ret, int fd);
  22. int
  23. ocall_lseek(off_t *p_ret, int fd, off_t offset, int whence);
  24. int
  25. ocall_ftruncate(int *p_ret, int fd, off_t length);
  26. int
  27. ocall_fsync(int *p_ret, int fd);
  28. int
  29. ocall_fdatasync(int *p_ret, int fd);
  30. int
  31. ocall_isatty(int *p_ret, int fd);
  32. /** fd end **/
  33. /** DIR **/
  34. int
  35. ocall_fdopendir(int fd, void **p_dirp);
  36. int
  37. ocall_readdir(void **p_dirent, void *dirp);
  38. int
  39. ocall_rewinddir(void *dirp);
  40. int
  41. ocall_seekdir(void *dirp, long loc);
  42. int
  43. ocall_telldir(long *p_dir, void *dirp);
  44. int
  45. ocall_closedir(int *p_ret, void *dirp);
  46. /** DIR end **/
  47. /** stat **/
  48. int
  49. ocall_stat(int *p_ret, const char *pathname, void *buf, unsigned int buf_len);
  50. int
  51. ocall_fstat(int *p_ret, int fd, void *buf, unsigned int buf_len);
  52. int
  53. ocall_fstatat(int *p_ret, int dirfd, const char *pathname, void *buf,
  54. unsigned int buf_len, int flags);
  55. /** stat end **/
  56. /** link **/
  57. int
  58. ocall_mkdirat(int *p_ret, int dirfd, const char *pathname, unsigned mode);
  59. int
  60. ocall_link(int *p_ret, const char *oldpath, const char *newpath);
  61. int
  62. ocall_linkat(int *p_ret, int olddirfd, const char *oldpath, int newdirfd,
  63. const char *newpath, int flags);
  64. int
  65. ocall_unlinkat(int *p_ret, int dirfd, const char *pathname, int flags);
  66. int
  67. ocall_readlinkat(ssize_t *p_ret, int dirfd, const char *pathname, char *buf,
  68. size_t bufsiz);
  69. int
  70. ocall_renameat(int *p_ret, int olddirfd, const char *oldpath, int newdirfd,
  71. const char *newpath);
  72. int
  73. ocall_symlinkat(int *p_ret, const char *target, int newdirfd,
  74. const char *linkpath);
  75. /** link end **/
  76. /** control **/
  77. int
  78. ocall_ioctl(int *p_ret, int fd, unsigned long request, void *arg,
  79. unsigned int arg_len);
  80. int
  81. ocall_fcntl(int *p_ret, int fd, int cmd);
  82. int
  83. ocall_fcntl_long(int *p_ret, int fd, int cmd, long arg);
  84. /** control end **/
  85. /** **/
  86. int
  87. ocall_realpath(int *p_ret, const char *path, char *buf, unsigned int buf_len);
  88. int
  89. ocall_posix_fallocate(int *p_ret, int fd, off_t offset, off_t len);
  90. int
  91. ocall_poll(int *p_ret, void *fds, unsigned nfds, int timeout,
  92. unsigned int fds_len);
  93. int
  94. ocall_getopt(int *p_ret, int argc, char *argv_buf, unsigned int argv_buf_len,
  95. const char *optstring);
  96. int
  97. ocall_getrandom(ssize_t *p_ret, void *buf, size_t buflen, unsigned int flags);
  98. int
  99. ocall_getentropy(int *p_ret, void *buffer, size_t length);
  100. int
  101. ocall_sched_yield(int *p_ret);
  102. /** struct iovec **/
  103. ssize_t
  104. ocall_readv(ssize_t *p_ret, int fd, char *iov_buf, unsigned int buf_size,
  105. int iovcnt, bool has_offset, off_t offset);
  106. ssize_t
  107. ocall_writev(ssize_t *p_ret, int fd, char *iov_buf, unsigned int buf_size,
  108. int iovcnt, bool has_offset, off_t offset);
  109. /** iovec end **/
  110. int
  111. ocall_get_errno(int *p_ret);
  112. int
  113. open(const char *pathname, int flags, ...)
  114. {
  115. int fd;
  116. bool has_mode = false;
  117. mode_t mode = 0;
  118. if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
  119. va_list ap;
  120. va_start(ap, flags);
  121. mode = va_arg(ap, mode_t);
  122. va_end(ap);
  123. has_mode = true;
  124. }
  125. if (SGX_SUCCESS != ocall_open(&fd, pathname, flags, has_mode, mode)) {
  126. TRACE_OCALL_FAIL();
  127. return -1;
  128. }
  129. if (fd >= 0 && (flags & O_CLOEXEC))
  130. fcntl(fd, F_SETFD, FD_CLOEXEC);
  131. if (fd == -1)
  132. errno = get_errno();
  133. return fd;
  134. }
  135. int
  136. openat(int dirfd, const char *pathname, int flags, ...)
  137. {
  138. int fd;
  139. bool has_mode = false;
  140. mode_t mode = 0;
  141. if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
  142. va_list ap;
  143. va_start(ap, flags);
  144. mode = va_arg(ap, mode_t);
  145. va_end(ap);
  146. has_mode = true;
  147. }
  148. if (SGX_SUCCESS
  149. != ocall_openat(&fd, dirfd, pathname, flags, has_mode, mode)) {
  150. TRACE_OCALL_FAIL();
  151. return -1;
  152. }
  153. if (fd >= 0 && (flags & O_CLOEXEC))
  154. fcntl(fd, F_SETFD, FD_CLOEXEC);
  155. if (fd == -1)
  156. errno = get_errno();
  157. return fd;
  158. }
  159. int
  160. close(int fd)
  161. {
  162. int ret;
  163. if (ocall_close(&ret, fd) != SGX_SUCCESS) {
  164. TRACE_OCALL_FAIL();
  165. return -1;
  166. }
  167. if (ret == -1)
  168. errno = get_errno();
  169. return ret;
  170. }
  171. ssize_t
  172. read(int fd, void *buf, size_t size)
  173. {
  174. ssize_t ret;
  175. int size_read_max = 2048, size_read, total_size_read = 0, count, i;
  176. char *p = buf;
  177. if (buf == NULL) {
  178. TRACE_FUNC();
  179. return -1;
  180. }
  181. count = (size + size_read_max - 1) / size_read_max;
  182. for (i = 0; i < count; i++) {
  183. size_read = (i < count - 1) ? size_read_max : size - size_read_max * i;
  184. if (ocall_read(&ret, fd, p, size_read) != SGX_SUCCESS) {
  185. TRACE_OCALL_FAIL();
  186. return -1;
  187. }
  188. if (ret == -1) {
  189. /* read failed */
  190. errno = get_errno();
  191. return -1;
  192. }
  193. p += ret;
  194. total_size_read += ret;
  195. if (ret < size_read)
  196. /* end of file */
  197. break;
  198. }
  199. return total_size_read;
  200. }
  201. DIR *
  202. fdopendir(int fd)
  203. {
  204. DIR *result = NULL;
  205. result = (DIR *)BH_MALLOC(sizeof(DIR));
  206. if (!result)
  207. return NULL;
  208. if (ocall_fdopendir(fd, (void **)result) != SGX_SUCCESS) {
  209. TRACE_OCALL_FAIL();
  210. BH_FREE(result);
  211. return NULL;
  212. }
  213. if ((void *)*result == NULL) { /* opendir failed */
  214. TRACE_FUNC();
  215. BH_FREE(result);
  216. errno = get_errno();
  217. return NULL;
  218. }
  219. return result;
  220. }
  221. struct dirent *
  222. readdir(DIR *dirp)
  223. {
  224. struct dirent *result;
  225. if (dirp == NULL)
  226. return NULL;
  227. if (ocall_readdir((void **)&result, (void *)*dirp) != SGX_SUCCESS) {
  228. TRACE_OCALL_FAIL();
  229. return NULL;
  230. }
  231. if (!result)
  232. errno = get_errno();
  233. return result;
  234. }
  235. void
  236. rewinddir(DIR *dirp)
  237. {
  238. if (ocall_rewinddir((void *)*dirp) != SGX_SUCCESS) {
  239. TRACE_OCALL_FAIL();
  240. }
  241. }
  242. void
  243. seekdir(DIR *dirp, long loc)
  244. {
  245. if (ocall_seekdir((void *)*dirp, loc) != SGX_SUCCESS) {
  246. TRACE_OCALL_FAIL();
  247. }
  248. }
  249. long
  250. telldir(DIR *dirp)
  251. {
  252. long ret;
  253. if (ocall_telldir(&ret, (void *)*dirp) != SGX_SUCCESS) {
  254. TRACE_OCALL_FAIL();
  255. return -1;
  256. }
  257. if (ret == -1)
  258. errno = get_errno();
  259. return ret;
  260. }
  261. int
  262. closedir(DIR *dirp)
  263. {
  264. int ret;
  265. if (ocall_closedir(&ret, (void *)*dirp) != SGX_SUCCESS) {
  266. TRACE_OCALL_FAIL();
  267. return -1;
  268. }
  269. BH_FREE(dirp);
  270. if (ret == -1)
  271. errno = get_errno();
  272. return ret;
  273. }
  274. static ssize_t
  275. readv_internal(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
  276. off_t offset)
  277. {
  278. ssize_t ret, size_left;
  279. struct iovec *iov1;
  280. int i;
  281. char *p;
  282. uint64 total_size = sizeof(struct iovec) * (uint64)iovcnt;
  283. if (iov == NULL || iovcnt < 1)
  284. return -1;
  285. for (i = 0; i < iovcnt; i++) {
  286. total_size += iov[i].iov_len;
  287. }
  288. if (total_size >= UINT32_MAX)
  289. return -1;
  290. iov1 = BH_MALLOC((uint32)total_size);
  291. if (iov1 == NULL)
  292. return -1;
  293. memset(iov1, 0, (uint32)total_size);
  294. p = (char *)(uintptr_t)(sizeof(struct iovec) * iovcnt);
  295. for (i = 0; i < iovcnt; i++) {
  296. iov1[i].iov_len = iov[i].iov_len;
  297. iov1[i].iov_base = p;
  298. p += iov[i].iov_len;
  299. }
  300. if (ocall_readv(&ret, fd, (char *)iov1, (uint32)total_size, iovcnt,
  301. has_offset, offset)
  302. != SGX_SUCCESS) {
  303. TRACE_OCALL_FAIL();
  304. BH_FREE(iov1);
  305. return -1;
  306. }
  307. p = (char *)(uintptr_t)(sizeof(struct iovec) * iovcnt);
  308. size_left = ret;
  309. for (i = 0; i < iovcnt; i++) {
  310. if (size_left > iov[i].iov_len) {
  311. memcpy(iov[i].iov_base, (uintptr_t)p + (char *)iov1,
  312. iov[i].iov_len);
  313. p += iov[i].iov_len;
  314. size_left -= iov[i].iov_len;
  315. }
  316. else {
  317. memcpy(iov[i].iov_base, (uintptr_t)p + (char *)iov1, size_left);
  318. break;
  319. }
  320. }
  321. BH_FREE(iov1);
  322. if (ret == -1)
  323. errno = get_errno();
  324. return ret;
  325. }
  326. static ssize_t
  327. writev_internal(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
  328. off_t offset)
  329. {
  330. ssize_t ret;
  331. struct iovec *iov1;
  332. int i;
  333. char *p;
  334. uint64 total_size = sizeof(struct iovec) * (uint64)iovcnt;
  335. if (iov == NULL || iovcnt < 1)
  336. return -1;
  337. for (i = 0; i < iovcnt; i++) {
  338. total_size += iov[i].iov_len;
  339. }
  340. if (total_size >= UINT32_MAX)
  341. return -1;
  342. iov1 = BH_MALLOC((uint32)total_size);
  343. if (iov1 == NULL)
  344. return -1;
  345. memset(iov1, 0, (uint32)total_size);
  346. p = (char *)(uintptr_t)(sizeof(struct iovec) * iovcnt);
  347. for (i = 0; i < iovcnt; i++) {
  348. iov1[i].iov_len = iov[i].iov_len;
  349. iov1[i].iov_base = p;
  350. memcpy((uintptr_t)p + (char *)iov1, iov[i].iov_base, iov[i].iov_len);
  351. p += iov[i].iov_len;
  352. }
  353. if (ocall_writev(&ret, fd, (char *)iov1, (uint32)total_size, iovcnt,
  354. has_offset, offset)
  355. != SGX_SUCCESS) {
  356. TRACE_OCALL_FAIL();
  357. BH_FREE(iov1);
  358. return -1;
  359. }
  360. BH_FREE(iov1);
  361. if (ret == -1)
  362. errno = get_errno();
  363. return ret;
  364. }
  365. ssize_t
  366. readv(int fd, const struct iovec *iov, int iovcnt)
  367. {
  368. return readv_internal(fd, iov, iovcnt, false, 0);
  369. }
  370. ssize_t
  371. writev(int fd, const struct iovec *iov, int iovcnt)
  372. {
  373. return writev_internal(fd, iov, iovcnt, false, 0);
  374. }
  375. ssize_t
  376. preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
  377. {
  378. return readv_internal(fd, iov, iovcnt, true, offset);
  379. }
  380. ssize_t
  381. pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
  382. {
  383. return writev_internal(fd, iov, iovcnt, true, offset);
  384. }
  385. off_t
  386. lseek(int fd, off_t offset, int whence)
  387. {
  388. off_t ret;
  389. if (ocall_lseek(&ret, fd, (long)offset, whence) != SGX_SUCCESS) {
  390. TRACE_OCALL_FAIL();
  391. return -1;
  392. }
  393. if (ret == -1)
  394. errno = get_errno();
  395. return ret;
  396. }
  397. int
  398. ftruncate(int fd, off_t length)
  399. {
  400. int ret;
  401. if (ocall_ftruncate(&ret, fd, length) != SGX_SUCCESS) {
  402. TRACE_OCALL_FAIL();
  403. return -1;
  404. }
  405. if (ret == -1)
  406. errno = get_errno();
  407. return ret;
  408. }
  409. int
  410. stat(const char *pathname, struct stat *statbuf)
  411. {
  412. int ret;
  413. if (statbuf == NULL)
  414. return -1;
  415. if (ocall_stat(&ret, pathname, (void *)statbuf, sizeof(struct stat))
  416. != SGX_SUCCESS) {
  417. TRACE_OCALL_FAIL();
  418. return -1;
  419. }
  420. if (ret == -1)
  421. errno = get_errno();
  422. return ret;
  423. }
  424. int
  425. fstat(int fd, struct stat *statbuf)
  426. {
  427. int ret;
  428. if (statbuf == NULL)
  429. return -1;
  430. if (ocall_fstat(&ret, fd, (void *)statbuf, sizeof(struct stat))
  431. != SGX_SUCCESS) {
  432. TRACE_OCALL_FAIL();
  433. return -1;
  434. }
  435. if (ret == -1)
  436. errno = get_errno();
  437. return ret;
  438. }
  439. int
  440. fstatat(int dirfd, const char *pathname, struct stat *statbuf, int flags)
  441. {
  442. int ret;
  443. if (statbuf == NULL)
  444. return -1;
  445. if (ocall_fstatat(&ret, dirfd, pathname, (void *)statbuf,
  446. sizeof(struct stat), flags)
  447. != SGX_SUCCESS) {
  448. TRACE_OCALL_FAIL();
  449. return -1;
  450. }
  451. if (ret == -1)
  452. errno = get_errno();
  453. return ret;
  454. }
  455. int
  456. fsync(int fd)
  457. {
  458. int ret;
  459. if (ocall_fsync(&ret, fd) != SGX_SUCCESS) {
  460. TRACE_OCALL_FAIL();
  461. return -1;
  462. }
  463. if (ret == -1)
  464. errno = get_errno();
  465. return ret;
  466. }
  467. int
  468. fdatasync(int fd)
  469. {
  470. int ret;
  471. if (ocall_fdatasync(&ret, fd) != SGX_SUCCESS) {
  472. TRACE_OCALL_FAIL();
  473. return -1;
  474. }
  475. if (ret == -1)
  476. errno = get_errno();
  477. return ret;
  478. }
  479. int
  480. mkdirat(int dirfd, const char *pathname, mode_t mode)
  481. {
  482. int ret;
  483. if (ocall_mkdirat(&ret, dirfd, pathname, mode) != SGX_SUCCESS) {
  484. TRACE_OCALL_FAIL();
  485. return -1;
  486. }
  487. if (ret == -1)
  488. errno = get_errno();
  489. return ret;
  490. }
  491. int
  492. link(const char *oldpath, const char *newpath)
  493. {
  494. int ret;
  495. if (ocall_link(&ret, oldpath, newpath) != SGX_SUCCESS) {
  496. TRACE_OCALL_FAIL();
  497. return -1;
  498. }
  499. if (ret == -1)
  500. errno = get_errno();
  501. return ret;
  502. }
  503. int
  504. linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
  505. int flags)
  506. {
  507. int ret;
  508. if (ocall_linkat(&ret, olddirfd, oldpath, newdirfd, newpath, flags)
  509. != SGX_SUCCESS) {
  510. TRACE_OCALL_FAIL();
  511. return -1;
  512. }
  513. if (ret == -1)
  514. errno = get_errno();
  515. return ret;
  516. }
  517. int
  518. unlinkat(int dirfd, const char *pathname, int flags)
  519. {
  520. int ret;
  521. if (ocall_unlinkat(&ret, dirfd, pathname, flags) != SGX_SUCCESS) {
  522. TRACE_OCALL_FAIL();
  523. return -1;
  524. }
  525. if (ret == -1)
  526. errno = get_errno();
  527. return ret;
  528. }
  529. ssize_t
  530. readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
  531. {
  532. ssize_t ret;
  533. if (buf == NULL)
  534. return -1;
  535. if (ocall_readlinkat(&ret, dirfd, pathname, buf, bufsiz) != SGX_SUCCESS) {
  536. TRACE_OCALL_FAIL();
  537. return -1;
  538. }
  539. if (ret == -1)
  540. errno = get_errno();
  541. return ret;
  542. }
  543. int
  544. symlinkat(const char *target, int newdirfd, const char *linkpath)
  545. {
  546. int ret;
  547. if (ocall_symlinkat(&ret, target, newdirfd, linkpath) != SGX_SUCCESS) {
  548. TRACE_OCALL_FAIL();
  549. return -1;
  550. }
  551. if (ret == -1)
  552. errno = get_errno();
  553. return ret;
  554. }
  555. int
  556. renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath)
  557. {
  558. int ret;
  559. if (ocall_renameat(&ret, olddirfd, oldpath, newdirfd, newpath)
  560. != SGX_SUCCESS) {
  561. TRACE_OCALL_FAIL();
  562. return -1;
  563. }
  564. if (ret == -1)
  565. errno = get_errno();
  566. return ret;
  567. }
  568. int
  569. ioctl(int fd, unsigned long request, ...)
  570. {
  571. int ret;
  572. va_list args;
  573. switch (request) {
  574. case FIONREAD:
  575. va_start(args, request);
  576. int *arg = (int *)va_arg(args, int *);
  577. if (ocall_ioctl(&ret, fd, request, arg, sizeof(*arg))
  578. != SGX_SUCCESS) {
  579. TRACE_OCALL_FAIL();
  580. va_end(args);
  581. return -1;
  582. }
  583. va_end(args);
  584. break;
  585. default:
  586. os_printf("ioctl failed: unknown request", request);
  587. return -1;
  588. }
  589. if (ret == -1)
  590. errno = get_errno();
  591. return ret;
  592. }
  593. int
  594. fcntl(int fd, int cmd, ... /* arg */)
  595. {
  596. int ret;
  597. va_list args;
  598. switch (cmd) {
  599. case F_GETFD:
  600. case F_GETFL:
  601. if (ocall_fcntl(&ret, fd, cmd) != SGX_SUCCESS) {
  602. TRACE_OCALL_FAIL();
  603. return -1;
  604. }
  605. break;
  606. case F_DUPFD:
  607. case F_SETFD:
  608. case F_SETFL:
  609. va_start(args, cmd);
  610. long arg_1 = (long)va_arg(args, long);
  611. if (ocall_fcntl_long(&ret, fd, cmd, arg_1) != SGX_SUCCESS) {
  612. TRACE_OCALL_FAIL();
  613. va_end(args);
  614. return -1;
  615. }
  616. va_end(args);
  617. break;
  618. default:
  619. os_printf("fcntl failed: unknown cmd %d.\n", cmd);
  620. return -1;
  621. }
  622. if (ret == -1)
  623. errno = get_errno();
  624. return ret;
  625. }
  626. int
  627. isatty(int fd)
  628. {
  629. int ret;
  630. if (ocall_isatty(&ret, fd) != SGX_SUCCESS) {
  631. TRACE_OCALL_FAIL();
  632. return -1;
  633. }
  634. if (ret == 0)
  635. errno = get_errno();
  636. return ret;
  637. }
  638. char *
  639. realpath(const char *path, char *resolved_path)
  640. {
  641. int ret;
  642. char buf[PATH_MAX] = { 0 };
  643. if (ocall_realpath(&ret, path, buf, PATH_MAX) != SGX_SUCCESS) {
  644. TRACE_OCALL_FAIL();
  645. return (char *)NULL;
  646. }
  647. if (ret != 0)
  648. return (char *)NULL;
  649. if (resolved_path) {
  650. strcpy(resolved_path, buf);
  651. }
  652. else {
  653. resolved_path = BH_MALLOC(strlen(buf) + 1);
  654. if (resolved_path == NULL)
  655. return NULL;
  656. strcpy(resolved_path, buf);
  657. }
  658. return resolved_path;
  659. }
  660. int
  661. posix_fallocate(int fd, off_t offset, off_t len)
  662. {
  663. int ret;
  664. if (ocall_posix_fallocate(&ret, fd, offset, len) != SGX_SUCCESS) {
  665. TRACE_OCALL_FAIL();
  666. return -1;
  667. }
  668. return ret;
  669. }
  670. int
  671. poll(struct pollfd *fds, nfds_t nfds, int timeout)
  672. {
  673. int ret;
  674. if (fds == NULL)
  675. return -1;
  676. if (ocall_poll(&ret, fds, nfds, timeout, sizeof(*fds) * nfds)
  677. != SGX_SUCCESS) {
  678. TRACE_OCALL_FAIL();
  679. return -1;
  680. }
  681. if (ret == -1)
  682. errno = get_errno();
  683. return ret;
  684. }
  685. int
  686. getopt(int argc, char *const argv[], const char *optstring)
  687. {
  688. int ret;
  689. char **argv1;
  690. char *p;
  691. int i;
  692. uint64 total_size = sizeof(char *) * (uint64)argc;
  693. for (i = 0; i < argc; i++) {
  694. total_size += strlen(argv[i]) + 1;
  695. }
  696. if (total_size >= UINT32_MAX)
  697. return -1;
  698. argv1 = BH_MALLOC((uint32)total_size);
  699. if (argv1 == NULL)
  700. return -1;
  701. p = (char *)(uintptr_t)(sizeof(char *) * argc);
  702. for (i = 0; i < argc; i++) {
  703. argv1[i] = p;
  704. strcpy((char *)argv1 + (uintptr_t)p, argv[i]);
  705. p += ((uintptr_t)strlen(argv[i]) + 1);
  706. }
  707. if (ocall_getopt(&ret, argc, (char *)argv1, total_size, optstring)
  708. != SGX_SUCCESS) {
  709. TRACE_OCALL_FAIL();
  710. BH_FREE(argv1);
  711. return -1;
  712. }
  713. BH_FREE(argv1);
  714. if (ret == -1)
  715. errno = get_errno();
  716. return ret;
  717. }
  718. int
  719. sched_yield(void)
  720. {
  721. int ret;
  722. if (ocall_sched_yield(&ret) != SGX_SUCCESS) {
  723. TRACE_OCALL_FAIL();
  724. return -1;
  725. }
  726. if (ret == -1)
  727. errno = get_errno();
  728. return ret;
  729. }
  730. ssize_t
  731. getrandom(void *buf, size_t buflen, unsigned int flags)
  732. {
  733. ssize_t ret;
  734. if (ocall_getrandom(&ret, buf, buflen, flags) != SGX_SUCCESS) {
  735. TRACE_OCALL_FAIL();
  736. return -1;
  737. }
  738. if (ret == -1)
  739. errno = get_errno();
  740. return ret;
  741. }
  742. int
  743. getentropy(void *buffer, size_t length)
  744. {
  745. int ret;
  746. if (ocall_getentropy(&ret, buffer, length) != SGX_SUCCESS) {
  747. TRACE_OCALL_FAIL();
  748. return -1;
  749. }
  750. if (ret == -1)
  751. errno = get_errno();
  752. return ret;
  753. }
  754. int
  755. get_errno(void)
  756. {
  757. int ret;
  758. if (ocall_get_errno(&ret) != SGX_SUCCESS) {
  759. TRACE_OCALL_FAIL();
  760. return -1;
  761. }
  762. return ret;
  763. }
  764. #endif