PageRenderTime 103ms CodeModel.GetById 11ms RepoModel.GetById 3ms app.codeStats 1ms

/process.c

https://github.com/vuxuandung/ruby
C | 6877 lines | 4638 code | 699 blank | 1540 comment | 1142 complexity | 669245bc685590d49ec357675d92d3c9 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0, 0BSD

Large files files are truncated, but you can click here to view the full file

  1. /**********************************************************************
  2. process.c -
  3. $Author$
  4. created at: Tue Aug 10 14:30:50 JST 1993
  5. Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
  7. Copyright (C) 2000 Information-technology Promotion Agency, Japan
  8. **********************************************************************/
  9. #include "ruby/ruby.h"
  10. #include "ruby/io.h"
  11. #include "ruby/thread.h"
  12. #include "ruby/util.h"
  13. #include "internal.h"
  14. #include "vm_core.h"
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <signal.h>
  18. #ifdef HAVE_STDLIB_H
  19. #include <stdlib.h>
  20. #endif
  21. #ifdef HAVE_UNISTD_H
  22. #include <unistd.h>
  23. #endif
  24. #ifdef HAVE_FCNTL_H
  25. #include <fcntl.h>
  26. #endif
  27. #ifdef HAVE_PROCESS_H
  28. #include <process.h>
  29. #endif
  30. #include <time.h>
  31. #include <ctype.h>
  32. #ifndef EXIT_SUCCESS
  33. #define EXIT_SUCCESS 0
  34. #endif
  35. #ifndef EXIT_FAILURE
  36. #define EXIT_FAILURE 1
  37. #endif
  38. #ifdef HAVE_SYS_WAIT_H
  39. # include <sys/wait.h>
  40. #endif
  41. #ifdef HAVE_SYS_RESOURCE_H
  42. # include <sys/resource.h>
  43. #endif
  44. #ifdef HAVE_SYS_PARAM_H
  45. # include <sys/param.h>
  46. #endif
  47. #ifndef MAXPATHLEN
  48. # define MAXPATHLEN 1024
  49. #endif
  50. #include "ruby/st.h"
  51. #ifdef __EMX__
  52. #undef HAVE_GETPGRP
  53. #endif
  54. #include <sys/stat.h>
  55. #if defined(__native_client__) && defined(NACL_NEWLIB)
  56. # include "nacl/stat.h"
  57. # include "nacl/unistd.h"
  58. #endif
  59. #ifdef HAVE_SYS_TIMES_H
  60. #include <sys/times.h>
  61. #endif
  62. #ifdef HAVE_PWD_H
  63. #include <pwd.h>
  64. #endif
  65. #ifdef HAVE_GRP_H
  66. #include <grp.h>
  67. #endif
  68. #define numberof(array) (int)(sizeof(array)/sizeof((array)[0]))
  69. #if defined(HAVE_TIMES) || defined(_WIN32)
  70. static VALUE rb_cProcessTms;
  71. #endif
  72. #ifndef WIFEXITED
  73. #define WIFEXITED(w) (((w) & 0xff) == 0)
  74. #endif
  75. #ifndef WIFSIGNALED
  76. #define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))
  77. #endif
  78. #ifndef WIFSTOPPED
  79. #define WIFSTOPPED(w) (((w) & 0xff) == 0x7f)
  80. #endif
  81. #ifndef WEXITSTATUS
  82. #define WEXITSTATUS(w) (((w) >> 8) & 0xff)
  83. #endif
  84. #ifndef WTERMSIG
  85. #define WTERMSIG(w) ((w) & 0x7f)
  86. #endif
  87. #ifndef WSTOPSIG
  88. #define WSTOPSIG WEXITSTATUS
  89. #endif
  90. #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
  91. #define HAVE_44BSD_SETUID 1
  92. #define HAVE_44BSD_SETGID 1
  93. #endif
  94. #ifdef __NetBSD__
  95. #undef HAVE_SETRUID
  96. #undef HAVE_SETRGID
  97. #endif
  98. #ifdef BROKEN_SETREUID
  99. #define setreuid ruby_setreuid
  100. int setreuid(rb_uid_t ruid, rb_uid_t euid);
  101. #endif
  102. #ifdef BROKEN_SETREGID
  103. #define setregid ruby_setregid
  104. int setregid(rb_gid_t rgid, rb_gid_t egid);
  105. #endif
  106. #if defined(HAVE_44BSD_SETUID) || defined(__APPLE__)
  107. #if !defined(USE_SETREUID) && !defined(BROKEN_SETREUID)
  108. #define OBSOLETE_SETREUID 1
  109. #endif
  110. #if !defined(USE_SETREGID) && !defined(BROKEN_SETREGID)
  111. #define OBSOLETE_SETREGID 1
  112. #endif
  113. #endif
  114. #define preserving_errno(stmts) \
  115. do {int saved_errno = errno; stmts; errno = saved_errno;} while (0)
  116. static void check_uid_switch(void);
  117. static void check_gid_switch(void);
  118. #if 1
  119. #define p_uid_from_name p_uid_from_name
  120. #define p_gid_from_name p_gid_from_name
  121. #endif
  122. #if defined(HAVE_PWD_H)
  123. # ifdef HAVE_GETPWNAM_R
  124. # define PREPARE_GETPWNAM \
  125. long getpw_buf_len = sysconf(_SC_GETPW_R_SIZE_MAX); \
  126. char *getpw_buf = ALLOCA_N(char, (getpw_buf_len < 0 ? (getpw_buf_len = 4096) : getpw_buf_len));
  127. # define OBJ2UID(id) obj2uid((id), getpw_buf, getpw_buf_len)
  128. static rb_uid_t obj2uid(VALUE id, char *getpw_buf, size_t getpw_buf_len);
  129. # else
  130. # define PREPARE_GETPWNAM /* do nothing */
  131. # define OBJ2UID(id) obj2uid((id))
  132. static rb_uid_t obj2uid(VALUE id);
  133. # endif
  134. #else
  135. # define PREPARE_GETPWNAM /* do nothing */
  136. # define OBJ2UID(id) NUM2UIDT(id)
  137. # ifdef p_uid_from_name
  138. # undef p_uid_from_name
  139. # define p_uid_from_name rb_f_notimplement
  140. # endif
  141. #endif
  142. #if defined(HAVE_GRP_H)
  143. # ifdef HAVE_GETGRNAM_R
  144. # define PREPARE_GETGRNAM \
  145. long getgr_buf_len = sysconf(_SC_GETGR_R_SIZE_MAX); \
  146. char *getgr_buf = ALLOCA_N(char, (getgr_buf_len < 0 ? (getgr_buf_len = 4096) : getgr_buf_len));
  147. # define OBJ2GID(id) obj2gid((id), getgr_buf, getgr_buf_len)
  148. static rb_gid_t obj2gid(VALUE id, char *getgr_buf, size_t getgr_buf_len);
  149. # else
  150. # define PREPARE_GETGRNAM /* do nothing */
  151. # define OBJ2GID(id) obj2gid((id))
  152. static rb_gid_t obj2gid(VALUE id);
  153. # endif
  154. #else
  155. # define PREPARE_GETGRNAM /* do nothing */
  156. # define OBJ2GID(id) NUM2GIDT(id)
  157. # ifdef p_gid_from_name
  158. # undef p_gid_from_name
  159. # define p_gid_from_name rb_f_notimplement
  160. # endif
  161. #endif
  162. /*
  163. * call-seq:
  164. * Process.pid -> fixnum
  165. *
  166. * Returns the process id of this process. Not available on all
  167. * platforms.
  168. *
  169. * Process.pid #=> 27415
  170. */
  171. static VALUE
  172. get_pid(void)
  173. {
  174. rb_secure(2);
  175. return PIDT2NUM(getpid());
  176. }
  177. /*
  178. * call-seq:
  179. * Process.ppid -> fixnum
  180. *
  181. * Returns the process id of the parent of this process. Returns
  182. * untrustworthy value on Win32/64. Not available on all platforms.
  183. *
  184. * puts "I am #{Process.pid}"
  185. * Process.fork { puts "Dad is #{Process.ppid}" }
  186. *
  187. * <em>produces:</em>
  188. *
  189. * I am 27417
  190. * Dad is 27417
  191. */
  192. static VALUE
  193. get_ppid(void)
  194. {
  195. rb_secure(2);
  196. return PIDT2NUM(getppid());
  197. }
  198. /*********************************************************************
  199. *
  200. * Document-class: Process::Status
  201. *
  202. * <code>Process::Status</code> encapsulates the information on the
  203. * status of a running or terminated system process. The built-in
  204. * variable <code>$?</code> is either +nil+ or a
  205. * <code>Process::Status</code> object.
  206. *
  207. * fork { exit 99 } #=> 26557
  208. * Process.wait #=> 26557
  209. * $?.class #=> Process::Status
  210. * $?.to_i #=> 25344
  211. * $? >> 8 #=> 99
  212. * $?.stopped? #=> false
  213. * $?.exited? #=> true
  214. * $?.exitstatus #=> 99
  215. *
  216. * Posix systems record information on processes using a 16-bit
  217. * integer. The lower bits record the process status (stopped,
  218. * exited, signaled) and the upper bits possibly contain additional
  219. * information (for example the program's return code in the case of
  220. * exited processes). Pre Ruby 1.8, these bits were exposed directly
  221. * to the Ruby program. Ruby now encapsulates these in a
  222. * <code>Process::Status</code> object. To maximize compatibility,
  223. * however, these objects retain a bit-oriented interface. In the
  224. * descriptions that follow, when we talk about the integer value of
  225. * _stat_, we're referring to this 16 bit value.
  226. */
  227. static VALUE rb_cProcessStatus;
  228. VALUE
  229. rb_last_status_get(void)
  230. {
  231. return GET_THREAD()->last_status;
  232. }
  233. void
  234. rb_last_status_set(int status, rb_pid_t pid)
  235. {
  236. rb_thread_t *th = GET_THREAD();
  237. th->last_status = rb_obj_alloc(rb_cProcessStatus);
  238. rb_iv_set(th->last_status, "status", INT2FIX(status));
  239. rb_iv_set(th->last_status, "pid", PIDT2NUM(pid));
  240. }
  241. void
  242. rb_last_status_clear(void)
  243. {
  244. GET_THREAD()->last_status = Qnil;
  245. }
  246. /*
  247. * call-seq:
  248. * stat.to_i -> fixnum
  249. * stat.to_int -> fixnum
  250. *
  251. * Returns the bits in _stat_ as a <code>Fixnum</code>. Poking
  252. * around in these bits is platform dependent.
  253. *
  254. * fork { exit 0xab } #=> 26566
  255. * Process.wait #=> 26566
  256. * sprintf('%04x', $?.to_i) #=> "ab00"
  257. */
  258. static VALUE
  259. pst_to_i(VALUE st)
  260. {
  261. return rb_iv_get(st, "status");
  262. }
  263. #define PST2INT(st) NUM2INT(pst_to_i(st))
  264. /*
  265. * call-seq:
  266. * stat.pid -> fixnum
  267. *
  268. * Returns the process ID that this status object represents.
  269. *
  270. * fork { exit } #=> 26569
  271. * Process.wait #=> 26569
  272. * $?.pid #=> 26569
  273. */
  274. static VALUE
  275. pst_pid(VALUE st)
  276. {
  277. return rb_attr_get(st, rb_intern("pid"));
  278. }
  279. static void
  280. pst_message(VALUE str, rb_pid_t pid, int status)
  281. {
  282. rb_str_catf(str, "pid %ld", (long)pid);
  283. if (WIFSTOPPED(status)) {
  284. int stopsig = WSTOPSIG(status);
  285. const char *signame = ruby_signal_name(stopsig);
  286. if (signame) {
  287. rb_str_catf(str, " stopped SIG%s (signal %d)", signame, stopsig);
  288. }
  289. else {
  290. rb_str_catf(str, " stopped signal %d", stopsig);
  291. }
  292. }
  293. if (WIFSIGNALED(status)) {
  294. int termsig = WTERMSIG(status);
  295. const char *signame = ruby_signal_name(termsig);
  296. if (signame) {
  297. rb_str_catf(str, " SIG%s (signal %d)", signame, termsig);
  298. }
  299. else {
  300. rb_str_catf(str, " signal %d", termsig);
  301. }
  302. }
  303. if (WIFEXITED(status)) {
  304. rb_str_catf(str, " exit %d", WEXITSTATUS(status));
  305. }
  306. #ifdef WCOREDUMP
  307. if (WCOREDUMP(status)) {
  308. rb_str_cat2(str, " (core dumped)");
  309. }
  310. #endif
  311. }
  312. /*
  313. * call-seq:
  314. * stat.to_s -> string
  315. *
  316. * Show pid and exit status as a string.
  317. *
  318. * system("false")
  319. * p $?.to_s #=> "pid 12766 exit 1"
  320. *
  321. */
  322. static VALUE
  323. pst_to_s(VALUE st)
  324. {
  325. rb_pid_t pid;
  326. int status;
  327. VALUE str;
  328. pid = NUM2PIDT(pst_pid(st));
  329. status = PST2INT(st);
  330. str = rb_str_buf_new(0);
  331. pst_message(str, pid, status);
  332. return str;
  333. }
  334. /*
  335. * call-seq:
  336. * stat.inspect -> string
  337. *
  338. * Override the inspection method.
  339. *
  340. * system("false")
  341. * p $?.inspect #=> "#<Process::Status: pid 12861 exit 1>"
  342. *
  343. */
  344. static VALUE
  345. pst_inspect(VALUE st)
  346. {
  347. rb_pid_t pid;
  348. int status;
  349. VALUE vpid, str;
  350. vpid = pst_pid(st);
  351. if (NIL_P(vpid)) {
  352. return rb_sprintf("#<%s: uninitialized>", rb_class2name(CLASS_OF(st)));
  353. }
  354. pid = NUM2PIDT(vpid);
  355. status = PST2INT(st);
  356. str = rb_sprintf("#<%s: ", rb_class2name(CLASS_OF(st)));
  357. pst_message(str, pid, status);
  358. rb_str_cat2(str, ">");
  359. return str;
  360. }
  361. /*
  362. * call-seq:
  363. * stat == other -> true or false
  364. *
  365. * Returns +true+ if the integer value of _stat_
  366. * equals <em>other</em>.
  367. */
  368. static VALUE
  369. pst_equal(VALUE st1, VALUE st2)
  370. {
  371. if (st1 == st2) return Qtrue;
  372. return rb_equal(pst_to_i(st1), st2);
  373. }
  374. /*
  375. * call-seq:
  376. * stat & num -> fixnum
  377. *
  378. * Logical AND of the bits in _stat_ with <em>num</em>.
  379. *
  380. * fork { exit 0x37 }
  381. * Process.wait
  382. * sprintf('%04x', $?.to_i) #=> "3700"
  383. * sprintf('%04x', $? & 0x1e00) #=> "1600"
  384. */
  385. static VALUE
  386. pst_bitand(VALUE st1, VALUE st2)
  387. {
  388. int status = PST2INT(st1) & NUM2INT(st2);
  389. return INT2NUM(status);
  390. }
  391. /*
  392. * call-seq:
  393. * stat >> num -> fixnum
  394. *
  395. * Shift the bits in _stat_ right <em>num</em> places.
  396. *
  397. * fork { exit 99 } #=> 26563
  398. * Process.wait #=> 26563
  399. * $?.to_i #=> 25344
  400. * $? >> 8 #=> 99
  401. */
  402. static VALUE
  403. pst_rshift(VALUE st1, VALUE st2)
  404. {
  405. int status = PST2INT(st1) >> NUM2INT(st2);
  406. return INT2NUM(status);
  407. }
  408. /*
  409. * call-seq:
  410. * stat.stopped? -> true or false
  411. *
  412. * Returns +true+ if this process is stopped. This is only
  413. * returned if the corresponding <code>wait</code> call had the
  414. * <code>WUNTRACED</code> flag set.
  415. */
  416. static VALUE
  417. pst_wifstopped(VALUE st)
  418. {
  419. int status = PST2INT(st);
  420. if (WIFSTOPPED(status))
  421. return Qtrue;
  422. else
  423. return Qfalse;
  424. }
  425. /*
  426. * call-seq:
  427. * stat.stopsig -> fixnum or nil
  428. *
  429. * Returns the number of the signal that caused _stat_ to stop
  430. * (or +nil+ if self is not stopped).
  431. */
  432. static VALUE
  433. pst_wstopsig(VALUE st)
  434. {
  435. int status = PST2INT(st);
  436. if (WIFSTOPPED(status))
  437. return INT2NUM(WSTOPSIG(status));
  438. return Qnil;
  439. }
  440. /*
  441. * call-seq:
  442. * stat.signaled? -> true or false
  443. *
  444. * Returns +true+ if _stat_ terminated because of
  445. * an uncaught signal.
  446. */
  447. static VALUE
  448. pst_wifsignaled(VALUE st)
  449. {
  450. int status = PST2INT(st);
  451. if (WIFSIGNALED(status))
  452. return Qtrue;
  453. else
  454. return Qfalse;
  455. }
  456. /*
  457. * call-seq:
  458. * stat.termsig -> fixnum or nil
  459. *
  460. * Returns the number of the signal that caused _stat_ to
  461. * terminate (or +nil+ if self was not terminated by an
  462. * uncaught signal).
  463. */
  464. static VALUE
  465. pst_wtermsig(VALUE st)
  466. {
  467. int status = PST2INT(st);
  468. if (WIFSIGNALED(status))
  469. return INT2NUM(WTERMSIG(status));
  470. return Qnil;
  471. }
  472. /*
  473. * call-seq:
  474. * stat.exited? -> true or false
  475. *
  476. * Returns +true+ if _stat_ exited normally (for
  477. * example using an <code>exit()</code> call or finishing the
  478. * program).
  479. */
  480. static VALUE
  481. pst_wifexited(VALUE st)
  482. {
  483. int status = PST2INT(st);
  484. if (WIFEXITED(status))
  485. return Qtrue;
  486. else
  487. return Qfalse;
  488. }
  489. /*
  490. * call-seq:
  491. * stat.exitstatus -> fixnum or nil
  492. *
  493. * Returns the least significant eight bits of the return code of
  494. * _stat_. Only available if <code>exited?</code> is
  495. * +true+.
  496. *
  497. * fork { } #=> 26572
  498. * Process.wait #=> 26572
  499. * $?.exited? #=> true
  500. * $?.exitstatus #=> 0
  501. *
  502. * fork { exit 99 } #=> 26573
  503. * Process.wait #=> 26573
  504. * $?.exited? #=> true
  505. * $?.exitstatus #=> 99
  506. */
  507. static VALUE
  508. pst_wexitstatus(VALUE st)
  509. {
  510. int status = PST2INT(st);
  511. if (WIFEXITED(status))
  512. return INT2NUM(WEXITSTATUS(status));
  513. return Qnil;
  514. }
  515. /*
  516. * call-seq:
  517. * stat.success? -> true, false or nil
  518. *
  519. * Returns +true+ if _stat_ is successful, +false+ if not.
  520. * Returns +nil+ if <code>exited?</code> is not +true+.
  521. */
  522. static VALUE
  523. pst_success_p(VALUE st)
  524. {
  525. int status = PST2INT(st);
  526. if (!WIFEXITED(status))
  527. return Qnil;
  528. return WEXITSTATUS(status) == EXIT_SUCCESS ? Qtrue : Qfalse;
  529. }
  530. /*
  531. * call-seq:
  532. * stat.coredump? -> true or false
  533. *
  534. * Returns +true+ if _stat_ generated a coredump
  535. * when it terminated. Not available on all platforms.
  536. */
  537. static VALUE
  538. pst_wcoredump(VALUE st)
  539. {
  540. #ifdef WCOREDUMP
  541. int status = PST2INT(st);
  542. if (WCOREDUMP(status))
  543. return Qtrue;
  544. else
  545. return Qfalse;
  546. #else
  547. return Qfalse;
  548. #endif
  549. }
  550. #if !defined(HAVE_WAITPID) && !defined(HAVE_WAIT4)
  551. #define NO_WAITPID
  552. static st_table *pid_tbl;
  553. struct wait_data {
  554. rb_pid_t pid;
  555. int status;
  556. };
  557. static int
  558. wait_each(rb_pid_t pid, int status, struct wait_data *data)
  559. {
  560. if (data->status != -1) return ST_STOP;
  561. data->pid = pid;
  562. data->status = status;
  563. return ST_DELETE;
  564. }
  565. static int
  566. waitall_each(rb_pid_t pid, int status, VALUE ary)
  567. {
  568. rb_last_status_set(status, pid);
  569. rb_ary_push(ary, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
  570. return ST_DELETE;
  571. }
  572. #else
  573. struct waitpid_arg {
  574. rb_pid_t pid;
  575. int *st;
  576. int flags;
  577. };
  578. #endif
  579. static void *
  580. rb_waitpid_blocking(void *data)
  581. {
  582. rb_pid_t result;
  583. #ifndef NO_WAITPID
  584. struct waitpid_arg *arg = data;
  585. #endif
  586. #if defined NO_WAITPID
  587. result = wait(data);
  588. #elif defined HAVE_WAITPID
  589. result = waitpid(arg->pid, arg->st, arg->flags);
  590. #else /* HAVE_WAIT4 */
  591. result = wait4(arg->pid, arg->st, arg->flags, NULL);
  592. #endif
  593. return (void *)(VALUE)result;
  594. }
  595. rb_pid_t
  596. rb_waitpid(rb_pid_t pid, int *st, int flags)
  597. {
  598. rb_pid_t result;
  599. #ifndef NO_WAITPID
  600. struct waitpid_arg arg;
  601. retry:
  602. arg.pid = pid;
  603. arg.st = st;
  604. arg.flags = flags;
  605. result = (rb_pid_t)(VALUE)rb_thread_call_without_gvl(rb_waitpid_blocking, &arg,
  606. RUBY_UBF_PROCESS, 0);
  607. if (result < 0) {
  608. if (errno == EINTR) {
  609. RUBY_VM_CHECK_INTS(GET_THREAD());
  610. goto retry;
  611. }
  612. return (rb_pid_t)-1;
  613. }
  614. #else /* NO_WAITPID */
  615. if (pid_tbl) {
  616. st_data_t status, piddata = (st_data_t)pid;
  617. if (pid == (rb_pid_t)-1) {
  618. struct wait_data data;
  619. data.pid = (rb_pid_t)-1;
  620. data.status = -1;
  621. st_foreach(pid_tbl, wait_each, (st_data_t)&data);
  622. if (data.status != -1) {
  623. rb_last_status_set(data.status, data.pid);
  624. return data.pid;
  625. }
  626. }
  627. else if (st_delete(pid_tbl, &piddata, &status)) {
  628. rb_last_status_set(*st = (int)status, pid);
  629. return pid;
  630. }
  631. }
  632. if (flags) {
  633. rb_raise(rb_eArgError, "can't do waitpid with flags");
  634. }
  635. for (;;) {
  636. result = (rb_pid_t)(VALUE)rb_thread_blocking_region(rb_waitpid_blocking,
  637. st, RUBY_UBF_PROCESS, 0);
  638. if (result < 0) {
  639. if (errno == EINTR) {
  640. rb_thread_schedule();
  641. continue;
  642. }
  643. return (rb_pid_t)-1;
  644. }
  645. if (result == pid || pid == (rb_pid_t)-1) {
  646. break;
  647. }
  648. if (!pid_tbl)
  649. pid_tbl = st_init_numtable();
  650. st_insert(pid_tbl, pid, (st_data_t)st);
  651. if (!rb_thread_alone()) rb_thread_schedule();
  652. }
  653. #endif
  654. if (result > 0) {
  655. rb_last_status_set(*st, result);
  656. }
  657. return result;
  658. }
  659. /* [MG]:FIXME: I wasn't sure how this should be done, since ::wait()
  660. has historically been documented as if it didn't take any arguments
  661. despite the fact that it's just an alias for ::waitpid(). The way I
  662. have it below is more truthful, but a little confusing.
  663. I also took the liberty of putting in the pid values, as they're
  664. pretty useful, and it looked as if the original 'ri' output was
  665. supposed to contain them after "[...]depending on the value of
  666. aPid:".
  667. The 'ansi' and 'bs' formats of the ri output don't display the
  668. definition list for some reason, but the plain text one does.
  669. */
  670. /*
  671. * call-seq:
  672. * Process.wait() -> fixnum
  673. * Process.wait(pid=-1, flags=0) -> fixnum
  674. * Process.waitpid(pid=-1, flags=0) -> fixnum
  675. *
  676. * Waits for a child process to exit, returns its process id, and
  677. * sets <code>$?</code> to a <code>Process::Status</code> object
  678. * containing information on that process. Which child it waits on
  679. * depends on the value of _pid_:
  680. *
  681. * > 0:: Waits for the child whose process ID equals _pid_.
  682. *
  683. * 0:: Waits for any child whose process group ID equals that of the
  684. * calling process.
  685. *
  686. * -1:: Waits for any child process (the default if no _pid_ is
  687. * given).
  688. *
  689. * < -1:: Waits for any child whose process group ID equals the absolute
  690. * value of _pid_.
  691. *
  692. * The _flags_ argument may be a logical or of the flag values
  693. * <code>Process::WNOHANG</code> (do not block if no child available)
  694. * or <code>Process::WUNTRACED</code> (return stopped children that
  695. * haven't been reported). Not all flags are available on all
  696. * platforms, but a flag value of zero will work on all platforms.
  697. *
  698. * Calling this method raises a SystemCallError if there are no child
  699. * processes. Not available on all platforms.
  700. *
  701. * include Process
  702. * fork { exit 99 } #=> 27429
  703. * wait #=> 27429
  704. * $?.exitstatus #=> 99
  705. *
  706. * pid = fork { sleep 3 } #=> 27440
  707. * Time.now #=> 2008-03-08 19:56:16 +0900
  708. * waitpid(pid, Process::WNOHANG) #=> nil
  709. * Time.now #=> 2008-03-08 19:56:16 +0900
  710. * waitpid(pid, 0) #=> 27440
  711. * Time.now #=> 2008-03-08 19:56:19 +0900
  712. */
  713. static VALUE
  714. proc_wait(int argc, VALUE *argv)
  715. {
  716. VALUE vpid, vflags;
  717. rb_pid_t pid;
  718. int flags, status;
  719. rb_secure(2);
  720. flags = 0;
  721. if (argc == 0) {
  722. pid = -1;
  723. }
  724. else {
  725. rb_scan_args(argc, argv, "02", &vpid, &vflags);
  726. pid = NUM2PIDT(vpid);
  727. if (argc == 2 && !NIL_P(vflags)) {
  728. flags = NUM2UINT(vflags);
  729. }
  730. }
  731. if ((pid = rb_waitpid(pid, &status, flags)) < 0)
  732. rb_sys_fail(0);
  733. if (pid == 0) {
  734. rb_last_status_clear();
  735. return Qnil;
  736. }
  737. return PIDT2NUM(pid);
  738. }
  739. /*
  740. * call-seq:
  741. * Process.wait2(pid=-1, flags=0) -> [pid, status]
  742. * Process.waitpid2(pid=-1, flags=0) -> [pid, status]
  743. *
  744. * Waits for a child process to exit (see Process::waitpid for exact
  745. * semantics) and returns an array containing the process id and the
  746. * exit status (a <code>Process::Status</code> object) of that
  747. * child. Raises a SystemCallError if there are no child processes.
  748. *
  749. * Process.fork { exit 99 } #=> 27437
  750. * pid, status = Process.wait2
  751. * pid #=> 27437
  752. * status.exitstatus #=> 99
  753. */
  754. static VALUE
  755. proc_wait2(int argc, VALUE *argv)
  756. {
  757. VALUE pid = proc_wait(argc, argv);
  758. if (NIL_P(pid)) return Qnil;
  759. return rb_assoc_new(pid, rb_last_status_get());
  760. }
  761. /*
  762. * call-seq:
  763. * Process.waitall -> [ [pid1,status1], ...]
  764. *
  765. * Waits for all children, returning an array of
  766. * _pid_/_status_ pairs (where _status_ is a
  767. * <code>Process::Status</code> object).
  768. *
  769. * fork { sleep 0.2; exit 2 } #=> 27432
  770. * fork { sleep 0.1; exit 1 } #=> 27433
  771. * fork { exit 0 } #=> 27434
  772. * p Process.waitall
  773. *
  774. * <em>produces</em>:
  775. *
  776. * [[30982, #<Process::Status: pid 30982 exit 0>],
  777. * [30979, #<Process::Status: pid 30979 exit 1>],
  778. * [30976, #<Process::Status: pid 30976 exit 2>]]
  779. */
  780. static VALUE
  781. proc_waitall(void)
  782. {
  783. VALUE result;
  784. rb_pid_t pid;
  785. int status;
  786. rb_secure(2);
  787. result = rb_ary_new();
  788. #ifdef NO_WAITPID
  789. if (pid_tbl) {
  790. st_foreach(pid_tbl, waitall_each, result);
  791. }
  792. #else
  793. rb_last_status_clear();
  794. #endif
  795. for (pid = -1;;) {
  796. #ifdef NO_WAITPID
  797. pid = wait(&status);
  798. #else
  799. pid = rb_waitpid(-1, &status, 0);
  800. #endif
  801. if (pid == -1) {
  802. if (errno == ECHILD)
  803. break;
  804. #ifdef NO_WAITPID
  805. if (errno == EINTR) {
  806. rb_thread_schedule();
  807. continue;
  808. }
  809. #endif
  810. rb_sys_fail(0);
  811. }
  812. #ifdef NO_WAITPID
  813. rb_last_status_set(status, pid);
  814. #endif
  815. rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
  816. }
  817. return result;
  818. }
  819. static inline ID
  820. id_pid(void)
  821. {
  822. ID pid;
  823. CONST_ID(pid, "pid");
  824. return pid;
  825. }
  826. static VALUE
  827. detach_process_pid(VALUE thread)
  828. {
  829. return rb_thread_local_aref(thread, id_pid());
  830. }
  831. static VALUE
  832. detach_process_watcher(void *arg)
  833. {
  834. rb_pid_t cpid, pid = (rb_pid_t)(VALUE)arg;
  835. int status;
  836. while ((cpid = rb_waitpid(pid, &status, 0)) == 0) {
  837. /* wait while alive */
  838. }
  839. return rb_last_status_get();
  840. }
  841. VALUE
  842. rb_detach_process(rb_pid_t pid)
  843. {
  844. VALUE watcher = rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
  845. rb_thread_local_aset(watcher, id_pid(), PIDT2NUM(pid));
  846. rb_define_singleton_method(watcher, "pid", detach_process_pid, 0);
  847. return watcher;
  848. }
  849. /*
  850. * call-seq:
  851. * Process.detach(pid) -> thread
  852. *
  853. * Some operating systems retain the status of terminated child
  854. * processes until the parent collects that status (normally using
  855. * some variant of <code>wait()</code>. If the parent never collects
  856. * this status, the child stays around as a <em>zombie</em> process.
  857. * <code>Process::detach</code> prevents this by setting up a
  858. * separate Ruby thread whose sole job is to reap the status of the
  859. * process _pid_ when it terminates. Use <code>detach</code>
  860. * only when you do not intent to explicitly wait for the child to
  861. * terminate.
  862. *
  863. * The waiting thread returns the exit status of the detached process
  864. * when it terminates, so you can use <code>Thread#join</code> to
  865. * know the result. If specified _pid_ is not a valid child process
  866. * ID, the thread returns +nil+ immediately.
  867. *
  868. * The waiting thread has <code>pid</code> method which returns the pid.
  869. *
  870. * In this first example, we don't reap the first child process, so
  871. * it appears as a zombie in the process status display.
  872. *
  873. * p1 = fork { sleep 0.1 }
  874. * p2 = fork { sleep 0.2 }
  875. * Process.waitpid(p2)
  876. * sleep 2
  877. * system("ps -ho pid,state -p #{p1}")
  878. *
  879. * <em>produces:</em>
  880. *
  881. * 27389 Z
  882. *
  883. * In the next example, <code>Process::detach</code> is used to reap
  884. * the child automatically.
  885. *
  886. * p1 = fork { sleep 0.1 }
  887. * p2 = fork { sleep 0.2 }
  888. * Process.detach(p1)
  889. * Process.waitpid(p2)
  890. * sleep 2
  891. * system("ps -ho pid,state -p #{p1}")
  892. *
  893. * <em>(produces no output)</em>
  894. */
  895. static VALUE
  896. proc_detach(VALUE obj, VALUE pid)
  897. {
  898. rb_secure(2);
  899. return rb_detach_process(NUM2PIDT(pid));
  900. }
  901. static int forked_child = 0;
  902. #ifdef SIGPIPE
  903. static RETSIGTYPE (*saved_sigpipe_handler)(int) = 0;
  904. #endif
  905. #ifdef SIGPIPE
  906. static RETSIGTYPE
  907. sig_do_nothing(int sig)
  908. {
  909. }
  910. #endif
  911. /* This function should be async-signal-safe. Actually it is. */
  912. static void
  913. before_exec_async_signal_safe(void)
  914. {
  915. #ifdef SIGPIPE
  916. /*
  917. * Some OS commands don't initialize signal handler properly. Thus we have
  918. * to reset signal handler before exec(). Otherwise, system() and similar
  919. * child process interaction might fail. (e.g. ruby -e "system 'yes | ls'")
  920. * [ruby-dev:12261]
  921. */
  922. saved_sigpipe_handler = signal(SIGPIPE, sig_do_nothing); /* async-signal-safe */
  923. #endif
  924. }
  925. static void
  926. before_exec_non_async_signal_safe(void)
  927. {
  928. if (!forked_child) {
  929. /*
  930. * On Mac OS X 10.5.x (Leopard) or earlier, exec() may return ENOTSUPP
  931. * if the process have multiple threads. Therefore we have to kill
  932. * internal threads temporary. [ruby-core:10583]
  933. * This is also true on Haiku. It returns Errno::EPERM against exec()
  934. * in multiple threads.
  935. */
  936. rb_thread_stop_timer_thread(0);
  937. }
  938. }
  939. static void
  940. before_exec(void)
  941. {
  942. before_exec_non_async_signal_safe();
  943. before_exec_async_signal_safe();
  944. }
  945. /* This function should be async-signal-safe. Actually it is. */
  946. static void
  947. after_exec_async_signal_safe(void)
  948. {
  949. #ifdef SIGPIPE
  950. signal(SIGPIPE, saved_sigpipe_handler); /* async-signal-safe */
  951. #endif
  952. }
  953. static void
  954. after_exec_non_async_signal_safe(void)
  955. {
  956. rb_thread_reset_timer_thread();
  957. rb_thread_start_timer_thread();
  958. forked_child = 0;
  959. }
  960. static void
  961. after_exec(void)
  962. {
  963. after_exec_async_signal_safe();
  964. after_exec_non_async_signal_safe();
  965. }
  966. #define before_fork() before_exec()
  967. #define after_fork() (rb_threadptr_pending_interrupt_clear(GET_THREAD()), after_exec())
  968. #include "dln.h"
  969. static void
  970. security(const char *str)
  971. {
  972. if (rb_env_path_tainted()) {
  973. if (rb_safe_level() > 0) {
  974. rb_raise(rb_eSecurityError, "Insecure PATH - %s", str);
  975. }
  976. }
  977. }
  978. #if defined(HAVE_FORK) && !defined(__native_client__)
  979. /* try_with_sh and exec_with_sh should be async-signal-safe. Actually it is.*/
  980. #define try_with_sh(prog, argv, envp) ((saved_errno == ENOEXEC) ? exec_with_sh((prog), (argv), (envp)) : (void)0)
  981. static void
  982. exec_with_sh(const char *prog, char **argv, char **envp)
  983. {
  984. *argv = (char *)prog;
  985. *--argv = (char *)"sh";
  986. if (envp)
  987. execve("/bin/sh", argv, envp); /* async-signal-safe */
  988. else
  989. execv("/bin/sh", argv); /* async-signal-safe */
  990. }
  991. #else
  992. #define try_with_sh(prog, argv, envp) (void)0
  993. #endif
  994. /* This function should be async-signal-safe. Actually it is. */
  995. static int
  996. proc_exec_cmd(const char *prog, VALUE argv_str, VALUE envp_str)
  997. {
  998. #ifdef __native_client__
  999. rb_notimplement();
  1000. UNREACHABLE;
  1001. #else
  1002. char **argv;
  1003. char **envp;
  1004. # if defined(__EMX__) || defined(OS2)
  1005. char **new_argv = NULL;
  1006. # endif
  1007. argv = ARGVSTR2ARGV(argv_str);
  1008. if (!prog) {
  1009. errno = ENOENT;
  1010. return -1;
  1011. }
  1012. # if defined(__EMX__) || defined(OS2)
  1013. {
  1014. # define COMMAND "cmd.exe"
  1015. char *extension;
  1016. if ((extension = strrchr(prog, '.')) != NULL && STRCASECMP(extension, ".bat") == 0) {
  1017. char *p;
  1018. int n;
  1019. for (n = 0; argv[n]; n++)
  1020. /* no-op */;
  1021. new_argv = ALLOC_N(char*, n + 2);
  1022. for (; n > 0; n--)
  1023. new_argv[n + 1] = argv[n];
  1024. new_argv[1] = strcpy(ALLOC_N(char, strlen(argv[0]) + 1), argv[0]);
  1025. for (p = new_argv[1]; *p != '\0'; p++)
  1026. if (*p == '/')
  1027. *p = '\\';
  1028. new_argv[0] = COMMAND;
  1029. argv = new_argv;
  1030. prog = dln_find_exe_r(argv[0], 0, fbuf, sizeof(fbuf));
  1031. if (!prog) {
  1032. errno = ENOENT;
  1033. return -1;
  1034. }
  1035. }
  1036. }
  1037. # endif /* __EMX__ */
  1038. envp = envp_str ? (char **)RSTRING_PTR(envp_str) : NULL;
  1039. if (envp_str)
  1040. execve(prog, argv, envp); /* async-signal-safe */
  1041. else
  1042. execv(prog, argv); /* async-signal-safe */
  1043. preserving_errno(try_with_sh(prog, argv, envp)); /* try_with_sh() is async-signal-safe. */
  1044. # if defined(__EMX__) || defined(OS2)
  1045. if (new_argv) {
  1046. xfree(new_argv[0]);
  1047. xfree(new_argv);
  1048. }
  1049. # endif
  1050. return -1;
  1051. #endif
  1052. }
  1053. /* deprecated */
  1054. static int
  1055. proc_exec_v(char **argv, const char *prog)
  1056. {
  1057. char fbuf[MAXPATHLEN];
  1058. if (!prog)
  1059. prog = argv[0];
  1060. prog = dln_find_exe_r(prog, 0, fbuf, sizeof(fbuf));
  1061. if (!prog) {
  1062. errno = ENOENT;
  1063. return -1;
  1064. }
  1065. before_exec();
  1066. execv(prog, argv);
  1067. preserving_errno(try_with_sh(prog, argv, 0); after_exec());
  1068. return -1;
  1069. }
  1070. /* deprecated */
  1071. int
  1072. rb_proc_exec_n(int argc, VALUE *argv, const char *prog)
  1073. {
  1074. #define ARGV_COUNT(n) ((n)+1)
  1075. #define ARGV_SIZE(n) (sizeof(char*) * ARGV_COUNT(n))
  1076. #define ALLOC_ARGV(n, v) ALLOCV_N(char*, (v), ARGV_COUNT(n))
  1077. char **args;
  1078. int i;
  1079. int ret = -1;
  1080. VALUE v;
  1081. args = ALLOC_ARGV(argc+1, v);
  1082. for (i=0; i<argc; i++) {
  1083. args[i] = RSTRING_PTR(argv[i]);
  1084. }
  1085. args[i] = 0;
  1086. if (args[0]) {
  1087. ret = proc_exec_v(args, prog);
  1088. }
  1089. ALLOCV_END(v);
  1090. return ret;
  1091. #undef ARGV_COUNT
  1092. #undef ARGV_SIZE
  1093. #undef ALLOC_ARGV
  1094. }
  1095. /* This function should be async-signal-safe. Actually it is. */
  1096. static int
  1097. proc_exec_sh(const char *str, VALUE envp_str)
  1098. {
  1099. #ifdef __native_client__
  1100. rb_notimplement();
  1101. UNREACHABLE;
  1102. #else
  1103. const char *s;
  1104. s = str;
  1105. while (*s == ' ' || *s == '\t' || *s == '\n')
  1106. s++;
  1107. if (!*s) {
  1108. errno = ENOENT;
  1109. return -1;
  1110. }
  1111. #ifdef _WIN32
  1112. rb_w32_spawn(P_OVERLAY, (char *)str, 0);
  1113. return -1;
  1114. #else
  1115. #if defined(__CYGWIN32__) || defined(__EMX__)
  1116. {
  1117. char fbuf[MAXPATHLEN];
  1118. char *shell = dln_find_exe_r("sh", 0, fbuf, sizeof(fbuf));
  1119. int status = -1;
  1120. if (shell)
  1121. execl(shell, "sh", "-c", str, (char *) NULL);
  1122. else
  1123. status = system(str);
  1124. if (status != -1)
  1125. exit(status);
  1126. }
  1127. #else
  1128. if (envp_str)
  1129. execle("/bin/sh", "sh", "-c", str, (char *)NULL, (char **)RSTRING_PTR(envp_str)); /* async-signal-safe */
  1130. else
  1131. execl("/bin/sh", "sh", "-c", str, (char *)NULL); /* async-signal-safe */
  1132. #endif
  1133. return -1;
  1134. #endif /* _WIN32 */
  1135. #endif
  1136. }
  1137. int
  1138. rb_proc_exec(const char *str)
  1139. {
  1140. int ret;
  1141. before_exec();
  1142. ret = proc_exec_sh(str, Qfalse);
  1143. preserving_errno(after_exec());
  1144. return ret;
  1145. }
  1146. static void
  1147. mark_exec_arg(void *ptr)
  1148. {
  1149. struct rb_execarg *eargp = ptr;
  1150. if (eargp->use_shell)
  1151. rb_gc_mark(eargp->invoke.sh.shell_script);
  1152. else {
  1153. rb_gc_mark(eargp->invoke.cmd.command_name);
  1154. rb_gc_mark(eargp->invoke.cmd.command_abspath);
  1155. rb_gc_mark(eargp->invoke.cmd.argv_str);
  1156. rb_gc_mark(eargp->invoke.cmd.argv_buf);
  1157. }
  1158. rb_gc_mark(eargp->redirect_fds);
  1159. rb_gc_mark(eargp->envp_str);
  1160. rb_gc_mark(eargp->envp_buf);
  1161. rb_gc_mark(eargp->dup2_tmpbuf);
  1162. rb_gc_mark(eargp->rlimit_limits);
  1163. rb_gc_mark(eargp->fd_dup2);
  1164. rb_gc_mark(eargp->fd_close);
  1165. rb_gc_mark(eargp->fd_open);
  1166. rb_gc_mark(eargp->fd_dup2_child);
  1167. rb_gc_mark(eargp->env_modification);
  1168. rb_gc_mark(eargp->chdir_dir);
  1169. }
  1170. static void
  1171. free_exec_arg(void *ptr)
  1172. {
  1173. xfree(ptr);
  1174. }
  1175. static size_t
  1176. memsize_exec_arg(const void *ptr)
  1177. {
  1178. return ptr ? sizeof(struct rb_execarg) : 0;
  1179. }
  1180. static const rb_data_type_t exec_arg_data_type = {
  1181. "exec_arg",
  1182. {mark_exec_arg, free_exec_arg, memsize_exec_arg},
  1183. };
  1184. #if defined(_WIN32)
  1185. #define HAVE_SPAWNV 1
  1186. #endif
  1187. #if !defined(HAVE_FORK) && defined(HAVE_SPAWNV)
  1188. # define USE_SPAWNV 1
  1189. #else
  1190. # define USE_SPAWNV 0
  1191. #endif
  1192. #ifndef P_NOWAIT
  1193. # define P_NOWAIT _P_NOWAIT
  1194. #endif
  1195. #if USE_SPAWNV
  1196. #if defined(_WIN32)
  1197. #define proc_spawn_cmd_internal(argv, prog) rb_w32_aspawn(P_NOWAIT, (prog), (argv))
  1198. #else
  1199. static rb_pid_t
  1200. proc_spawn_cmd_internal(char **argv, char *prog)
  1201. {
  1202. char fbuf[MAXPATHLEN];
  1203. rb_pid_t status;
  1204. if (!prog)
  1205. prog = argv[0];
  1206. security(prog);
  1207. prog = dln_find_exe_r(prog, 0, fbuf, sizeof(fbuf));
  1208. if (!prog)
  1209. return -1;
  1210. before_exec();
  1211. status = spawnv(P_NOWAIT, prog, (const char **)argv);
  1212. if (status == -1 && errno == ENOEXEC) {
  1213. *argv = (char *)prog;
  1214. *--argv = (char *)"sh";
  1215. status = spawnv(P_NOWAIT, "/bin/sh", (const char **)argv);
  1216. after_exec();
  1217. if (status == -1) errno = ENOEXEC;
  1218. }
  1219. rb_last_status_set(status == -1 ? 127 : status, 0);
  1220. return status;
  1221. }
  1222. #endif
  1223. static rb_pid_t
  1224. proc_spawn_cmd(char **argv, VALUE prog, struct rb_execarg *eargp)
  1225. {
  1226. rb_pid_t pid = -1;
  1227. if (argv[0]) {
  1228. #if defined(_WIN32)
  1229. DWORD flags = 0;
  1230. if (eargp->new_pgroup_given && eargp->new_pgroup_flag) {
  1231. flags = CREATE_NEW_PROCESS_GROUP;
  1232. }
  1233. pid = rb_w32_aspawn_flags(P_NOWAIT, prog ? RSTRING_PTR(prog) : 0, argv, flags);
  1234. #else
  1235. pid = proc_spawn_cmd_internal(argv, prog ? RSTRING_PTR(prog) : 0);
  1236. #endif
  1237. }
  1238. return pid;
  1239. }
  1240. #if defined(_WIN32)
  1241. #define proc_spawn_sh(str) rb_w32_spawn(P_NOWAIT, (str), 0)
  1242. #else
  1243. static rb_pid_t
  1244. proc_spawn_sh(char *str)
  1245. {
  1246. char fbuf[MAXPATHLEN];
  1247. rb_pid_t status;
  1248. char *shell = dln_find_exe_r("sh", 0, fbuf, sizeof(fbuf));
  1249. before_exec();
  1250. status = spawnl(P_NOWAIT, (shell ? shell : "/bin/sh"), "sh", "-c", str, (char*)NULL);
  1251. rb_last_status_set(status == -1 ? 127 : status, 0);
  1252. after_exec();
  1253. return status;
  1254. }
  1255. #endif
  1256. #endif
  1257. static VALUE
  1258. hide_obj(VALUE obj)
  1259. {
  1260. RBASIC(obj)->klass = 0;
  1261. return obj;
  1262. }
  1263. static VALUE
  1264. check_exec_redirect_fd(VALUE v, int iskey)
  1265. {
  1266. VALUE tmp;
  1267. int fd;
  1268. if (FIXNUM_P(v)) {
  1269. fd = FIX2INT(v);
  1270. }
  1271. else if (SYMBOL_P(v)) {
  1272. ID id = SYM2ID(v);
  1273. if (id == rb_intern("in"))
  1274. fd = 0;
  1275. else if (id == rb_intern("out"))
  1276. fd = 1;
  1277. else if (id == rb_intern("err"))
  1278. fd = 2;
  1279. else
  1280. goto wrong;
  1281. }
  1282. else if (!NIL_P(tmp = rb_check_convert_type(v, T_FILE, "IO", "to_io"))) {
  1283. rb_io_t *fptr;
  1284. GetOpenFile(tmp, fptr);
  1285. if (fptr->tied_io_for_writing)
  1286. rb_raise(rb_eArgError, "duplex IO redirection");
  1287. fd = fptr->fd;
  1288. }
  1289. else {
  1290. rb_raise(rb_eArgError, "wrong exec redirect");
  1291. }
  1292. if (fd < 0) {
  1293. wrong:
  1294. rb_raise(rb_eArgError, "negative file descriptor");
  1295. }
  1296. #ifdef _WIN32
  1297. else if (fd >= 3 && iskey) {
  1298. rb_raise(rb_eArgError, "wrong file descriptor (%d)", fd);
  1299. }
  1300. #endif
  1301. return INT2FIX(fd);
  1302. }
  1303. static VALUE
  1304. check_exec_redirect1(VALUE ary, VALUE key, VALUE param)
  1305. {
  1306. if (ary == Qfalse) {
  1307. ary = hide_obj(rb_ary_new());
  1308. }
  1309. if (!RB_TYPE_P(key, T_ARRAY)) {
  1310. VALUE fd = check_exec_redirect_fd(key, !NIL_P(param));
  1311. rb_ary_push(ary, hide_obj(rb_assoc_new(fd, param)));
  1312. }
  1313. else {
  1314. int i, n=0;
  1315. for (i = 0 ; i < RARRAY_LEN(key); i++) {
  1316. VALUE v = RARRAY_PTR(key)[i];
  1317. VALUE fd = check_exec_redirect_fd(v, !NIL_P(param));
  1318. rb_ary_push(ary, hide_obj(rb_assoc_new(fd, param)));
  1319. n++;
  1320. }
  1321. }
  1322. return ary;
  1323. }
  1324. static void
  1325. check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp)
  1326. {
  1327. VALUE param;
  1328. VALUE path, flags, perm;
  1329. VALUE tmp;
  1330. ID id;
  1331. switch (TYPE(val)) {
  1332. case T_SYMBOL:
  1333. id = SYM2ID(val);
  1334. if (id == rb_intern("close")) {
  1335. param = Qnil;
  1336. eargp->fd_close = check_exec_redirect1(eargp->fd_close, key, param);
  1337. }
  1338. else if (id == rb_intern("in")) {
  1339. param = INT2FIX(0);
  1340. eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
  1341. }
  1342. else if (id == rb_intern("out")) {
  1343. param = INT2FIX(1);
  1344. eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
  1345. }
  1346. else if (id == rb_intern("err")) {
  1347. param = INT2FIX(2);
  1348. eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
  1349. }
  1350. else {
  1351. rb_raise(rb_eArgError, "wrong exec redirect symbol: %s",
  1352. rb_id2name(id));
  1353. }
  1354. break;
  1355. case T_FILE:
  1356. io:
  1357. val = check_exec_redirect_fd(val, 0);
  1358. /* fall through */
  1359. case T_FIXNUM:
  1360. param = val;
  1361. eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
  1362. break;
  1363. case T_ARRAY:
  1364. path = rb_ary_entry(val, 0);
  1365. if (RARRAY_LEN(val) == 2 && SYMBOL_P(path) &&
  1366. SYM2ID(path) == rb_intern("child")) {
  1367. param = check_exec_redirect_fd(rb_ary_entry(val, 1), 0);
  1368. eargp->fd_dup2_child = check_exec_redirect1(eargp->fd_dup2_child, key, param);
  1369. }
  1370. else {
  1371. FilePathValue(path);
  1372. flags = rb_ary_entry(val, 1);
  1373. if (NIL_P(flags))
  1374. flags = INT2NUM(O_RDONLY);
  1375. else if (RB_TYPE_P(flags, T_STRING))
  1376. flags = INT2NUM(rb_io_modestr_oflags(StringValueCStr(flags)));
  1377. else
  1378. flags = rb_to_int(flags);
  1379. perm = rb_ary_entry(val, 2);
  1380. perm = NIL_P(perm) ? INT2FIX(0644) : rb_to_int(perm);
  1381. param = hide_obj(rb_ary_new3(3, hide_obj(rb_str_dup(path)),
  1382. flags, perm));
  1383. eargp->fd_open = check_exec_redirect1(eargp->fd_open, key, param);
  1384. }
  1385. break;
  1386. case T_STRING:
  1387. path = val;
  1388. FilePathValue(path);
  1389. if (RB_TYPE_P(key, T_FILE))
  1390. key = check_exec_redirect_fd(key, 1);
  1391. if (FIXNUM_P(key) && (FIX2INT(key) == 1 || FIX2INT(key) == 2))
  1392. flags = INT2NUM(O_WRONLY|O_CREAT|O_TRUNC);
  1393. else
  1394. flags = INT2NUM(O_RDONLY);
  1395. perm = INT2FIX(0644);
  1396. param = hide_obj(rb_ary_new3(3, hide_obj(rb_str_dup(path)),
  1397. flags, perm));
  1398. eargp->fd_open = check_exec_redirect1(eargp->fd_open, key, param);
  1399. break;
  1400. default:
  1401. tmp = val;
  1402. val = rb_io_check_io(tmp);
  1403. if (!NIL_P(val)) goto io;
  1404. rb_raise(rb_eArgError, "wrong exec redirect action");
  1405. }
  1406. }
  1407. #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
  1408. static int rlimit_type_by_lname(const char *name);
  1409. #endif
  1410. int
  1411. rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
  1412. {
  1413. struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
  1414. ID id;
  1415. #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
  1416. int rtype;
  1417. #endif
  1418. rb_secure(2);
  1419. switch (TYPE(key)) {
  1420. case T_SYMBOL:
  1421. id = SYM2ID(key);
  1422. #ifdef HAVE_SETPGID
  1423. if (id == rb_intern("pgroup")) {
  1424. pid_t pgroup;
  1425. if (eargp->pgroup_given) {
  1426. rb_raise(rb_eArgError, "pgroup option specified twice");
  1427. }
  1428. if (!RTEST(val))
  1429. pgroup = -1; /* asis(-1) means "don't call setpgid()". */
  1430. else if (val == Qtrue)
  1431. pgroup = 0; /* new process group. */
  1432. else {
  1433. pgroup = NUM2PIDT(val);
  1434. if (pgroup < 0) {
  1435. rb_raise(rb_eArgError, "negative process group ID : %ld", (long)pgroup);
  1436. }
  1437. }
  1438. eargp->pgroup_given = 1;
  1439. eargp->pgroup_pgid = pgroup;
  1440. }
  1441. else
  1442. #endif
  1443. #ifdef _WIN32
  1444. if (id == rb_intern("new_pgroup")) {
  1445. if (eargp->new_pgroup_given) {
  1446. rb_raise(rb_eArgError, "new_pgroup option specified twice");
  1447. }
  1448. eargp->new_pgroup_given = 1;
  1449. eargp->new_pgroup_flag = RTEST(val) ? 1 : 0;
  1450. }
  1451. else
  1452. #endif
  1453. #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
  1454. if (strncmp("rlimit_", rb_id2name(id), 7) == 0 &&
  1455. (rtype = rlimit_type_by_lname(rb_id2name(id)+7)) != -1) {
  1456. VALUE ary = eargp->rlimit_limits;
  1457. VALUE tmp, softlim, hardlim;
  1458. if (eargp->rlimit_limits == Qfalse)
  1459. ary = eargp->rlimit_limits = hide_obj(rb_ary_new());
  1460. else
  1461. ary = eargp->rlimit_limits;
  1462. tmp = rb_check_array_type(val);
  1463. if (!NIL_P(tmp)) {
  1464. if (RARRAY_LEN(tmp) == 1)
  1465. softlim = hardlim = rb_to_int(rb_ary_entry(tmp, 0));
  1466. else if (RARRAY_LEN(tmp) == 2) {
  1467. softlim = rb_to_int(rb_ary_entry(tmp, 0));
  1468. hardlim = rb_to_int(rb_ary_entry(tmp, 1));
  1469. }
  1470. else {
  1471. rb_raise(rb_eArgError, "wrong exec rlimit option");
  1472. }
  1473. }
  1474. else {
  1475. softlim = hardlim = rb_to_int(val);
  1476. }
  1477. tmp = hide_obj(rb_ary_new3(3, INT2NUM(rtype), softlim, hardlim));
  1478. rb_ary_push(ary, tmp);
  1479. }
  1480. else
  1481. #endif
  1482. if (id == rb_intern("unsetenv_others")) {
  1483. if (eargp->unsetenv_others_given) {
  1484. rb_raise(rb_eArgError, "unsetenv_others option specified twice");
  1485. }
  1486. eargp->unsetenv_others_given = 1;
  1487. eargp->unsetenv_others_do = RTEST(val) ? 1 : 0;
  1488. }
  1489. else if (id == rb_intern("chdir")) {
  1490. if (eargp->chdir_given) {
  1491. rb_raise(rb_eArgError, "chdir option specified twice");
  1492. }
  1493. FilePathValue(val);
  1494. eargp->chdir_given = 1;
  1495. eargp->chdir_dir = hide_obj(rb_str_dup(val));
  1496. }
  1497. else if (id == rb_intern("umask")) {
  1498. mode_t cmask = NUM2MODET(val);
  1499. if (eargp->umask_given) {
  1500. rb_raise(rb_eArgError, "umask option specified twice");
  1501. }
  1502. eargp->umask_given = 1;
  1503. eargp->umask_mask = cmask;
  1504. }
  1505. else if (id == rb_intern("close_others")) {
  1506. if (eargp->close_others_given) {
  1507. rb_raise(rb_eArgError, "close_others option specified twice");
  1508. }
  1509. eargp->close_others_given = 1;
  1510. eargp->close_others_do = RTEST(val) ? 1 : 0;
  1511. }
  1512. else if (id == rb_intern("in")) {
  1513. key = INT2FIX(0);
  1514. goto redirect;
  1515. }
  1516. else if (id == rb_intern("out")) {
  1517. key = INT2FIX(1);
  1518. goto redirect;
  1519. }
  1520. else if (id == rb_intern("err")) {
  1521. key = INT2FIX(2);
  1522. goto redirect;
  1523. }
  1524. else if (id == rb_intern("uid")) {
  1525. #ifdef HAVE_SETUID
  1526. if (eargp->uid_given) {
  1527. rb_raise(rb_eArgError, "uid option specified twice");
  1528. }
  1529. check_uid_switch();
  1530. {
  1531. PREPARE_GETPWNAM;
  1532. eargp->uid = OBJ2UID(val);
  1533. eargp->uid_given = 1;
  1534. }
  1535. #else
  1536. rb_raise(rb_eNotImpError,
  1537. "uid option is unimplemented on this machine");
  1538. #endif
  1539. }
  1540. else if (id == rb_intern("gid")) {
  1541. #ifdef HAVE_SETGID
  1542. if (eargp->gid_given) {
  1543. rb_raise(rb_eArgError, "gid option specified twice");
  1544. }
  1545. check_gid_switch();
  1546. {
  1547. PREPARE_GETGRNAM;
  1548. eargp->gid = OBJ2GID(val);
  1549. eargp->gid_given = 1;
  1550. }
  1551. #else
  1552. rb_raise(rb_eNotImpError,
  1553. "gid option is unimplemented on this machine");
  1554. #endif
  1555. }
  1556. else {
  1557. return ST_STOP;
  1558. }
  1559. break;
  1560. case T_FIXNUM:
  1561. case T_FILE:
  1562. case T_ARRAY:
  1563. redirect:
  1564. check_exec_redirect(key, val, eargp);
  1565. break;
  1566. default:
  1567. return ST_STOP;
  1568. }
  1569. RB_GC_GUARD(execarg_obj);
  1570. return ST_CONTINUE;
  1571. }
  1572. int
  1573. rb_exec_arg_addopt(struct rb_exec_arg *e, VALUE key, VALUE val)
  1574. {
  1575. return rb_execarg_addopt(e->execarg_obj, key, val);
  1576. }
  1577. static int
  1578. check_exec_options_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
  1579. {
  1580. VALUE key = (VALUE)st_key;
  1581. VALUE val = (VALUE)st_val;
  1582. VALUE execarg_obj = (VALUE)arg;
  1583. if (rb_execarg_addopt(execarg_obj, key, val) != ST_CONTINUE) {
  1584. if (SYMBOL_P(key))
  1585. rb_raise(rb_eArgError, "wrong exec option symbol: %"PRIsVALUE,
  1586. key);
  1587. rb_raise(rb_eArgError, "wrong exec option");
  1588. }
  1589. return ST_CONTINUE;
  1590. }
  1591. static int
  1592. check_exec_options_i_extract(st_data_t st_key, st_data_t st_val, st_data_t arg)
  1593. {
  1594. VALUE key = (VALUE)st_key;
  1595. VALUE val = (VALUE)st_val;
  1596. VALUE *args = (VALUE *)arg;
  1597. VALUE execarg_obj = args[0];
  1598. if (rb_execarg_addopt(execarg_obj, key, val) != ST_CONTINUE) {
  1599. VALUE nonopts = args[1];
  1600. if (NIL_P(nonopts)) args[1] = nonopts = rb_hash_new();
  1601. rb_hash_aset(nonopts, key, val);
  1602. }
  1603. return ST_CONTINUE;
  1604. }
  1605. static int
  1606. check_exec_fds_1(struct rb_execarg *eargp, VALUE h, int maxhint, VALUE ary)
  1607. {
  1608. long i;
  1609. if (ary != Qfalse) {
  1610. for (i = 0; i < RARRAY_LEN(ary); i++) {
  1611. VALUE elt = RARRAY_PTR(ary)[i];
  1612. int fd = FIX2INT(RARRAY_PTR(elt)[0]);
  1613. if (RTEST(rb_hash_lookup(h, INT2FIX(fd)))) {
  1614. rb_raise(rb_eArgError, "fd %d specified twice", fd);
  1615. }
  1616. if (ary == eargp->fd_open || ary == eargp->fd_dup2)
  1617. rb_hash_aset(h, INT2FIX(fd), Qtrue);
  1618. else if (ary == eargp->fd_dup2_child)
  1619. rb_hash_aset(h, INT2FIX(fd), RARRAY_PTR(elt)[1]);
  1620. else /* ary == eargp->fd_close */
  1621. rb_hash_aset(h, INT2FIX(fd), INT2FIX(-1));
  1622. if (maxhint < fd)
  1623. maxhint = fd;
  1624. if (ary == eargp->fd_dup2 || ary == eargp->fd_dup2_child) {
  1625. fd = FIX2INT(RARRAY_PTR(elt)[1]);
  1626. if (maxhint < fd)
  1627. maxhint = fd;
  1628. }
  1629. }
  1630. }
  1631. return maxhint;
  1632. }
  1633. static VALUE
  1634. check_exec_fds(struct rb_execarg *eargp)
  1635. {
  1636. VALUE h = rb_hash_new();
  1637. VALUE ary;
  1638. int maxhint = -1;
  1639. long i;
  1640. maxhint = check_exec_fds_1(eargp, h, maxhint, eargp->fd_dup2);
  1641. maxhint = check_exec_fds_1(eargp, h, maxhint, eargp->fd_close);
  1642. maxhint = check_exec_fds_1(eargp, h, maxhint, eargp->fd_open);
  1643. maxhint = check_exec_fds_1(eargp, h, maxhint, eargp->fd_dup2_child);
  1644. if (eargp->fd_dup2_child) {
  1645. ary = eargp->fd_dup2_child;
  1646. for (i = 0; i < RARRAY_LEN(ary); i++) {
  1647. VALUE elt = RARRAY_PTR(ary)[i];
  1648. int newfd = FIX2INT(RARRAY_PTR(elt)[0]);
  1649. int oldfd = FIX2INT(RARRAY_PTR(elt)[1]);
  1650. int lastfd = oldfd;
  1651. VALUE val = rb_hash_lookup(h, INT2FIX(lastfd));
  1652. long depth = 0;
  1653. while (FIXNUM_P(val) && 0 <= FIX2INT(val)) {
  1654. lastfd = FIX2INT(val);
  1655. val = rb_hash_lookup(h, val);
  1656. if (RARRAY_LEN(ary) < depth)
  1657. rb_raise(rb_eArgError, "cyclic child fd redirection from %d", oldfd);
  1658. depth++;
  1659. }
  1660. if (val != Qtrue)
  1661. rb_raise(rb_eArgError, "child fd %d is not redirected", oldfd);
  1662. if (oldfd != lastfd) {
  1663. VALUE val2;
  1664. rb_ary_store(elt, 1, INT2FIX(lastfd));
  1665. rb_hash_aset(h, INT2FIX(newfd), INT2FIX(lastfd));
  1666. val = INT2FIX(oldfd);
  1667. while (FIXNUM_P(val2 = rb_hash_lookup(h, val))) {
  1668. rb_hash_aset(h, val, INT2FIX(lastfd));
  1669. val = val2;
  1670. }
  1671. }
  1672. }
  1673. }
  1674. eargp->close_others_maxhint = maxhint;
  1675. return h;
  1676. }
  1677. static void
  1678. rb_check_exec_options(VALUE opthash, VALUE execarg_obj)
  1679. {
  1680. if (RHASH_EMPTY_P(opthash))
  1681. return;
  1682. st_foreach(RHASH_TBL(opthash), check_exec_options_i, (st_data_t)execarg_obj);
  1683. }
  1684. VALUE
  1685. rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash)
  1686. {
  1687. VALUE args[2];
  1688. if (RHASH_EMPTY_P(opthash))
  1689. return Qnil;
  1690. args[0] = execarg_obj;
  1691. args[1] = Qnil;
  1692. st_foreach(RHASH_TBL(opthash), check_exec_options_i_extract, (st_data_t)args);
  1693. return args[1];
  1694. }
  1695. static int
  1696. check_exec_env_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
  1697. {
  1698. VALUE key = (VALUE)st_key;
  1699. VALUE val = (VALUE)st_val;
  1700. VALUE env = (VALUE)arg;
  1701. char *k;
  1702. k = StringValueCStr(key);
  1703. if (strchr(k, '='))
  1704. rb_raise(rb_eArgError, "environment name contains a equal : %s", k);
  1705. if (!NIL_P(val))
  1706. StringValueCStr(val);
  1707. rb_ary_push(env, hide_obj(rb_assoc_new(key, val)));
  1708. return ST_CONTINUE;
  1709. }
  1710. static VALUE
  1711. rb_check_exec_env(VALUE hash)
  1712. {
  1713. VALUE env;
  1714. env = hide_obj(rb_ary_new());
  1715. st_foreach(RHASH_TBL(hash), check_exec_env_i, (st_data_t)env);
  1716. return env;
  1717. }
  1718. static VALUE
  1719. rb_check_argv(int argc, VALUE *argv)
  1720. {
  1721. VALUE tmp, prog;
  1722. int i;
  1723. const char *name = 0;
  1724. rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
  1725. prog = 0;
  1726. tmp = rb_check_array_type(argv[0]);
  1727. if (!NIL_P(tmp)) {
  1728. if (RARRAY_LEN(tmp) != 2) {
  1729. rb_raise(rb_eArgError, "wrong first argument");
  1730. }
  1731. prog = RARRAY_PTR(tmp)[0];
  1732. argv[0] = RARRAY_PTR(tmp)[1];
  1733. SafeStringValue(prog);
  1734. StringValueCStr(prog);
  1735. prog = rb_str_new_frozen(prog);
  1736. name = RSTRING_PTR(prog);
  1737. }
  1738. for (i = 0; i < argc; i++) {
  1739. SafeStringValue(argv[i]);
  1740. argv[i] = rb_str_new_frozen(argv[i]);
  1741. StringValueCStr(argv[i]);
  1742. }
  1743. security(name ? name : RSTRING_PTR(argv[0]));
  1744. return prog;
  1745. }
  1746. static VALUE
  1747. rb_exec_getargs(int *argc_p, VALUE **argv_p, int accept_shell, VALUE *env_ret, VALUE *opthash_ret)
  1748. {
  1749. VALUE hash, prog;
  1750. if (0 < *argc_p) {
  1751. hash = rb_check_hash_type((*argv_p)[*argc_p-1]);
  1752. if (!NIL_P(hash)) {
  1753. *opthash_ret = hash;
  1754. (*argc_p)--;
  1755. }
  1756. }
  1757. if (0 < *argc_p) {
  1758. hash = rb_check_hash_type((*argv_p)[0]);
  1759. if (!NIL_P(hash)) {
  1760. *env_ret = hash;
  1761. (*argc_p)--;
  1762. (*argv_p)++;
  1763. }
  1764. }
  1765. prog = rb_check_argv(*argc_p, *argv_p);
  1766. if (!prog) {
  1767. prog = (*argv_p)[0];
  1768. if (accept_shell && *argc_p == 1) {
  1769. *argc_p = 0;
  1770. *argv_p = 0;
  1771. }
  1772. }
  1773. return prog;
  1774. }
  1775. #ifndef _WIN32
  1776. struct string_part {
  1777. const char *ptr;
  1778. size_t len;
  1779. };
  1780. static int
  1781. compare_posix_sh(const void *key, const void *el)
  1782. {
  1783. const struct string_part *word = key;
  1784. int ret = strncmp(word->ptr, el, word->len);
  1785. if (!ret && ((const char *)el)[word->len]) ret = -1;
  1786. return ret;
  1787. }
  1788. #endif
  1789. static void
  1790. rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, VALUE execarg_obj)
  1791. {
  1792. struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
  1793. char fbuf[MAXPATHLEN];
  1794. MEMZERO(eargp, struct rb_execarg, 1);
  1795. if (!NIL_P(opthash)) {
  1796. rb_check_exec_options(opthash, execarg_obj);
  1797. }
  1798. if (!NIL_P(env)) {
  1799. env = rb_check_exec_env(env);
  1800. eargp->env_modification = env;
  1801. }
  1802. eargp->use_shell = argc == 0;
  1803. if (eargp->use_shell)
  1804. eargp->invoke.sh.shell_script = prog;
  1805. else
  1806. eargp->invoke.cmd.command_name = prog;
  1807. #ifndef _WIN32
  1808. if (eargp->use_shell) {
  1809. static const char posix_sh_cmds[][9] = {
  1810. "!", /* reserved */
  1811. ".", /* special built-in */
  1812. ":", /* special built-in */
  1813. "break", /* special built-in */
  1814. "case", /* reserved */
  1815. "continue", /* special …

Large files files are truncated, but you can click here to view the full file