lwp_syscall.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-06-10 Bernard first version
  9. */
  10. /* RT-Thread System call */
  11. #include <rthw.h>
  12. #include <board.h>
  13. #include <lwp.h>
  14. #ifdef RT_USING_USERSPACE
  15. #include <lwp_user_mm.h>
  16. #endif
  17. #ifdef RT_USING_DFS
  18. #include <dfs_poll.h>
  19. #include <dfs_posix.h>
  20. #include <dfs_select.h>
  21. #endif
  22. #if (defined(RT_USING_SAL) && defined(SAL_USING_POSIX))
  23. #include <sys/socket.h>
  24. #define SYSCALL_NET(f) ((void*)(f))
  25. #else
  26. #define SYSCALL_NET(f) ((void*)sys_notimpl)
  27. #endif
  28. #if defined(RT_USING_DFS) && defined(RT_USING_USERSPACE)
  29. #define SYSCALL_USPACE(f) ((void*)(f))
  30. #else
  31. #define SYSCALL_USPACE(f) ((void*)sys_notimpl)
  32. #endif
  33. #define DBG_TAG "SYSCALL"
  34. #define DBG_LVL DBG_INFO
  35. #include <rtdbg.h>
  36. #ifdef RT_USING_SAL
  37. #include <netdev_ipaddr.h>
  38. #include <netdev.h>
  39. #include <sal_netdb.h>
  40. #include <sal.h>
  41. #endif /* RT_USING_SAL */
  42. #include "lwp_ipc_internal.h"
  43. #define ALLOC_KERNEL_STACK_SIZE 5120
  44. struct musl_sockaddr
  45. {
  46. uint16_t sa_family;
  47. char sa_data[14];
  48. };
  49. extern void lwp_user_entry(void *args, const void *text, void *data, void *user_stack);
  50. extern void set_user_context(void *stack);
  51. void lwp_cleanup(struct rt_thread *tid);
  52. #ifdef RT_USING_USERSPACE
  53. static void *kmem_get(size_t size)
  54. {
  55. return rt_malloc(size);
  56. }
  57. static void kmem_put(void *kptr)
  58. {
  59. rt_free(kptr);
  60. }
  61. #endif
  62. static void sockaddr_tolwip(const struct musl_sockaddr *std, struct sockaddr *lwip)
  63. {
  64. if (std && lwip)
  65. {
  66. lwip->sa_len = sizeof(*lwip);
  67. lwip->sa_family = (sa_family_t) std->sa_family;
  68. memcpy(lwip->sa_data, std->sa_data, sizeof(lwip->sa_data));
  69. }
  70. }
  71. static void sockaddr_tomusl(const struct sockaddr *lwip, struct musl_sockaddr *std)
  72. {
  73. if (std && lwip)
  74. {
  75. std->sa_family = (uint16_t) lwip->sa_family;
  76. memcpy(std->sa_data, lwip->sa_data, sizeof(std->sa_data));
  77. }
  78. }
  79. static void lwp_user_thread(void *parameter)
  80. {
  81. rt_thread_t tid;
  82. uint32_t user_stack;
  83. struct rt_lwp *lwp;
  84. tid = rt_thread_self();
  85. lwp = lwp_self();
  86. user_stack = (uint32_t)tid->user_stack + tid->user_stack_size;
  87. user_stack &= ~7; //align 8
  88. set_user_context((void*)user_stack);
  89. lwp_user_entry(parameter, tid->user_entry, lwp->data_entry, (void*)user_stack);
  90. }
  91. /* thread/process */
  92. void sys_exit(int value)
  93. {
  94. rt_base_t level;
  95. rt_thread_t tid, main_thread;
  96. struct rt_lwp *lwp;
  97. LOG_D("thread/process exit.");
  98. tid = rt_thread_self();
  99. lwp = (struct rt_lwp*)tid->lwp;
  100. level = rt_hw_interrupt_disable();
  101. main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling);
  102. if (main_thread == tid)
  103. {
  104. lwp_terminate(lwp);
  105. lwp_wait_subthread_exit();
  106. lwp->lwp_ret = value;
  107. }
  108. rt_thread_delete(tid);
  109. rt_schedule();
  110. rt_hw_interrupt_enable(level);
  111. return;
  112. }
  113. /* exit group */
  114. void sys_exit_group(int status)
  115. {
  116. return;
  117. }
  118. /* syscall: "read" ret: "ssize_t" args: "int" "void *" "size_t" */
  119. ssize_t sys_read(int fd, void *buf, size_t nbyte)
  120. {
  121. #ifdef RT_USING_USERSPACE
  122. void *kmem;
  123. ssize_t ret;
  124. if (!nbyte)
  125. return 0;
  126. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)buf, nbyte))
  127. return 0;
  128. kmem = kmem_get(nbyte);
  129. if (!kmem)
  130. return 0;
  131. ret = read(fd, kmem, nbyte);
  132. if (ret)
  133. lwp_data_put(&lwp_self()->mmu_info, buf, kmem, ret);
  134. kmem_put(kmem);
  135. return ret;
  136. #else
  137. return read(fd, buf, nbyte);
  138. #endif
  139. }
  140. /* syscall: "write" ret: "ssize_t" args: "int" "const void *" "size_t" */
  141. ssize_t sys_write(int fd, const void *buf, size_t nbyte)
  142. {
  143. #ifdef RT_USING_USERSPACE
  144. void *kmem;
  145. ssize_t ret;
  146. if (!nbyte)
  147. return 0;
  148. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)buf, nbyte))
  149. return 0;
  150. kmem = kmem_get(nbyte);
  151. if (!kmem)
  152. return 0;
  153. lwp_data_get(&lwp_self()->mmu_info, kmem, (void *)buf, nbyte);
  154. ret = write(fd, kmem, nbyte);
  155. kmem_put(kmem);
  156. return ret;
  157. #else
  158. return write(fd, buf, nbyte);
  159. #endif
  160. }
  161. /* syscall: "lseek" ret: "off_t" args: "int" "off_t" "int" */
  162. off_t sys_lseek(int fd, off_t offset, int whence)
  163. {
  164. return lseek(fd, offset, whence);
  165. }
  166. /* syscall: "open" ret: "int" args: "const char *" "int" "..." */
  167. int sys_open(const char *name, int flag, ...)
  168. {
  169. #ifdef RT_USING_USERSPACE
  170. int ret;
  171. rt_size_t len;
  172. char *kname;
  173. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)name, 1))
  174. return -1;
  175. len = rt_strlen(name);
  176. if (!len)
  177. return -1;
  178. kname = (char *)kmem_get(len + 1);
  179. if (!kname)
  180. return -1;
  181. lwp_data_get(&lwp_self()->mmu_info, kname, (void *)name, len + 1);
  182. ret = open(kname, flag, 0);
  183. kmem_put(kname);
  184. return ret;
  185. #else
  186. return open(name, flag, 0);
  187. #endif
  188. }
  189. /* syscall: "close" ret: "int" args: "int" */
  190. int sys_close(int fd)
  191. {
  192. if ((0 <= fd) && (fd <= 2))
  193. {
  194. return 0;
  195. }
  196. return close(fd);
  197. }
  198. /* syscall: "ioctl" ret: "int" args: "int" "u_long" "..." */
  199. int sys_ioctl(int fd, unsigned long cmd, void* data)
  200. {
  201. return ioctl(fd, cmd, data);
  202. }
  203. int sys_fstat(int file, struct stat *buf)
  204. {
  205. #ifdef RT_USING_USERSPACE
  206. int ret;
  207. struct stat statbuff;
  208. ret = fstat(file, &statbuff);
  209. lwp_data_put(&lwp_self()->mmu_info, buf, &statbuff, sizeof statbuff);
  210. return ret;
  211. #else
  212. return fstat(file, buf);
  213. #endif
  214. }
  215. int sys_poll(struct pollfd *fds, nfds_t nfds, int timeout)
  216. {
  217. #ifdef RT_USING_USERSPACE
  218. int ret;
  219. struct pollfd *kfds;
  220. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)fds, nfds * sizeof *fds))
  221. return -1;
  222. kfds = (struct pollfd *)kmem_get(nfds * sizeof *kfds);
  223. if (!kfds)
  224. return -1;
  225. lwp_data_get(&lwp_self()->mmu_info, kfds, fds, nfds * sizeof *kfds);
  226. ret = poll(kfds, nfds, timeout);
  227. lwp_data_put(&lwp_self()->mmu_info, fds, kfds, nfds * sizeof *kfds);
  228. kmem_put(kfds);
  229. return ret;
  230. #else
  231. return poll(fds, nfds, timeout);
  232. #endif
  233. }
  234. int sys_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
  235. {
  236. #ifdef RT_USING_USERSPACE
  237. int ret = -1;
  238. fd_set *kreadfds = RT_NULL, *kwritefds = RT_NULL, *kexceptfds = RT_NULL;
  239. if (readfds)
  240. {
  241. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)readfds, nfds * sizeof *readfds))
  242. return -1;
  243. kreadfds = (fd_set *)kmem_get(nfds * sizeof *kreadfds);
  244. if (!kreadfds)
  245. goto quit;
  246. lwp_data_get(&lwp_self()->mmu_info, kreadfds, readfds, nfds * sizeof *kreadfds);
  247. }
  248. if (writefds)
  249. {
  250. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)writefds, nfds * sizeof *writefds))
  251. return -1;
  252. kwritefds = (fd_set *)kmem_get(nfds * sizeof *kwritefds);
  253. if (!kwritefds)
  254. goto quit;
  255. lwp_data_get(&lwp_self()->mmu_info, kwritefds, writefds, nfds * sizeof *kwritefds);
  256. }
  257. if (exceptfds)
  258. {
  259. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)exceptfds, nfds * sizeof *exceptfds))
  260. return -1;
  261. kexceptfds = (fd_set *)kmem_get(nfds * sizeof *kexceptfds);
  262. if (!kexceptfds)
  263. goto quit;
  264. lwp_data_get(&lwp_self()->mmu_info, kexceptfds, exceptfds, nfds * sizeof *kexceptfds);
  265. }
  266. ret = select(nfds, kreadfds, kwritefds, kexceptfds, timeout);
  267. if (kreadfds)
  268. lwp_data_put(&lwp_self()->mmu_info, readfds, kreadfds, nfds * sizeof *kreadfds);
  269. if (kwritefds)
  270. lwp_data_put(&lwp_self()->mmu_info, writefds, kwritefds, nfds * sizeof *kwritefds);
  271. if (kexceptfds)
  272. lwp_data_put(&lwp_self()->mmu_info, exceptfds, kexceptfds, nfds * sizeof *kexceptfds);
  273. quit:
  274. if (kreadfds)
  275. kmem_put(kreadfds);
  276. if (kwritefds)
  277. kmem_put(kwritefds);
  278. if (kexceptfds)
  279. kmem_put(kexceptfds);
  280. return ret;
  281. #else
  282. return select(nfds, readfds, writefds, exceptfds, timeout);
  283. #endif
  284. }
  285. int sys_unlink(const char *pathname)
  286. {
  287. #ifdef RT_USING_USERSPACE
  288. int ret;
  289. rt_size_t len;
  290. char *kname;
  291. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)pathname, 1))
  292. return -1;
  293. len = rt_strlen(pathname);
  294. if (!len)
  295. return -1;
  296. kname = (char *)kmem_get(len + 1);
  297. if (!kname)
  298. return -1;
  299. lwp_data_get(&lwp_self()->mmu_info, kname, (void *)pathname, len + 1);
  300. ret = unlink(kname);
  301. kmem_put(kname);
  302. return ret;
  303. #else
  304. return unlink(pathname);
  305. #endif
  306. }
  307. /* syscall: "nanosleep" ret: "int" args: "const struct timespec *" "struct timespec *" */
  308. int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
  309. {
  310. rt_tick_t tick;
  311. #ifdef RT_USING_USERSPACE
  312. struct timespec rqtp_k;
  313. struct timespec rmtp_k;
  314. dbg_log(DBG_LOG, "sys_nanosleep\n");
  315. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)rqtp, sizeof *rqtp))
  316. return -1;
  317. lwp_data_get(&lwp_self()->mmu_info, &rqtp_k, (void *)rqtp, sizeof rqtp_k);
  318. tick = rqtp_k.tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp_k.tv_nsec * RT_TICK_PER_SECOND)/ 1000000000;
  319. rt_thread_delay(tick);
  320. if (rmtp)
  321. {
  322. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)rmtp, sizeof *rmtp))
  323. return -1;
  324. tick = rt_tick_get() - tick;
  325. /* get the passed time */
  326. rmtp_k.tv_sec = tick/RT_TICK_PER_SECOND;
  327. rmtp_k.tv_nsec = (tick%RT_TICK_PER_SECOND) * (1000000000/RT_TICK_PER_SECOND);
  328. lwp_data_put(&lwp_self()->mmu_info, rmtp, (void *)&rmtp_k, sizeof rmtp_k);
  329. }
  330. #else
  331. dbg_log(DBG_LOG, "sys_nanosleep\n");
  332. tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp->tv_nsec * RT_TICK_PER_SECOND)/ 1000000000;
  333. rt_thread_delay(tick);
  334. if (rmtp)
  335. {
  336. tick = rt_tick_get() - tick;
  337. /* get the passed time */
  338. rmtp->tv_sec = tick/RT_TICK_PER_SECOND;
  339. rmtp->tv_nsec = (tick%RT_TICK_PER_SECOND) * (1000000000/RT_TICK_PER_SECOND);
  340. }
  341. #endif
  342. return 0;
  343. }
  344. /* syscall: "gettimeofday" ret: "int" args: "struct timeval *" "struct timezone *" */
  345. int sys_gettimeofday(struct timeval *tp, struct timezone *tzp)
  346. {
  347. struct timeval t_k;
  348. #ifdef RT_USING_USERSPACE
  349. if (tp)
  350. {
  351. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)tp, sizeof *tp))
  352. return -1;
  353. t_k.tv_sec = rt_tick_get() / RT_TICK_PER_SECOND;
  354. t_k.tv_usec = (rt_tick_get() % RT_TICK_PER_SECOND) * (1000000 / RT_TICK_PER_SECOND);
  355. lwp_data_put(&lwp_self()->mmu_info, tp, (void *)&t_k, sizeof t_k);
  356. }
  357. #else
  358. if (tp)
  359. {
  360. tp->tv_sec = rt_tick_get() / RT_TICK_PER_SECOND;
  361. tp->tv_usec = (rt_tick_get() % RT_TICK_PER_SECOND) * (1000000 / RT_TICK_PER_SECOND);
  362. }
  363. #endif
  364. return 0;
  365. }
  366. int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp)
  367. {
  368. return 0;
  369. }
  370. #ifdef RT_USING_GDBSERVER
  371. int lwp_execve(char *filename, int debug, int argc, char **argv, char **envp);
  372. #else
  373. int lwp_execve(char *filename, int argc, char **argv, char **envp);
  374. #endif
  375. int sys_exec(char *filename, int argc, char **argv, char **envp)
  376. {
  377. #ifdef RT_USING_GDBSERVER
  378. return lwp_execve(filename, 0, argc, argv, envp);
  379. #else
  380. return lwp_execve(filename, argc, argv, envp);
  381. #endif
  382. }
  383. int sys_kill(int pid, int sig)
  384. {
  385. return lwp_kill(pid, sig);
  386. }
  387. int sys_getpid(void)
  388. {
  389. return lwp_getpid();
  390. }
  391. /* syscall: "getpriority" ret: "int" args: "int" "id_t" */
  392. int sys_getpriority(int which, id_t who)
  393. {
  394. if (which == PRIO_PROCESS)
  395. {
  396. rt_thread_t tid;
  397. tid = rt_thread_self();
  398. if (who == (id_t)tid || who == 0xff)
  399. {
  400. return tid->current_priority;
  401. }
  402. }
  403. return 0xff;
  404. }
  405. /* syscall: "setpriority" ret: "int" args: "int" "id_t" "int" */
  406. int sys_setpriority(int which, id_t who, int prio)
  407. {
  408. if (which == PRIO_PROCESS)
  409. {
  410. rt_thread_t tid;
  411. tid = rt_thread_self();
  412. if ((who == (id_t)tid || who == 0xff) && (prio >= 0 && prio < RT_THREAD_PRIORITY_MAX))
  413. {
  414. rt_thread_control(tid, RT_THREAD_CTRL_CHANGE_PRIORITY, &prio);
  415. return 0;
  416. }
  417. }
  418. return -1;
  419. }
  420. rt_sem_t sys_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag)
  421. {
  422. return rt_sem_create(name, value, flag);
  423. }
  424. rt_err_t sys_sem_delete(rt_sem_t sem)
  425. {
  426. return rt_sem_delete(sem);
  427. }
  428. rt_err_t sys_sem_take(rt_sem_t sem, rt_int32_t time)
  429. {
  430. return rt_sem_take(sem, time);
  431. }
  432. rt_err_t sys_sem_release(rt_sem_t sem)
  433. {
  434. return rt_sem_release(sem);
  435. }
  436. rt_mutex_t sys_mutex_create(const char *name, rt_uint8_t flag)
  437. {
  438. return rt_mutex_create(name, flag);
  439. }
  440. rt_err_t sys_mutex_delete(rt_mutex_t mutex)
  441. {
  442. return rt_mutex_delete(mutex);
  443. }
  444. rt_err_t sys_mutex_take(rt_mutex_t mutex, rt_int32_t time)
  445. {
  446. return rt_mutex_take(mutex, time);
  447. }
  448. rt_err_t sys_mutex_release(rt_mutex_t mutex)
  449. {
  450. return rt_mutex_release(mutex);
  451. }
  452. #ifdef RT_USING_USERSPACE
  453. /* memory allocation */
  454. extern int lwp_brk(void *addr);
  455. int sys_brk(void *addr)
  456. {
  457. return lwp_brk(addr);
  458. }
  459. extern void *lwp_mmap2(void *addr, size_t length, int prot,
  460. int flags, int fd, off_t pgoffset);
  461. void *sys_mmap2(void *addr, size_t length, int prot,
  462. int flags, int fd, off_t pgoffset)
  463. {
  464. return lwp_mmap2(addr, length, prot, flags, fd, pgoffset);
  465. }
  466. extern int lwp_munmap(void *addr, size_t length);
  467. int sys_munmap(void *addr, size_t length)
  468. {
  469. return lwp_munmap(addr, length);
  470. }
  471. #endif
  472. rt_event_t sys_event_create(const char *name, rt_uint8_t flag)
  473. {
  474. return rt_event_create(name, flag);
  475. }
  476. rt_err_t sys_event_delete(rt_event_t event)
  477. {
  478. return rt_event_delete(event);
  479. }
  480. rt_err_t sys_event_send(rt_event_t event, rt_uint32_t set)
  481. {
  482. return rt_event_send(event, set);
  483. }
  484. rt_err_t sys_event_recv(rt_event_t event,
  485. rt_uint32_t set,
  486. rt_uint8_t opt,
  487. rt_int32_t timeout,
  488. rt_uint32_t *recved)
  489. {
  490. return rt_event_recv(event, set, opt, timeout, recved);
  491. }
  492. rt_mailbox_t sys_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
  493. {
  494. return rt_mb_create(name, size, flag);
  495. }
  496. rt_err_t sys_mb_delete(rt_mailbox_t mb)
  497. {
  498. return rt_mb_delete(mb);
  499. }
  500. rt_err_t sys_mb_send(rt_mailbox_t mb, rt_uint32_t value)
  501. {
  502. return rt_mb_send(mb, value);
  503. }
  504. rt_err_t sys_mb_send_wait(rt_mailbox_t mb,
  505. rt_uint32_t value,
  506. rt_int32_t timeout)
  507. {
  508. return rt_mb_send_wait(mb, value, timeout);
  509. }
  510. rt_err_t sys_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout)
  511. {
  512. return rt_mb_recv(mb, (rt_ubase_t*)value, timeout);
  513. }
  514. rt_mq_t sys_mq_create(const char *name,
  515. rt_size_t msg_size,
  516. rt_size_t max_msgs,
  517. rt_uint8_t flag)
  518. {
  519. return rt_mq_create(name, msg_size, max_msgs, flag);
  520. }
  521. rt_err_t sys_mq_delete(rt_mq_t mq)
  522. {
  523. return rt_mq_delete(mq);
  524. }
  525. rt_err_t sys_mq_send(rt_mq_t mq, void *buffer, rt_size_t size)
  526. {
  527. return rt_mq_send(mq, buffer, size);
  528. }
  529. rt_err_t sys_mq_urgent(rt_mq_t mq, void *buffer, rt_size_t size)
  530. {
  531. return rt_mq_urgent(mq, buffer, size);
  532. }
  533. rt_err_t sys_mq_recv(rt_mq_t mq,
  534. void *buffer,
  535. rt_size_t size,
  536. rt_int32_t timeout)
  537. {
  538. return rt_mq_recv(mq, buffer, size, timeout);
  539. }
  540. static void timer_timeout_callback(void *parameter)
  541. {
  542. rt_sem_t sem = (rt_sem_t)parameter;
  543. rt_sem_release(sem);
  544. }
  545. rt_timer_t sys_timer_create(const char *name,
  546. void *data,
  547. rt_tick_t time,
  548. rt_uint8_t flag)
  549. {
  550. return rt_timer_create(name, timer_timeout_callback, (void*)data, time, flag);
  551. }
  552. rt_err_t sys_timer_delete(rt_timer_t timer)
  553. {
  554. return rt_timer_delete(timer);
  555. }
  556. rt_err_t sys_timer_start(rt_timer_t timer)
  557. {
  558. return rt_timer_start(timer);
  559. }
  560. rt_err_t sys_timer_stop(rt_timer_t timer)
  561. {
  562. return rt_timer_stop(timer);
  563. }
  564. rt_err_t sys_timer_control(rt_timer_t timer, int cmd, void *arg)
  565. {
  566. return rt_timer_control(timer, cmd, arg);
  567. }
  568. #ifdef RT_USING_USERSPACE
  569. void *lwp_map_user(struct rt_lwp *lwp, void *map_va, size_t map_size);
  570. #endif
  571. rt_thread_t sys_thread_create(void *arg[])
  572. {
  573. rt_base_t level;
  574. void *user_stack = 0;
  575. struct rt_lwp *lwp = 0;
  576. rt_thread_t tid;
  577. lwp = rt_thread_self()->lwp;
  578. lwp_ref_inc(lwp);
  579. #ifdef RT_USING_USERSPACE
  580. user_stack = lwp_map_user(lwp, 0, (size_t)arg[3]);
  581. #else
  582. user_stack = (void *)RT_KERNEL_MALLOC((uint32_t)arg[3]);
  583. #endif
  584. if (!user_stack)
  585. {
  586. return RT_NULL;
  587. }
  588. tid = rt_thread_create((const char*)arg[0], lwp_user_thread, (void*)arg[2], ALLOC_KERNEL_STACK_SIZE, (rt_uint8_t)(size_t)arg[4], (rt_uint32_t)arg[5]);
  589. if (!tid)
  590. {
  591. goto fail;
  592. }
  593. tid->cleanup = lwp_cleanup;
  594. tid->user_entry = (void (*)(void *))arg[1];
  595. tid->user_stack = (void *)user_stack;
  596. tid->user_stack_size = (uint32_t)arg[3];
  597. tid->lwp = (void*)lwp;
  598. level = rt_hw_interrupt_disable();
  599. rt_list_insert_after(&lwp->t_grp, &tid->sibling);
  600. rt_hw_interrupt_enable(level);
  601. return tid;
  602. fail:
  603. #ifndef RT_USING_USERSPACE
  604. if (user_stack)
  605. {
  606. RT_KERNEL_FREE(user_stack);
  607. }
  608. #endif
  609. if (lwp)
  610. {
  611. lwp_ref_dec(lwp);
  612. }
  613. return RT_NULL;
  614. }
  615. rt_err_t sys_thread_delete(rt_thread_t thread)
  616. {
  617. return rt_thread_delete(thread);
  618. }
  619. rt_err_t sys_thread_startup(rt_thread_t thread)
  620. {
  621. return rt_thread_startup(thread);
  622. }
  623. rt_thread_t sys_thread_self(void)
  624. {
  625. return rt_thread_self();
  626. }
  627. /* sys channel */
  628. int sys_channel_open(const char *name, int flags)
  629. {
  630. return lwp_channel_open(FDT_TYPE_LWP, name, flags);
  631. }
  632. rt_err_t sys_channel_close(int fd)
  633. {
  634. return lwp_channel_close(FDT_TYPE_LWP, fd);
  635. }
  636. rt_err_t sys_channel_send(int fd, rt_channel_msg_t data)
  637. {
  638. return lwp_channel_send(FDT_TYPE_LWP, fd, data);
  639. }
  640. rt_err_t sys_channel_send_recv_timeout(int fd, rt_channel_msg_t data, rt_channel_msg_t data_ret, rt_int32_t time)
  641. {
  642. return lwp_channel_send_recv_timeout(FDT_TYPE_LWP, fd, data, data_ret, time);
  643. }
  644. rt_err_t sys_channel_reply(int fd, rt_channel_msg_t data)
  645. {
  646. return lwp_channel_reply(FDT_TYPE_LWP, fd, data);
  647. }
  648. rt_err_t sys_channel_recv_timeout(int fd, rt_channel_msg_t data, rt_int32_t time)
  649. {
  650. return lwp_channel_recv_timeout(FDT_TYPE_LWP, fd, data, time);
  651. }
  652. /*****/
  653. static struct rt_semaphore critical_lock;
  654. static int critical_init(void)
  655. {
  656. rt_sem_init(&critical_lock, "ct_lock", 1, RT_IPC_FLAG_FIFO);
  657. return 0;
  658. }
  659. INIT_DEVICE_EXPORT(critical_init);
  660. void sys_enter_critical(void)
  661. {
  662. rt_sem_take(&critical_lock, RT_WAITING_FOREVER);
  663. }
  664. void sys_exit_critical(void)
  665. {
  666. rt_sem_release(&critical_lock);
  667. }
  668. /* syscall: "sys_log" ret: "int" args: "const char*" "size" */
  669. static int __sys_log_enable = 0;
  670. static int sys_log_enable(int argc, char** argv)
  671. {
  672. if (argc == 1)
  673. {
  674. rt_kprintf("sys_log = %d\n", __sys_log_enable);
  675. return 0;
  676. }
  677. else
  678. {
  679. __sys_log_enable = atoi(argv[1]);
  680. }
  681. return 0;
  682. }
  683. MSH_CMD_EXPORT_ALIAS(sys_log_enable, sys_log, sys_log 1(enable)/0(disable));
  684. int sys_log(const char* log, int size)
  685. {
  686. rt_device_t console = rt_console_get_device();
  687. if (console && __sys_log_enable) rt_device_write(console, -1, log, size);
  688. return 0;
  689. }
  690. int sys_stat(const char *file, struct stat *buf)
  691. {
  692. return stat(file, buf);
  693. }
  694. int sys_notimpl(void)
  695. {
  696. return -ENOSYS;
  697. }
  698. uint32_t sys_hw_interrupt_disable(void)
  699. {
  700. return rt_hw_interrupt_disable();
  701. }
  702. void sys_hw_interrupt_enable(uint32_t level)
  703. {
  704. rt_hw_interrupt_enable(level);
  705. }
  706. #ifdef RT_USING_USERSPACE
  707. int sys_shmget(size_t key, size_t size, int create)
  708. {
  709. return lwp_shmget(key, size, create);
  710. }
  711. int sys_shmrm(int id)
  712. {
  713. return lwp_shmrm(id);
  714. }
  715. void* sys_shmat(int id, void* shm_vaddr)
  716. {
  717. return lwp_shmat(id, shm_vaddr);
  718. }
  719. int sys_shmdt(void* shm_vaddr)
  720. {
  721. return lwp_shmdt(shm_vaddr);
  722. }
  723. #endif
  724. /* device interfaces */
  725. rt_err_t sys_device_init(rt_device_t dev)
  726. {
  727. return rt_device_init(dev);
  728. }
  729. rt_err_t sys_device_register(rt_device_t dev, const char *name, rt_uint16_t flags)
  730. {
  731. return rt_device_register(dev, name, flags);
  732. }
  733. rt_err_t sys_device_control(rt_device_t dev, int cmd, void *arg)
  734. {
  735. return rt_device_control(dev, cmd, arg);
  736. }
  737. rt_device_t sys_device_find(const char* name)
  738. {
  739. return rt_device_find(name);
  740. }
  741. rt_err_t sys_device_open(rt_device_t dev, rt_uint16_t oflag)
  742. {
  743. return rt_device_open(dev, oflag);
  744. }
  745. rt_err_t sys_device_close(rt_device_t dev)
  746. {
  747. return rt_device_close(dev);
  748. }
  749. rt_size_t sys_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  750. {
  751. return rt_device_read(dev, pos, buffer, size);
  752. }
  753. rt_size_t sys_device_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  754. {
  755. return rt_device_write(dev, pos, buffer, size);
  756. }
  757. /* network interfaces */
  758. int sys_accept(int socket, struct musl_sockaddr *addr, socklen_t *addrlen)
  759. {
  760. struct sockaddr sa;
  761. sockaddr_tolwip(addr, &sa);
  762. return accept(socket, &sa, addrlen);
  763. }
  764. int sys_bind(int socket, const struct musl_sockaddr *name, socklen_t namelen)
  765. {
  766. struct sockaddr sa;
  767. sockaddr_tolwip(name, &sa);
  768. return bind(socket, &sa, namelen);
  769. }
  770. int sys_shutdown(int socket, int how)
  771. {
  772. return shutdown(socket, how);
  773. }
  774. int sys_getpeername (int socket, struct musl_sockaddr *name, socklen_t *namelen)
  775. {
  776. int ret;
  777. struct sockaddr sa;
  778. sockaddr_tolwip(name, &sa);
  779. ret = getpeername (socket, &sa, namelen);
  780. if (name) sockaddr_tomusl(&sa, name);
  781. return ret;
  782. }
  783. int sys_getsockname (int socket, struct musl_sockaddr *name, socklen_t *namelen)
  784. {
  785. int ret;
  786. struct sockaddr sa;
  787. sockaddr_tolwip(name, &sa);
  788. ret = getsockname (socket, &sa, namelen);
  789. if (name) sockaddr_tomusl(&sa, name);
  790. return ret;
  791. }
  792. int sys_getsockopt (int socket, int level, int optname, void *optval, socklen_t *optlen)
  793. {
  794. LOG_I("syscall: getsockopt");
  795. return getsockopt (socket, level, optname, optval, optlen);
  796. }
  797. int sys_setsockopt (int socket, int level, int optname, const void *optval, socklen_t optlen)
  798. {
  799. LOG_I("syscall: setsockopt");
  800. return setsockopt (socket, level, optname, optval, optlen);
  801. }
  802. int sys_connect(int socket, const struct musl_sockaddr *name, socklen_t namelen)
  803. {
  804. struct sockaddr sa;
  805. sockaddr_tolwip(name, &sa);
  806. return connect(socket, &sa, namelen);
  807. }
  808. int sys_listen(int socket, int backlog)
  809. {
  810. return listen(socket, backlog);
  811. }
  812. #define MUSLC_MSG_OOB 0x0001
  813. #define MUSLC_MSG_PEEK 0x0002
  814. #define MUSLC_MSG_DONTWAIT 0x0040
  815. #define MUSLC_MSG_WAITALL 0x0100
  816. #define MUSLC_MSG_MORE 0x8000
  817. static int netflags_muslc_2_lwip(int flags)
  818. {
  819. int flgs = 0;
  820. if (flags & MUSLC_MSG_PEEK)
  821. flgs |= MSG_PEEK;
  822. if (flags & MUSLC_MSG_WAITALL)
  823. flgs |= MSG_WAITALL;
  824. if (flags & MUSLC_MSG_OOB)
  825. flgs |= MSG_OOB;
  826. if (flags & MUSLC_MSG_DONTWAIT)
  827. flgs |= MSG_DONTWAIT;
  828. if (flags & MUSLC_MSG_MORE)
  829. flgs |= MSG_MORE;
  830. return flgs;
  831. }
  832. int sys_recvfrom(int socket, void *mem, size_t len, int flags,
  833. struct musl_sockaddr *from, socklen_t *fromlen)
  834. {
  835. int flgs = 0;
  836. #ifdef RT_USING_USERSPACE
  837. int ret = -1;
  838. void *kmem = RT_NULL;
  839. #endif
  840. flgs = netflags_muslc_2_lwip(flags);
  841. #ifdef RT_USING_USERSPACE
  842. if (!len)
  843. return -1;
  844. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)mem, len))
  845. return -1;
  846. kmem = kmem_get(len);
  847. if (!kmem)
  848. return -1;
  849. if (flags == 0x2) {
  850. flags = 0x1;
  851. }
  852. if (from)
  853. {
  854. struct sockaddr sa;
  855. sockaddr_tolwip(from, &sa);
  856. ret = recvfrom(socket, kmem, len, flgs, &sa, fromlen);
  857. } else
  858. ret = recvfrom(socket, kmem, len, flgs, NULL, NULL);
  859. if (ret > 0)
  860. lwp_data_put(&lwp_self()->mmu_info, mem, kmem, len);
  861. kmem_put(kmem);
  862. return ret;
  863. #else
  864. if (from)
  865. {
  866. struct sockaddr sa;
  867. sockaddr_tolwip(from, &sa);
  868. return recvfrom(socket, mem, len, flgs, &sa, fromlen);
  869. }
  870. return recvfrom(socket, mem, len, flags, NULL, NULL);
  871. #endif
  872. }
  873. int sys_recv(int socket, void *mem, size_t len, int flags)
  874. {
  875. int flgs = 0;
  876. flgs = netflags_muslc_2_lwip(flags);
  877. return recvfrom(socket, mem, len, flgs, NULL, NULL);
  878. }
  879. int sys_sendto(int socket, const void *dataptr, size_t size, int flags,
  880. const struct musl_sockaddr *to, socklen_t tolen)
  881. {
  882. int flgs = 0;
  883. #ifdef RT_USING_USERSPACE
  884. int ret = -1;
  885. void *kmem = RT_NULL;
  886. #endif
  887. flgs = netflags_muslc_2_lwip(flags);
  888. #ifdef RT_USING_USERSPACE
  889. if (!size)
  890. return -1;
  891. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)dataptr, size))
  892. return -1;
  893. kmem = kmem_get(size);
  894. if (!kmem)
  895. return -1;
  896. lwp_data_get(&lwp_self()->mmu_info, kmem, (void *)dataptr, size);
  897. if (to)
  898. {
  899. struct sockaddr sa;
  900. sockaddr_tolwip(to, &sa);
  901. ret = sendto(socket, kmem, size, flgs, &sa, tolen);
  902. }
  903. else
  904. ret = sendto(socket, kmem, size, flgs, NULL, tolen);
  905. kmem_put(kmem);
  906. return ret;
  907. #else
  908. if (to)
  909. {
  910. struct sockaddr sa;
  911. sockaddr_tolwip(to, &sa);
  912. return sendto(socket, dataptr, size, flgs, &sa, tolen);
  913. }
  914. return sendto(socket, dataptr, size, flgs, NULL, tolen);
  915. #endif
  916. }
  917. int sys_send(int socket, const void *dataptr, size_t size, int flags)
  918. {
  919. int flgs = 0;
  920. flgs = netflags_muslc_2_lwip(flags);
  921. return sendto(socket, dataptr, size, flgs, NULL, 0);
  922. }
  923. int sys_socket(int domain, int type, int protocol)
  924. {
  925. /* not support SOCK_CLOEXEC type */
  926. if (type & SOCK_CLOEXEC) type &= ~SOCK_CLOEXEC;
  927. return socket(domain, type, protocol);
  928. }
  929. int sys_closesocket(int socket)
  930. {
  931. return closesocket(socket);
  932. }
  933. rt_thread_t sys_thread_find(char *name)
  934. {
  935. return rt_thread_find(name);
  936. }
  937. rt_tick_t sys_tick_get(void)
  938. {
  939. return rt_tick_get();
  940. }
  941. rt_err_t sys_thread_mdelay(rt_int32_t ms)
  942. {
  943. return rt_thread_mdelay(ms);
  944. }
  945. void sys_sighandler_set(int sig, lwp_sighandler_t func)
  946. {
  947. lwp_sighandler_set(sig, func);
  948. }
  949. int sys_sigprocmask(const lwp_sigset_t *sigset, lwp_sigset_t *oset)
  950. {
  951. return lwp_sigprocmask(sigset, oset);
  952. }
  953. int sys_thread_kill(rt_thread_t thread, int sig)
  954. {
  955. return lwp_thread_kill(thread, sig);
  956. }
  957. void sys_thread_sighandler_set(int sig, lwp_sighandler_t func)
  958. {
  959. lwp_thread_sighandler_set(sig, func);
  960. }
  961. int sys_thread_sigprocmask(const lwp_sigset_t *sigset, lwp_sigset_t *oset)
  962. {
  963. return lwp_thread_sigprocmask(sigset, oset);
  964. }
  965. int32_t sys_waitpid(int32_t pid, int *status, int options)
  966. {
  967. return waitpid(pid, status, options);
  968. }
  969. #if defined(RT_USING_SAL) && defined(SAL_USING_POSIX)
  970. struct musl_addrinfo
  971. {
  972. int ai_flags;
  973. int ai_family;
  974. int ai_socktype;
  975. int ai_protocol;
  976. socklen_t ai_addrlen;
  977. struct musl_sockaddr *ai_addr;
  978. char *ai_canonname;
  979. struct musl_addrinfo *ai_next;
  980. };
  981. int sys_getaddrinfo(const char *nodename, const char *servname, const struct musl_addrinfo *hints, struct musl_addrinfo *res)
  982. {
  983. int ret = -1;
  984. struct addrinfo *k_res = NULL;
  985. char *k_nodename = NULL;
  986. char *k_servname = NULL;
  987. struct addrinfo *k_hints = NULL;
  988. LOG_I("syscall: getaddrinfo");
  989. if (nodename)
  990. {
  991. k_nodename = rt_strdup(nodename);
  992. if (!k_nodename) goto exit;
  993. }
  994. if (servname)
  995. {
  996. k_servname = rt_strdup(servname);
  997. if (!k_servname)
  998. {
  999. goto exit;
  1000. }
  1001. }
  1002. if (hints)
  1003. {
  1004. k_hints = (struct addrinfo*) rt_malloc(sizeof *hints);
  1005. if (!k_hints)
  1006. {
  1007. goto exit;
  1008. }
  1009. rt_memset(k_hints, 0x0, sizeof(struct addrinfo));
  1010. k_hints->ai_flags = hints->ai_flags;
  1011. k_hints->ai_family = hints->ai_family;
  1012. k_hints->ai_socktype = hints->ai_socktype;
  1013. k_hints->ai_protocol = hints->ai_protocol;
  1014. k_hints->ai_addrlen = hints->ai_addrlen;
  1015. }
  1016. ret = sal_getaddrinfo(k_nodename, k_servname, k_hints, &k_res);
  1017. if (ret == 0)
  1018. {
  1019. /* set sockaddr */
  1020. sockaddr_tomusl(k_res->ai_addr, res->ai_addr);
  1021. res->ai_addrlen = k_res->ai_addrlen;
  1022. /* set up addrinfo */
  1023. res->ai_family = k_res->ai_family;
  1024. res->ai_flags = k_res->ai_flags;
  1025. if (hints != NULL)
  1026. {
  1027. /* copy socktype & protocol from hints if specified */
  1028. res->ai_socktype = hints->ai_socktype;
  1029. res->ai_protocol = hints->ai_protocol;
  1030. }
  1031. sal_freeaddrinfo(k_res);
  1032. k_res = NULL;
  1033. }
  1034. exit:
  1035. if (k_nodename)
  1036. {
  1037. rt_free(k_nodename);
  1038. }
  1039. if (k_servname)
  1040. {
  1041. rt_free(k_servname);
  1042. }
  1043. if (k_hints)
  1044. {
  1045. rt_free(k_hints);
  1046. }
  1047. return ret;
  1048. }
  1049. #define HOSTENT_BUFSZ 512
  1050. int sys_gethostbyname2_r(const char *name, int af, struct hostent *ret,
  1051. char *buf, size_t buflen,
  1052. struct hostent **result, int *err)
  1053. {
  1054. int sal_ret, sal_err;
  1055. struct hostent sal_he;
  1056. struct hostent *sal_result = NULL;
  1057. char *sal_buf = NULL;
  1058. char *k_name = NULL;
  1059. if (result == NULL)
  1060. {
  1061. /* not all arguments given */
  1062. *err = EINVAL;
  1063. return -1;
  1064. }
  1065. if ((name == NULL) || (ret == NULL) || (buf == NULL))
  1066. {
  1067. /* not all arguments given */
  1068. *err = EINVAL;
  1069. return -1;
  1070. }
  1071. *result = ret;
  1072. sal_buf = (char *)malloc (HOSTENT_BUFSZ);
  1073. if (sal_buf == NULL)
  1074. {
  1075. goto __exit;
  1076. }
  1077. k_name = rt_strdup(name);
  1078. if (k_name == NULL)
  1079. {
  1080. goto __exit;
  1081. }
  1082. /* get host by name in SAL */
  1083. sal_ret = sal_gethostbyname_r(k_name, &sal_he, sal_buf, HOSTENT_BUFSZ, &sal_result, &sal_err);
  1084. if (sal_ret == 0)
  1085. {
  1086. int index, cnt;
  1087. char *ptr = buf;
  1088. /* get counter */
  1089. index = 0;
  1090. while (sal_he.h_addr_list[index] != NULL) index ++;
  1091. cnt = index + 1;
  1092. /* update user space hostent */
  1093. ret->h_addrtype = sal_he.h_addrtype;
  1094. ret->h_length = sal_he.h_length;
  1095. rt_strncpy(ptr, k_name, buflen - (ptr - buf));
  1096. ret->h_name = ptr;
  1097. ptr += rt_strlen(k_name);
  1098. ret->h_addr_list = (char**)ptr;
  1099. ptr += cnt * sizeof(char*);
  1100. index = 0;
  1101. while (sal_he.h_addr_list[index] != NULL)
  1102. {
  1103. ret->h_addr_list[index] = ptr;
  1104. rt_memcpy(ptr, sal_he.h_addr_list[index], sal_he.h_length);
  1105. ptr += sal_he.h_length;
  1106. index ++;
  1107. }
  1108. ret->h_addr_list[index] = NULL;
  1109. }
  1110. __exit:
  1111. /* release buffer */
  1112. if (sal_buf) free(sal_buf);
  1113. if (k_name) free(k_name);
  1114. return 0;
  1115. }
  1116. #endif
  1117. char *sys_getcwd(char *buf, size_t size)
  1118. {
  1119. return getcwd(buf, size);
  1120. }
  1121. int sys_chdir(const char *path)
  1122. {
  1123. return chdir(path);
  1124. }
  1125. int sys_mkdir(const char *path, mode_t mode)
  1126. {
  1127. return mkdir(path, mode);
  1128. }
  1129. int sys_rmdir(const char *path)
  1130. {
  1131. return unlink(path);
  1132. }
  1133. typedef uint64_t ino_t;
  1134. struct libc_dirent {
  1135. ino_t d_ino;
  1136. off_t d_off;
  1137. unsigned short d_reclen;
  1138. unsigned char d_type;
  1139. char d_name[256];
  1140. };
  1141. int sys_getdents(int fd, struct libc_dirent *dirp, size_t nbytes)
  1142. {
  1143. int ret;
  1144. struct dfs_fd *dfs_fd;
  1145. size_t cnt = (nbytes / sizeof(struct libc_dirent));
  1146. size_t rtt_nbytes;
  1147. struct dirent *rtt_dirp;
  1148. if (cnt == 0)
  1149. {
  1150. return 0;
  1151. }
  1152. rtt_nbytes = cnt * sizeof(struct dirent);
  1153. rtt_dirp = (struct dirent*)rt_malloc(rtt_nbytes);
  1154. if (!rtt_dirp)
  1155. {
  1156. return 0;
  1157. }
  1158. dfs_fd = fd_get(fd);
  1159. ret = dfs_file_getdents(dfs_fd, rtt_dirp, nbytes);
  1160. fd_put(dfs_fd);
  1161. if (ret)
  1162. {
  1163. size_t i;
  1164. cnt = ret / sizeof(struct dirent);
  1165. for (i = 0; i < cnt; i++)
  1166. {
  1167. dirp[i].d_ino = 0;
  1168. dirp[i].d_off = 0;
  1169. dirp[i].d_type = rtt_dirp[i].d_type;
  1170. dirp[i].d_reclen = sizeof(struct libc_dirent);
  1171. strcpy(dirp[i].d_name, rtt_dirp[i].d_name);
  1172. }
  1173. ret = cnt * sizeof(struct libc_dirent);
  1174. }
  1175. rt_free(rtt_dirp);
  1176. return ret;
  1177. }
  1178. rt_err_t sys_get_errno(void)
  1179. {
  1180. return rt_get_errno();
  1181. }
  1182. void sys_set_thread_area(void *p)
  1183. {
  1184. lwp_set_thread_area(p);
  1185. }
  1186. long sys_set_tid_address(int *tidptr)
  1187. {
  1188. return 0;
  1189. }
  1190. int sys_access(const char *filename, int mode)
  1191. {
  1192. int ret;
  1193. #ifdef RT_USING_USERSPACE
  1194. rt_size_t len;
  1195. char *kname;
  1196. if (!lwp_data_access_ok(&lwp_self()->mmu_info, (void*)filename, 1))
  1197. return -1;
  1198. len = rt_strlen(filename);
  1199. if (!len)
  1200. return -1;
  1201. kname = (char *)kmem_get(len + 1);
  1202. if (!kname)
  1203. return -1;
  1204. lwp_data_get(&lwp_self()->mmu_info, kname, (void *)filename, len + 1);
  1205. ret = open(kname, mode, 0);
  1206. kmem_put(kname);
  1207. #else
  1208. ret = open(filename, mode, 0);
  1209. #endif
  1210. if (ret >= 0)
  1211. {
  1212. close(ret);
  1213. }
  1214. return (ret >= 0)? 0: ret;
  1215. }
  1216. const static void* func_table[] =
  1217. {
  1218. (void*)sys_exit, /* 01 */
  1219. (void*)sys_read,
  1220. (void*)sys_write,
  1221. (void*)sys_lseek,
  1222. (void*)sys_open, /* 05 */
  1223. (void*)sys_close,
  1224. (void*)sys_ioctl,
  1225. (void*)sys_fstat,
  1226. (void*)sys_poll,
  1227. (void*)sys_nanosleep, /* 10 */
  1228. (void*)sys_gettimeofday,
  1229. (void*)sys_settimeofday,
  1230. (void*)sys_exec,
  1231. (void*)sys_kill,
  1232. (void*)sys_getpid, /* 15 */
  1233. (void*)sys_getpriority,
  1234. (void*)sys_setpriority,
  1235. (void*)sys_sem_create,
  1236. (void*)sys_sem_delete,
  1237. (void*)sys_sem_take, /* 20 */
  1238. (void*)sys_sem_release,
  1239. (void*)sys_mutex_create,
  1240. (void*)sys_mutex_delete,
  1241. (void*)sys_mutex_take,
  1242. (void*)sys_mutex_release, /* 25 */
  1243. (void*)sys_event_create,
  1244. (void*)sys_event_delete,
  1245. (void*)sys_event_send,
  1246. (void*)sys_event_recv,
  1247. (void*)sys_mb_create, /* 30 */
  1248. (void*)sys_mb_delete,
  1249. (void*)sys_mb_send,
  1250. (void*)sys_mb_send_wait,
  1251. (void*)sys_mb_recv,
  1252. (void*)sys_mq_create, /* 35 */
  1253. (void*)sys_mq_delete,
  1254. (void*)sys_mq_send,
  1255. (void*)sys_mq_urgent,
  1256. (void*)sys_mq_recv,
  1257. (void*)sys_thread_create, /* 40 */
  1258. (void*)sys_thread_delete,
  1259. (void*)sys_thread_startup,
  1260. (void*)sys_thread_self,
  1261. (void*)sys_channel_open,
  1262. (void*)sys_channel_close, /* 45 */
  1263. (void*)sys_channel_send,
  1264. (void*)sys_channel_send_recv_timeout,
  1265. (void*)sys_channel_reply,
  1266. (void*)sys_channel_recv_timeout,
  1267. (void*)sys_enter_critical, /* 50 */
  1268. (void*)sys_exit_critical,
  1269. SYSCALL_USPACE(sys_brk),
  1270. SYSCALL_USPACE(sys_mmap2),
  1271. SYSCALL_USPACE(sys_munmap),
  1272. SYSCALL_USPACE(sys_shmget),
  1273. SYSCALL_USPACE(sys_shmrm),
  1274. SYSCALL_USPACE(sys_shmat),
  1275. SYSCALL_USPACE(sys_shmdt),
  1276. (void *)sys_device_init,
  1277. (void *)sys_device_register,
  1278. (void *)sys_device_control,
  1279. (void *)sys_device_find,
  1280. (void *)sys_device_open,
  1281. (void *)sys_device_close,
  1282. (void *)sys_device_read,
  1283. (void *)sys_device_write,
  1284. (void *)sys_stat,
  1285. (void *)sys_thread_find,
  1286. SYSCALL_NET(sys_accept),
  1287. SYSCALL_NET(sys_bind),
  1288. SYSCALL_NET(sys_shutdown),
  1289. SYSCALL_NET(sys_getpeername),
  1290. SYSCALL_NET(sys_getsockname),
  1291. SYSCALL_NET(sys_getsockopt),
  1292. SYSCALL_NET(sys_setsockopt),
  1293. SYSCALL_NET(sys_connect),
  1294. SYSCALL_NET(sys_listen),
  1295. SYSCALL_NET(sys_recv),
  1296. SYSCALL_NET(sys_recvfrom),
  1297. SYSCALL_NET(sys_send),
  1298. SYSCALL_NET(sys_sendto),
  1299. SYSCALL_NET(sys_socket),
  1300. SYSCALL_NET(sys_closesocket),
  1301. SYSCALL_NET(sys_getaddrinfo),
  1302. SYSCALL_NET(sys_gethostbyname2_r),
  1303. (void *)sys_notimpl, //(void *)network,
  1304. (void *)sys_notimpl, //(void *)network,
  1305. (void *)sys_notimpl, //(void *)network,
  1306. (void *)sys_notimpl, //(void *)network,
  1307. (void *)sys_notimpl, //(void *)network,
  1308. (void *)sys_notimpl, //(void *)network,
  1309. (void *)sys_notimpl, //(void *)network,
  1310. (void *)sys_notimpl, //(void *)network,
  1311. #ifdef RT_USING_DFS
  1312. (void *)sys_select,
  1313. #else
  1314. (void *)sys_notimpl,
  1315. #endif
  1316. (void *)sys_notimpl, //(void *)sys_hw_interrupt_disable,
  1317. (void *)sys_notimpl, //(void *)sys_hw_interrupt_enable,
  1318. (void *)sys_tick_get,
  1319. (void *)sys_exit_group,
  1320. (void *)sys_notimpl, //(void *)rt_delayed_work_init,
  1321. (void *)sys_notimpl, //(void *)rt_work_submit,
  1322. (void *)sys_notimpl, //(void *)rt_wqueue_wakeup,
  1323. (void *)sys_thread_mdelay,
  1324. (void*)sys_sighandler_set,
  1325. (void*)sys_sigprocmask,
  1326. (void*)sys_thread_kill,
  1327. (void*)sys_thread_sighandler_set,
  1328. (void*)sys_thread_sigprocmask,
  1329. (void*)sys_notimpl,
  1330. (void*)sys_notimpl,
  1331. (void*)sys_waitpid,
  1332. (void *)sys_timer_create,
  1333. (void *)sys_timer_delete,
  1334. (void *)sys_timer_start,
  1335. (void *)sys_timer_stop,
  1336. (void *)sys_timer_control,
  1337. (void *)sys_getcwd,
  1338. (void *)sys_chdir,
  1339. (void *)sys_unlink,
  1340. (void *)sys_mkdir,
  1341. (void *)sys_rmdir,
  1342. (void *)sys_getdents,
  1343. (void *)sys_get_errno,
  1344. (void *)sys_set_thread_area,
  1345. (void *)sys_set_tid_address,
  1346. (void *)sys_access,
  1347. };
  1348. const void *lwp_get_sys_api(rt_uint32_t number)
  1349. {
  1350. const void *func = (const void*)sys_notimpl;
  1351. if (number == 0xff)
  1352. {
  1353. func = (void *)sys_log;
  1354. }
  1355. else
  1356. {
  1357. number -= 1;
  1358. if (number < sizeof(func_table)/sizeof(func_table[0]))
  1359. {
  1360. func = func_table[number];
  1361. }
  1362. }
  1363. return func;
  1364. }