Feature #5041 ยป close-on-exec-by-default.patch
NEWS (working copy) | ||
---|---|---|
30 | 30 |
* Signal.trap |
31 | 31 | |
32 | 32 |
See above. |
33 | ||
34 |
* incompatible changes: |
|
35 |
The :close_others option is true by default for system() and exec(). |
|
36 |
The close on exec flag is set by default for all new file descriptors. |
|
37 |
This means file descriptors doesn't inherit to spawned process unless |
|
38 |
explicitly requested as system(..., fd=>fd). |
include/ruby/intern.h (working copy) | ||
---|---|---|
501 | 501 |
int rb_reserved_fd_p(int fd); |
502 | 502 |
#define RB_RESERVED_FD_P(fd) rb_reserved_fd_p(fd) |
503 | 503 |
void rb_update_max_fd(int fd); |
504 |
void rb_fd_set_cloexec(int fd); |
|
504 | 505 |
/* marshal.c */ |
505 | 506 |
VALUE rb_marshal_dump(VALUE, VALUE); |
506 | 507 |
VALUE rb_marshal_load(VALUE); |
thread_pthread.c (working copy) | ||
---|---|---|
1207 | 1207 |
if (err != 0) { |
1208 | 1208 |
rb_bug_errno("thread_timer: Failed to create communication pipe for timer thread", errno); |
1209 | 1209 |
} |
1210 |
rb_update_max_fd(timer_thread_pipe[0]);
|
|
1211 |
rb_update_max_fd(timer_thread_pipe[1]);
|
|
1210 |
rb_fd_set_cloexec(timer_thread_pipe[0]);
|
|
1211 |
rb_fd_set_cloexec(timer_thread_pipe[1]);
|
|
1212 | 1212 |
#if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(F_SETFL) |
1213 | 1213 |
{ |
1214 | 1214 |
int oflags; |
io.c (working copy) | ||
---|---|---|
157 | 157 |
if (max_file_descriptor < fd) max_file_descriptor = fd; |
158 | 158 |
} |
159 | 159 | |
160 |
void rb_fd_set_cloexec(int fd) |
|
161 |
{ |
|
162 |
int flags, ret; |
|
163 |
flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */ |
|
164 |
if (flags == -1) { |
|
165 |
rb_bug("rb_fd_set_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno)); |
|
166 |
} |
|
167 |
if (2 < fd) { |
|
168 |
if (!(flags & FD_CLOEXEC)) { |
|
169 |
flags |= FD_CLOEXEC; |
|
170 |
ret = fcntl(fd, F_SETFD, flags); |
|
171 |
if (ret == -1) { |
|
172 |
rb_bug("rb_fd_set_cloexec: fcntl(%d, F_SETFD, %d) failed: %s", fd, flags, strerror(errno)); |
|
173 |
} |
|
174 |
} |
|
175 |
} |
|
176 |
if (max_file_descriptor < fd) max_file_descriptor = fd; |
|
177 |
} |
|
178 | ||
160 | 179 |
#define argf_of(obj) (*(struct argf *)DATA_PTR(obj)) |
161 | 180 |
#define ARGF argf_of(argf) |
162 | 181 | |
... | ... | |
527 | 546 |
rb_sys_fail(0); |
528 | 547 |
} |
529 | 548 |
} |
530 |
rb_update_max_fd(fd);
|
|
549 |
rb_fd_set_cloexec(fd);
|
|
531 | 550 |
return fd; |
532 | 551 |
} |
533 | 552 | |
... | ... | |
4591 | 4610 |
int fd; |
4592 | 4611 |
fd = (int)rb_thread_blocking_region(sysopen_func, data, RUBY_UBF_IO, 0); |
4593 | 4612 |
if (0 <= fd) |
4594 |
rb_update_max_fd(fd);
|
|
4613 |
rb_fd_set_cloexec(fd);
|
|
4595 | 4614 |
return fd; |
4596 | 4615 |
} |
4597 | 4616 | |
... | ... | |
4919 | 4938 |
} |
4920 | 4939 |
#endif |
4921 | 4940 |
if (ret == 0) { |
4922 |
rb_update_max_fd(pipes[0]);
|
|
4923 |
rb_update_max_fd(pipes[1]);
|
|
4941 |
rb_fd_set_cloexec(pipes[0]);
|
|
4942 |
rb_fd_set_cloexec(pipes[1]);
|
|
4924 | 4943 |
} |
4925 | 4944 |
return ret; |
4926 | 4945 |
} |
... | ... | |
5802 | 5821 |
/* need to keep FILE objects of stdin, stdout and stderr */ |
5803 | 5822 |
if (dup2(fd2, fd) < 0) |
5804 | 5823 |
rb_sys_fail_path(orig->pathv); |
5805 |
rb_update_max_fd(fd);
|
|
5824 |
rb_fd_set_cloexec(fd);
|
|
5806 | 5825 |
} |
5807 | 5826 |
else { |
5808 | 5827 |
fclose(fptr->stdio_file); |
... | ... | |
5810 | 5829 |
fptr->fd = -1; |
5811 | 5830 |
if (dup2(fd2, fd) < 0) |
5812 | 5831 |
rb_sys_fail_path(orig->pathv); |
5813 |
rb_update_max_fd(fd);
|
|
5832 |
rb_fd_set_cloexec(fd);
|
|
5814 | 5833 |
fptr->fd = fd; |
5815 | 5834 |
} |
5816 | 5835 |
rb_thread_fd_close(fd); |
... | ... | |
7702 | 7721 |
retval = (int)rb_thread_io_blocking_region(nogvl_io_cntl, &arg, fd); |
7703 | 7722 |
#if defined(F_DUPFD) |
7704 | 7723 |
if (!io_p && retval != -1 && cmd == F_DUPFD) { |
7705 |
rb_update_max_fd(retval);
|
|
7724 |
rb_fd_set_cloexec(retval);
|
|
7706 | 7725 |
} |
7707 | 7726 |
#endif |
7708 | 7727 |
process.c (working copy) | ||
---|---|---|
1857 | 1857 | |
1858 | 1858 |
rb_exec_arg_init(argc, argv, TRUE, &earg); |
1859 | 1859 |
if (NIL_P(rb_ary_entry(earg.options, EXEC_OPTION_CLOSE_OTHERS))) |
1860 |
rb_exec_arg_addopt(&earg, ID2SYM(rb_intern("close_others")), Qfalse);
|
|
1860 |
rb_exec_arg_addopt(&earg, ID2SYM(rb_intern("close_others")), Qtrue);
|
|
1861 | 1861 |
rb_exec_arg_fixup(&earg); |
1862 | 1862 | |
1863 | 1863 |
rb_exec_err(&earg, errmsg, sizeof(errmsg)); |
... | ... | |
2498 | 2498 |
ret = fcntl(fdp[i], F_DUPFD, min); |
2499 | 2499 |
if (ret == -1) |
2500 | 2500 |
return -1; |
2501 |
rb_update_max_fd(ret);
|
|
2501 |
rb_fd_set_cloexec(ret);
|
|
2502 | 2502 |
close(fdp[i]); |
2503 | 2503 |
fdp[i] = ret; |
2504 | 2504 |
} |
... | ... | |
3076 | 3076 | |
3077 | 3077 |
chfunc = signal(SIGCHLD, SIG_DFL); |
3078 | 3078 |
#endif |
3079 |
pid = rb_spawn_internal(argc, argv, FALSE, NULL, 0);
|
|
3079 |
pid = rb_spawn_internal(argc, argv, TRUE, NULL, 0);
|
|
3080 | 3080 |
#if defined(HAVE_FORK) || defined(HAVE_SPAWNV) |
3081 | 3081 |
if (pid > 0) { |
3082 | 3082 |
rb_syswait(pid); |
... | ... | |
3151 | 3151 |
* integer : the file descriptor of specified the integer |
3152 | 3152 |
* io : the file descriptor specified as io.fileno |
3153 | 3153 |
* file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not |
3154 |
* :close_others => false : inherit fds (default for system and exec) |
|
3155 |
* :close_others => true : don't inherit (default for spawn and IO.popen) |
|
3154 |
* :close_others => true : don't inherit |
|
3156 | 3155 |
* |
3157 | 3156 |
* If a hash is given as +env+, the environment is |
3158 | 3157 |
* updated by +env+ before <code>exec(2)</code> in the child process. |
... | ... | |
3547 | 3546 |
if (ret == -1) return -1; |
3548 | 3547 | |
3549 | 3548 |
if ((fd = open("/dev/tty", O_RDWR)) >= 0) { |
3550 |
rb_update_max_fd(fd);
|
|
3549 |
rb_fd_set_cloexec(fd);
|
|
3551 | 3550 |
ioctl(fd, TIOCNOTTY, NULL); |
3552 | 3551 |
close(fd); |
3553 | 3552 |
} |
... | ... | |
4838 | 4837 |
err = chdir("/"); |
4839 | 4838 | |
4840 | 4839 |
if (!noclose && (n = open("/dev/null", O_RDWR, 0)) != -1) { |
4841 |
rb_update_max_fd(n);
|
|
4840 |
rb_fd_set_cloexec(n);
|
|
4842 | 4841 |
(void)dup2(n, 0); |
4843 | 4842 |
(void)dup2(n, 1); |
4844 | 4843 |
(void)dup2(n, 2); |
ext/pty/pty.c (working copy) | ||
---|---|---|
177 | 177 |
{ |
178 | 178 |
int i = open("/dev/tty", O_RDONLY); |
179 | 179 |
if (i < 0) ERROR_EXIT("/dev/tty"); |
180 |
rb_update_max_fd(i);
|
|
180 |
rb_fd_set_cloexec(i);
|
|
181 | 181 |
if (ioctl(i, TIOCNOTTY, (char *)0)) |
182 | 182 |
ERROR_EXIT("ioctl(TIOCNOTTY)"); |
183 | 183 |
close(i); |
... | ... | |
199 | 199 |
if (slave < 0) { |
200 | 200 |
ERROR_EXIT("open: pty slave"); |
201 | 201 |
} |
202 |
rb_update_max_fd(slave);
|
|
202 |
rb_fd_set_cloexec(slave);
|
|
203 | 203 |
close(master); |
204 | 204 |
#endif |
205 | 205 |
dup2(slave,0); |
... | ... | |
291 | 291 |
sigemptyset(&dfl.sa_mask); |
292 | 292 | |
293 | 293 |
if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error; |
294 |
rb_update_max_fd(masterfd);
|
|
294 |
rb_fd_set_cloexec(masterfd);
|
|
295 | 295 |
if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error; |
296 | 296 |
if (grantpt(masterfd) == -1) goto grantpt_error; |
297 | 297 |
if (sigaction(SIGCHLD, &old, NULL) == -1) goto error; |
... | ... | |
299 | 299 |
if ((slavedevice = ptsname(masterfd)) == NULL) goto error; |
300 | 300 |
if (no_mesg(slavedevice, nomesg) == -1) goto error; |
301 | 301 |
if ((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error; |
302 |
rb_update_max_fd(slavefd);
|
|
302 |
rb_fd_set_cloexec(slavefd);
|
|
303 | 303 | |
304 | 304 |
#if defined I_PUSH && !defined linux |
305 | 305 |
if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error; |
... | ... | |
331 | 331 |
if (!fail) return -1; |
332 | 332 |
rb_raise(rb_eRuntimeError, "openpty() failed"); |
333 | 333 |
} |
334 |
rb_update_max_fd(*master);
|
|
335 |
rb_update_max_fd(*slave);
|
|
334 |
rb_fd_set_cloexec(*master);
|
|
335 |
rb_fd_set_cloexec(*slave);
|
|
336 | 336 |
if (no_mesg(SlaveName, nomesg) == -1) { |
337 | 337 |
if (!fail) return -1; |
338 | 338 |
rb_raise(rb_eRuntimeError, "can't chmod slave pty"); |
... | ... | |
348 | 348 |
if (!fail) return -1; |
349 | 349 |
rb_raise(rb_eRuntimeError, "_getpty() failed"); |
350 | 350 |
} |
351 |
rb_update_max_fd(*master);
|
|
351 |
rb_fd_set_cloexec(*master);
|
|
352 | 352 | |
353 | 353 |
*slave = open(name, O_RDWR); |
354 | 354 |
/* error check? */ |
355 |
rb_update_max_fd(*slave);
|
|
355 |
rb_fd_set_cloexec(*slave);
|
|
356 | 356 |
strlcpy(SlaveName, name, DEVICELEN); |
357 | 357 | |
358 | 358 |
return 0; |
... | ... | |
366 | 366 |
extern int grantpt(int); |
367 | 367 | |
368 | 368 |
if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error; |
369 |
rb_update_max_fd(masterfd);
|
|
369 |
rb_fd_set_cloexec(masterfd);
|
|
370 | 370 |
s = signal(SIGCHLD, SIG_DFL); |
371 | 371 |
if(grantpt(masterfd) == -1) goto error; |
372 | 372 |
signal(SIGCHLD, s); |
... | ... | |
374 | 374 |
if((slavedevice = ptsname(masterfd)) == NULL) goto error; |
375 | 375 |
if (no_mesg(slavedevice, nomesg) == -1) goto error; |
376 | 376 |
if((slavefd = open(slavedevice, O_RDWR, 0)) == -1) goto error; |
377 |
rb_update_max_fd(slavefd);
|
|
377 |
rb_fd_set_cloexec(slavefd);
|
|
378 | 378 |
#if defined I_PUSH && !defined linux |
379 | 379 |
if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error; |
380 | 380 |
if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error; |
... | ... | |
398 | 398 |
for (p = deviceNo; *p != NULL; p++) { |
399 | 399 |
snprintf(MasterName, sizeof MasterName, MasterDevice, *p); |
400 | 400 |
if ((masterfd = open(MasterName,O_RDWR,0)) >= 0) { |
401 |
rb_update_max_fd(masterfd);
|
|
401 |
rb_fd_set_cloexec(masterfd);
|
|
402 | 402 |
*master = masterfd; |
403 | 403 |
snprintf(SlaveName, DEVICELEN, SlaveDevice, *p); |
404 | 404 |
if ((slavefd = open(SlaveName,O_RDWR,0)) >= 0) { |
405 |
rb_update_max_fd(slavefd);
|
|
405 |
rb_fd_set_cloexec(slavefd);
|
|
406 | 406 |
*slave = slavefd; |
407 | 407 |
if (chown(SlaveName, getuid(), getgid()) != 0) goto error; |
408 | 408 |
if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error; |
... | ... | |
590 | 590 |
wfptr->fd = dup(info.fd); |
591 | 591 |
if (wfptr->fd == -1) |
592 | 592 |
rb_sys_fail("dup()"); |
593 |
rb_update_max_fd(wfptr->fd);
|
|
593 |
rb_fd_set_cloexec(wfptr->fd);
|
|
594 | 594 |
wfptr->pathv = rfptr->pathv; |
595 | 595 | |
596 | 596 |
res = rb_ary_new2(3); |
ext/openssl/ossl_bio.c (working copy) | ||
---|---|---|
28 | 28 |
if ((fd = dup(FPTR_TO_FD(fptr))) < 0){ |
29 | 29 |
rb_sys_fail(0); |
30 | 30 |
} |
31 |
rb_update_max_fd(fd);
|
|
31 |
rb_fd_set_cloexec(fd);
|
|
32 | 32 |
if (!(fp = fdopen(fd, "r"))){ |
33 | 33 |
close(fd); |
34 | 34 |
rb_sys_fail(0); |
ext/socket/init.c (working copy) | ||
---|---|---|
252 | 252 |
} |
253 | 253 |
} |
254 | 254 |
if (0 <= fd) |
255 |
rb_update_max_fd(fd);
|
|
255 |
rb_fd_set_cloexec(fd);
|
|
256 | 256 |
return fd; |
257 | 257 |
} |
258 | 258 | |
... | ... | |
466 | 466 |
} |
467 | 467 |
rb_sys_fail("accept(2)"); |
468 | 468 |
} |
469 |
rb_update_max_fd(fd2);
|
|
469 |
rb_fd_set_cloexec(fd2);
|
|
470 | 470 |
make_fd_nonblock(fd2); |
471 | 471 |
return rsock_init_sock(rb_obj_alloc(klass), fd2); |
472 | 472 |
} |
... | ... | |
513 | 513 |
} |
514 | 514 |
rb_sys_fail(0); |
515 | 515 |
} |
516 |
rb_update_max_fd(fd2);
|
|
516 |
rb_fd_set_cloexec(fd2);
|
|
517 | 517 |
if (!klass) return INT2NUM(fd2); |
518 | 518 |
return rsock_init_sock(rb_obj_alloc(klass), fd2); |
519 | 519 |
} |
ext/socket/socket.c (working copy) | ||
---|---|---|
119 | 119 |
if (ret < 0) { |
120 | 120 |
rb_sys_fail("socketpair(2)"); |
121 | 121 |
} |
122 |
rb_update_max_fd(sp[0]);
|
|
123 |
rb_update_max_fd(sp[1]);
|
|
122 |
rb_fd_set_cloexec(sp[0]);
|
|
123 |
rb_fd_set_cloexec(sp[1]);
|
|
124 | 124 | |
125 | 125 |
s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]); |
126 | 126 |
s2 = rsock_init_sock(rb_obj_alloc(klass), sp[1]); |
ext/socket/ancdata.c (working copy) | ||
---|---|---|
1396 | 1396 |
int *end = (int *)((char *)cmh + cmh->cmsg_len); |
1397 | 1397 |
while ((char *)fdp + sizeof(int) <= (char *)end && |
1398 | 1398 |
(char *)fdp + sizeof(int) <= msg_end) { |
1399 |
rb_update_max_fd(*fdp);
|
|
1399 |
rb_fd_set_cloexec(*fdp);
|
|
1400 | 1400 |
close(*fdp); |
1401 | 1401 |
fdp++; |
1402 | 1402 |
} |
... | ... | |
1439 | 1439 |
VALUE io; |
1440 | 1440 |
if (fstat(fd, &stbuf) == -1) |
1441 | 1441 |
rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS"); |
1442 |
rb_update_max_fd(fd);
|
|
1442 |
rb_fd_set_cloexec(fd);
|
|
1443 | 1443 |
if (S_ISSOCK(stbuf.st_mode)) |
1444 | 1444 |
io = rsock_init_sock(rb_obj_alloc(rb_cSocket), fd); |
1445 | 1445 |
else |
ext/socket/unixsocket.c (working copy) | ||
---|---|---|
383 | 383 |
#if FD_PASSING_BY_MSG_CONTROL |
384 | 384 |
memcpy(&fd, CMSG_DATA(&cmsg.hdr), sizeof(int)); |
385 | 385 |
#endif |
386 |
rb_update_max_fd(fd);
|
|
386 |
rb_fd_set_cloexec(fd);
|
|
387 | 387 | |
388 | 388 |
if (klass == Qnil) |
389 | 389 |
return INT2FIX(fd); |
ext/io/console/console.c (working copy) | ||
---|---|---|
562 | 562 |
#ifdef CONSOLE_DEVICE_FOR_WRITING |
563 | 563 |
fd = open(CONSOLE_DEVICE_FOR_WRITING, O_WRONLY); |
564 | 564 |
if (fd < 0) return Qnil; |
565 |
rb_update_max_fd(fd);
|
|
565 |
rb_fd_set_cloexec(fd);
|
|
566 | 566 |
args[1] = INT2FIX(O_WRONLY); |
567 | 567 |
args[0] = INT2NUM(fd); |
568 | 568 |
out = rb_class_new_instance(2, args, klass); |
... | ... | |
574 | 574 |
#endif |
575 | 575 |
return Qnil; |
576 | 576 |
} |
577 |
rb_update_max_fd(fd);
|
|
577 |
rb_fd_set_cloexec(fd);
|
|
578 | 578 |
args[1] = INT2FIX(O_RDWR); |
579 | 579 |
args[0] = INT2NUM(fd); |
580 | 580 |
con = rb_class_new_instance(2, args, klass); |
ruby.c (working copy) | ||
---|---|---|
1527 | 1527 |
if ((fd = open(fname, mode)) < 0) { |
1528 | 1528 |
rb_load_fail(fname); |
1529 | 1529 |
} |
1530 |
rb_update_max_fd(fd);
|
|
1530 |
rb_fd_set_cloexec(fd);
|
|
1531 | 1531 | |
1532 | 1532 |
f = rb_io_fdopen(fd, mode, fname); |
1533 | 1533 |
} |
test/ruby/test_io.rb (working copy) | ||
---|---|---|
1261 | 1261 |
def test_close_on_exec |
1262 | 1262 |
skip "IO\#close_on_exec is not implemented." unless have_close_on_exec? |
1263 | 1263 |
ruby do |f| |
1264 |
assert_equal(true, f.close_on_exec?) |
|
1265 |
f.close_on_exec = false |
|
1264 | 1266 |
assert_equal(false, f.close_on_exec?) |
1265 | 1267 |
f.close_on_exec = true |
1266 | 1268 |
assert_equal(true, f.close_on_exec?) |
... | ... | |
1269 | 1271 |
end |
1270 | 1272 | |
1271 | 1273 |
with_pipe do |r, w| |
1274 |
assert_equal(true, r.close_on_exec?) |
|
1275 |
r.close_on_exec = false |
|
1272 | 1276 |
assert_equal(false, r.close_on_exec?) |
1273 | 1277 |
r.close_on_exec = true |
1274 | 1278 |
assert_equal(true, r.close_on_exec?) |
1275 | 1279 |
r.close_on_exec = false |
1276 | 1280 |
assert_equal(false, r.close_on_exec?) |
1277 | 1281 | |
1282 |
assert_equal(true, w.close_on_exec?) |
|
1283 |
w.close_on_exec = false |
|
1278 | 1284 |
assert_equal(false, w.close_on_exec?) |
1279 | 1285 |
w.close_on_exec = true |
1280 | 1286 |
assert_equal(true, w.close_on_exec?) |
test/ruby/test_process.rb (working copy) | ||
---|---|---|
603 | 603 |
def test_fd_inheritance |
604 | 604 |
skip "inheritance of fd other than stdin,stdout and stderr is not supported" if windows? |
605 | 605 |
with_pipe {|r, w| |
606 |
system(RUBY, '-e', 'IO.new(ARGV[0].to_i, "w").puts(:ba)', w.fileno.to_s) |
|
606 |
system(RUBY, '-e', 'IO.new(ARGV[0].to_i, "w").puts(:ba)', w.fileno.to_s, w=>w)
|
|
607 | 607 |
w.close |
608 | 608 |
assert_equal("ba\n", r.read) |
609 | 609 |
} |
... | ... | |
619 | 619 |
write_file("s", <<-"End") |
620 | 620 |
exec(#{RUBY.dump}, '-e', |
621 | 621 |
'IO.new(ARGV[0].to_i, "w").puts("bu") rescue nil', |
622 |
#{w.fileno.to_s.dump}) |
|
622 |
#{w.fileno.to_s.dump}, :close_others=>false)
|
|
623 | 623 |
End |
624 |
w.close_on_exec = false |
|
624 | 625 |
Process.wait spawn(RUBY, "s", :close_others=>false) |
625 | 626 |
w.close |
626 | 627 |
assert_equal("bu\n", r.read) |
... | ... | |
660 | 661 |
File.unlink("err") |
661 | 662 |
} |
662 | 663 |
with_pipe {|r, w| |
664 |
w.close_on_exec = false |
|
663 | 665 |
Process.wait spawn(RUBY, '-e', 'IO.new(ARGV[0].to_i, "w").puts("bi")', w.fileno.to_s, :close_others=>false) |
664 | 666 |
w.close |
665 | 667 |
assert_equal("bi\n", r.read) |
... | ... | |
686 | 688 |
Process.wait |
687 | 689 |
} |
688 | 690 |
with_pipe {|r, w| |
691 |
w.close_on_exec = false |
|
689 | 692 |
io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('mo')", :close_others=>false]) |
690 | 693 |
w.close |
691 | 694 |
errmsg = io.read |
... | ... | |
694 | 697 |
Process.wait |
695 | 698 |
} |
696 | 699 |
with_pipe {|r, w| |
700 |
w.close_on_exec = false |
|
697 | 701 |
io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('mo')", :close_others=>nil]) |
698 | 702 |
w.close |
699 | 703 |
errmsg = io.read |
file.c (working copy) | ||
---|---|---|
3914 | 3914 |
if ((tmpfd = open(StringValueCStr(path), 0)) < 0) { |
3915 | 3915 |
rb_sys_fail(RSTRING_PTR(path)); |
3916 | 3916 |
} |
3917 |
rb_update_max_fd(tmpfd);
|
|
3917 |
rb_fd_set_cloexec(tmpfd);
|
|
3918 | 3918 |
if (chsize(tmpfd, pos) < 0) { |
3919 | 3919 |
close(tmpfd); |
3920 | 3920 |
rb_sys_fail(RSTRING_PTR(path)); |
... | ... | |
5062 | 5062 |
int ret = 1; |
5063 | 5063 |
int fd = open(path, O_RDONLY); |
5064 | 5064 |
if (fd == -1) return 0; |
5065 |
rb_update_max_fd(fd);
|
|
5065 |
rb_fd_set_cloexec(fd);
|
|
5066 | 5066 |
#if !defined DOSISH |
5067 | 5067 |
{ |
5068 | 5068 |
struct stat st; |
random.c (working copy) | ||
---|---|---|
512 | 512 |
|O_NOCTTY |
513 | 513 |
#endif |
514 | 514 |
)) >= 0) { |
515 |
rb_update_max_fd(fd);
|
|
515 |
rb_fd_set_cloexec(fd);
|
|
516 | 516 |
if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) { |
517 | 517 |
if (read(fd, seed, DEFAULT_SEED_LEN) < DEFAULT_SEED_LEN) { |
518 | 518 |
/* abandon */; |