binding.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. #include <assert.h>
  2. #include <bare.h>
  3. #include <js.h>
  4. #include <stdlib.h>
  5. #include <utf.h>
  6. #include <uv.h>
  7. static uv_rwlock_t bare_os_env_lock;
  8. static uv_once_t bare_os_env_lock_guard = UV_ONCE_INIT;
  9. static void
  10. bare_os_env_on_lock_init (void) {
  11. int err = uv_rwlock_init(&bare_os_env_lock);
  12. assert(err == 0);
  13. }
  14. static js_value_t *
  15. bare_os_type (js_env_t *env, js_callback_info_t *info) {
  16. int err;
  17. uv_utsname_t buffer;
  18. err = uv_os_uname(&buffer);
  19. if (err < 0) {
  20. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  21. return NULL;
  22. }
  23. js_value_t *result;
  24. err = js_create_string_utf8(env, (utf8_t *) buffer.sysname, -1, &result);
  25. if (err < 0) return NULL;
  26. return result;
  27. }
  28. static js_value_t *
  29. bare_os_version (js_env_t *env, js_callback_info_t *info) {
  30. int err;
  31. uv_utsname_t buffer;
  32. err = uv_os_uname(&buffer);
  33. if (err < 0) {
  34. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  35. return NULL;
  36. }
  37. js_value_t *result;
  38. err = js_create_string_utf8(env, (utf8_t *) buffer.version, -1, &result);
  39. if (err < 0) return NULL;
  40. return result;
  41. }
  42. static js_value_t *
  43. bare_os_release (js_env_t *env, js_callback_info_t *info) {
  44. int err;
  45. uv_utsname_t buffer;
  46. err = uv_os_uname(&buffer);
  47. if (err < 0) {
  48. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  49. return NULL;
  50. }
  51. js_value_t *result;
  52. err = js_create_string_utf8(env, (utf8_t *) buffer.release, -1, &result);
  53. if (err < 0) return NULL;
  54. return result;
  55. }
  56. static js_value_t *
  57. bare_os_machine (js_env_t *env, js_callback_info_t *info) {
  58. int err;
  59. uv_utsname_t buffer;
  60. err = uv_os_uname(&buffer);
  61. if (err < 0) {
  62. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  63. return NULL;
  64. }
  65. js_value_t *result;
  66. err = js_create_string_utf8(env, (utf8_t *) buffer.machine, -1, &result);
  67. if (err < 0) return NULL;
  68. return result;
  69. }
  70. static js_value_t *
  71. bare_os_exec_path (js_env_t *env, js_callback_info_t *info) {
  72. int err;
  73. size_t len = 4096;
  74. char exec_path[4096];
  75. err = uv_exepath(exec_path, &len);
  76. if (err < 0) {
  77. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  78. return NULL;
  79. }
  80. js_value_t *result;
  81. err = js_create_string_utf8(env, (utf8_t *) exec_path, len, &result);
  82. if (err < 0) return NULL;
  83. return result;
  84. }
  85. static js_value_t *
  86. bare_os_pid (js_env_t *env, js_callback_info_t *info) {
  87. int err;
  88. js_value_t *result;
  89. err = js_create_uint32(env, uv_os_getpid(), &result);
  90. if (err < 0) return NULL;
  91. return result;
  92. }
  93. static js_value_t *
  94. bare_os_ppid (js_env_t *env, js_callback_info_t *info) {
  95. int err;
  96. js_value_t *result;
  97. err = js_create_uint32(env, uv_os_getppid(), &result);
  98. if (err < 0) return NULL;
  99. return result;
  100. }
  101. static js_value_t *
  102. bare_os_cwd (js_env_t *env, js_callback_info_t *info) {
  103. int err;
  104. size_t len = 4096;
  105. char cwd[4096];
  106. err = uv_cwd(cwd, &len);
  107. if (err < 0) {
  108. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  109. return NULL;
  110. }
  111. js_value_t *result;
  112. err = js_create_string_utf8(env, (utf8_t *) cwd, len, &result);
  113. if (err < 0) return NULL;
  114. return result;
  115. }
  116. static js_value_t *
  117. bare_os_chdir (js_env_t *env, js_callback_info_t *info) {
  118. int err;
  119. size_t argc = 1;
  120. js_value_t *argv[1];
  121. err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
  122. assert(err == 0);
  123. assert(argc == 1);
  124. utf8_t dir[4096];
  125. err = js_get_value_string_utf8(env, argv[0], dir, 4096, NULL);
  126. assert(err == 0);
  127. err = uv_chdir((char *) dir);
  128. if (err < 0) {
  129. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  130. return NULL;
  131. }
  132. return NULL;
  133. }
  134. static js_value_t *
  135. bare_os_tmpdir (js_env_t *env, js_callback_info_t *info) {
  136. int err;
  137. size_t len = 4096;
  138. char tmpdir[4096];
  139. err = uv_os_tmpdir(tmpdir, &len);
  140. if (err < 0) {
  141. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  142. return NULL;
  143. }
  144. js_value_t *result;
  145. err = js_create_string_utf8(env, (utf8_t *) tmpdir, len, &result);
  146. if (err < 0) return NULL;
  147. return result;
  148. }
  149. static js_value_t *
  150. bare_os_homedir (js_env_t *env, js_callback_info_t *info) {
  151. int err;
  152. size_t len = 4096;
  153. char homedir[4096];
  154. err = uv_os_homedir(homedir, &len);
  155. if (err < 0) {
  156. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  157. return NULL;
  158. }
  159. js_value_t *result;
  160. err = js_create_string_utf8(env, (utf8_t *) homedir, len, &result);
  161. if (err < 0) return NULL;
  162. return result;
  163. }
  164. static js_value_t *
  165. bare_os_kill (js_env_t *env, js_callback_info_t *info) {
  166. int err;
  167. size_t argc = 2;
  168. js_value_t *argv[2];
  169. err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
  170. assert(err == 0);
  171. assert(argc == 2);
  172. uint32_t pid;
  173. err = js_get_value_uint32(env, argv[0], &pid);
  174. assert(err == 0);
  175. uint32_t signum;
  176. err = js_get_value_uint32(env, argv[1], &signum);
  177. assert(err == 0);
  178. err = uv_kill(pid, signum);
  179. if (err < 0) {
  180. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  181. return NULL;
  182. }
  183. return NULL;
  184. }
  185. static js_value_t *
  186. bare_os_get_process_title (js_env_t *env, js_callback_info_t *info) {
  187. int err;
  188. char title[256];
  189. err = uv_get_process_title(title, 256);
  190. if (err < 0) {
  191. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  192. return NULL;
  193. }
  194. js_value_t *result;
  195. err = js_create_string_utf8(env, (utf8_t *) title, -1, &result);
  196. assert(err == 0);
  197. return result;
  198. }
  199. static js_value_t *
  200. bare_os_set_process_title (js_env_t *env, js_callback_info_t *info) {
  201. int err;
  202. size_t argc = 1;
  203. js_value_t *argv[1];
  204. err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
  205. assert(err == 0);
  206. assert(argc == 1);
  207. utf8_t data[256];
  208. err = js_get_value_string_utf8(env, argv[0], data, 256, NULL);
  209. assert(err == 0);
  210. err = uv_set_process_title((char *) data);
  211. assert(err == 0);
  212. return NULL;
  213. }
  214. static js_value_t *
  215. bare_os_get_env_keys (js_env_t *env, js_callback_info_t *info) {
  216. int err;
  217. uv_env_item_t *items;
  218. int len;
  219. uv_rwlock_rdlock(&bare_os_env_lock);
  220. err = uv_os_environ(&items, &len);
  221. uv_rwlock_rdunlock(&bare_os_env_lock);
  222. if (err < 0) {
  223. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  224. return NULL;
  225. }
  226. js_value_t *result;
  227. err = js_create_array_with_length(env, len, &result);
  228. assert(err == 0);
  229. for (int i = 0; i < len; i++) {
  230. uv_env_item_t *item = &items[i];
  231. js_value_t *val;
  232. err = js_create_string_utf8(env, (utf8_t *) item->name, -1, &val);
  233. assert(err == 0);
  234. err = js_set_element(env, result, i, val);
  235. assert(err == 0);
  236. }
  237. uv_os_free_environ(items, len);
  238. return result;
  239. }
  240. static js_value_t *
  241. bare_os_get_env (js_env_t *env, js_callback_info_t *info) {
  242. int err;
  243. size_t argc = 1;
  244. js_value_t *argv[1];
  245. err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
  246. assert(err == 0);
  247. assert(argc == 1);
  248. size_t name_len;
  249. err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
  250. assert(err == 0);
  251. name_len += 1 /* NULL */;
  252. utf8_t *name = malloc(name_len);
  253. err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
  254. assert(err == 0);
  255. uv_rwlock_rdlock(&bare_os_env_lock);
  256. size_t value_len = 256;
  257. char *value = malloc(value_len);
  258. err = uv_os_getenv((char *) name, value, &value_len);
  259. js_value_t *result;
  260. if (err == UV_ENOENT) {
  261. err = js_get_undefined(env, &result);
  262. assert(err == 0);
  263. } else {
  264. if (err == UV_ENOBUFS) {
  265. value = realloc(value, value_len);
  266. err = uv_os_getenv((char *) name, value, &value_len);
  267. assert(err == 0);
  268. } else if (err < 0) {
  269. uv_rwlock_rdunlock(&bare_os_env_lock);
  270. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  271. free(name);
  272. return NULL;
  273. }
  274. err = js_create_string_utf8(env, (utf8_t *) value, value_len, &result);
  275. assert(err == 0);
  276. }
  277. uv_rwlock_rdunlock(&bare_os_env_lock);
  278. free(name);
  279. free(value);
  280. return result;
  281. }
  282. static js_value_t *
  283. bare_os_has_env (js_env_t *env, js_callback_info_t *info) {
  284. int err;
  285. size_t argc = 1;
  286. js_value_t *argv[1];
  287. err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
  288. assert(err == 0);
  289. assert(argc == 1);
  290. size_t name_len;
  291. err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
  292. assert(err == 0);
  293. utf8_t *name = malloc(++name_len);
  294. err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
  295. assert(err == 0);
  296. uv_rwlock_rdlock(&bare_os_env_lock);
  297. size_t value_len = 1;
  298. char value[1];
  299. err = uv_os_getenv((char *) name, value, &value_len);
  300. uv_rwlock_rdunlock(&bare_os_env_lock);
  301. if (err != 0 && err != UV_ENOENT && err != UV_ENOBUFS) {
  302. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  303. free(name);
  304. return NULL;
  305. }
  306. free(name);
  307. js_value_t *result;
  308. err = js_get_boolean(env, err != UV_ENOENT, &result);
  309. assert(err == 0);
  310. return result;
  311. }
  312. static js_value_t *
  313. bare_os_set_env (js_env_t *env, js_callback_info_t *info) {
  314. int err;
  315. size_t argc = 2;
  316. js_value_t *argv[2];
  317. err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
  318. assert(err == 0);
  319. assert(argc == 2);
  320. size_t name_len;
  321. err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
  322. assert(err == 0);
  323. utf8_t *name = malloc(++name_len);
  324. err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
  325. assert(err == 0);
  326. size_t value_len;
  327. err = js_get_value_string_utf8(env, argv[1], NULL, 0, &value_len);
  328. assert(err == 0);
  329. utf8_t *value = malloc(++value_len);
  330. err = js_get_value_string_utf8(env, argv[1], value, value_len, &value_len);
  331. assert(err == 0);
  332. uv_rwlock_wrlock(&bare_os_env_lock);
  333. err = uv_os_setenv((char *) name, (char *) value);
  334. uv_rwlock_wrunlock(&bare_os_env_lock);
  335. if (err < 0) {
  336. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  337. free(name);
  338. free(value);
  339. return NULL;
  340. }
  341. free(name);
  342. free(value);
  343. return NULL;
  344. }
  345. static js_value_t *
  346. bare_os_unset_env (js_env_t *env, js_callback_info_t *info) {
  347. int err;
  348. size_t argc = 1;
  349. js_value_t *argv[1];
  350. err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
  351. assert(err == 0);
  352. assert(argc == 1);
  353. size_t name_len;
  354. err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
  355. assert(err == 0);
  356. utf8_t *name = malloc(++name_len);
  357. err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
  358. assert(err == 0);
  359. uv_rwlock_wrlock(&bare_os_env_lock);
  360. err = uv_os_unsetenv((char *) name);
  361. uv_rwlock_wrunlock(&bare_os_env_lock);
  362. if (err < 0) {
  363. js_throw_error(env, uv_err_name(err), uv_strerror(err));
  364. free(name);
  365. return NULL;
  366. }
  367. free(name);
  368. return NULL;
  369. }
  370. static js_value_t *
  371. init (js_env_t *env, js_value_t *exports) {
  372. uv_once(&bare_os_env_lock_guard, bare_os_env_on_lock_init);
  373. int err;
  374. #define V(name, str) \
  375. { \
  376. js_value_t *val; \
  377. err = js_create_string_utf8(env, (utf8_t *) str, -1, &val); \
  378. assert(err == 0); \
  379. err = js_set_named_property(env, exports, name, val); \
  380. assert(err == 0); \
  381. }
  382. V("platform", BARE_PLATFORM);
  383. V("arch", BARE_ARCH);
  384. #undef V
  385. #define V(name, fn) \
  386. { \
  387. js_value_t *val; \
  388. err = js_create_function(env, name, -1, fn, NULL, &val); \
  389. assert(err == 0); \
  390. err = js_set_named_property(env, exports, name, val); \
  391. assert(err == 0); \
  392. }
  393. V("type", bare_os_type);
  394. V("version", bare_os_version);
  395. V("release", bare_os_release);
  396. V("machine", bare_os_machine);
  397. V("execPath", bare_os_exec_path);
  398. V("pid", bare_os_pid);
  399. V("ppid", bare_os_ppid);
  400. V("cwd", bare_os_cwd);
  401. V("chdir", bare_os_chdir);
  402. V("tmpdir", bare_os_tmpdir);
  403. V("homedir", bare_os_homedir);
  404. V("kill", bare_os_kill);
  405. V("getProcessTitle", bare_os_get_process_title);
  406. V("setProcessTitle", bare_os_set_process_title);
  407. V("getEnvKeys", bare_os_get_env_keys)
  408. V("getEnv", bare_os_get_env)
  409. V("hasEnv", bare_os_get_env)
  410. V("setEnv", bare_os_set_env)
  411. V("unsetEnv", bare_os_unset_env)
  412. #undef V
  413. js_value_t *signals;
  414. err = js_create_object(env, &signals);
  415. assert(err == 0);
  416. err = js_set_named_property(env, exports, "signals", signals);
  417. assert(err == 0);
  418. #define V(name) \
  419. { \
  420. js_value_t *val; \
  421. err = js_create_uint32(env, name, &val); \
  422. assert(err == 0); \
  423. err = js_set_named_property(env, signals, #name, val); \
  424. assert(err == 0); \
  425. }
  426. #ifdef SIGHUP
  427. V(SIGHUP);
  428. #endif
  429. #ifdef SIGINT
  430. V(SIGINT);
  431. #endif
  432. #ifdef SIGQUIT
  433. V(SIGQUIT);
  434. #endif
  435. #ifdef SIGILL
  436. V(SIGILL);
  437. #endif
  438. #ifdef SIGTRAP
  439. V(SIGTRAP);
  440. #endif
  441. #ifdef SIGABRT
  442. V(SIGABRT);
  443. #endif
  444. #ifdef SIGIOT
  445. V(SIGIOT);
  446. #endif
  447. #ifdef SIGBUS
  448. V(SIGBUS);
  449. #endif
  450. #ifdef SIGFPE
  451. V(SIGFPE);
  452. #endif
  453. #ifdef SIGKILL
  454. V(SIGKILL);
  455. #endif
  456. #ifdef SIGUSR1
  457. V(SIGUSR1);
  458. #endif
  459. #ifdef SIGSEGV
  460. V(SIGSEGV);
  461. #endif
  462. #ifdef SIGUSR2
  463. V(SIGUSR2);
  464. #endif
  465. #ifdef SIGPIPE
  466. V(SIGPIPE);
  467. #endif
  468. #ifdef SIGALRM
  469. V(SIGALRM);
  470. #endif
  471. V(SIGTERM);
  472. #ifdef SIGCHLD
  473. V(SIGCHLD);
  474. #endif
  475. #ifdef SIGSTKFLT
  476. V(SIGSTKFLT);
  477. #endif
  478. #ifdef SIGCONT
  479. V(SIGCONT);
  480. #endif
  481. #ifdef SIGSTOP
  482. V(SIGSTOP);
  483. #endif
  484. #ifdef SIGTSTP
  485. V(SIGTSTP);
  486. #endif
  487. #ifdef SIGBREAK
  488. V(SIGBREAK);
  489. #endif
  490. #ifdef SIGTTIN
  491. V(SIGTTIN);
  492. #endif
  493. #ifdef SIGTTOU
  494. V(SIGTTOU);
  495. #endif
  496. #ifdef SIGURG
  497. V(SIGURG);
  498. #endif
  499. #ifdef SIGXCPU
  500. V(SIGXCPU);
  501. #endif
  502. #ifdef SIGXFSZ
  503. V(SIGXFSZ);
  504. #endif
  505. #ifdef SIGVTALRM
  506. V(SIGVTALRM);
  507. #endif
  508. #ifdef SIGPROF
  509. V(SIGPROF);
  510. #endif
  511. #ifdef SIGWINCH
  512. V(SIGWINCH);
  513. #endif
  514. #ifdef SIGIO
  515. V(SIGIO);
  516. #endif
  517. #ifdef SIGPOLL
  518. V(SIGPOLL);
  519. #endif
  520. #ifdef SIGLOST
  521. V(SIGLOST);
  522. #endif
  523. #ifdef SIGPWR
  524. V(SIGPWR);
  525. #endif
  526. #ifdef SIGINFO
  527. V(SIGINFO);
  528. #endif
  529. #ifdef SIGSYS
  530. V(SIGSYS);
  531. #endif
  532. #ifdef SIGUNUSED
  533. V(SIGUNUSED);
  534. #endif
  535. #undef V
  536. js_value_t *errnos;
  537. err = js_create_object(env, &errnos);
  538. assert(err == 0);
  539. err = js_set_named_property(env, exports, "errnos", errnos);
  540. assert(err == 0);
  541. #define V(name, msg) \
  542. { \
  543. js_value_t *val; \
  544. err = js_create_int32(env, UV_##name, &val); \
  545. assert(err == 0); \
  546. err = js_set_named_property(env, errnos, #name, val); \
  547. assert(err == 0); \
  548. }
  549. UV_ERRNO_MAP(V);
  550. #undef V
  551. return exports;
  552. }
  553. BARE_MODULE(bare_os, init)