This project is closed and read-only.
Backport #5075 » 5075-1.9.2.patch
| include/ruby/intern.h (working copy) | ||
|---|---|---|
|
void rb_write_error2(const char*, long);
|
||
|
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds);
|
||
|
int rb_pipe(int *pipes);
|
||
|
void rb_update_max_fd(int fd);
|
||
|
/* marshal.c */
|
||
|
VALUE rb_marshal_dump(VALUE, VALUE);
|
||
|
VALUE rb_marshal_load(VALUE);
|
||
| ChangeLog (working copy) | ||
|---|---|---|
|
Sun Jul 24 22:47:10 2011 Tanaka Akira <akr@fsij.org>
|
||
|
* backport r32579, r32581, r32587, r32588, r32598, r32638, r32655,
|
||
|
r32656, r32657 from trunk.
|
||
|
r32579:
|
||
|
* io.c (rb_update_max_fd): new function.
|
||
|
r32581:
|
||
|
* io.c (UPDATE_MAXFD): removed.
|
||
|
r32587:
|
||
|
* include/ruby/intern.h (rb_update_max_fd): declared.
|
||
|
|
||
|
* file.c: ditto.
|
||
|
|
||
|
* io.c: call rb_update_max_fd for each new fds.
|
||
|
|
||
|
* process.c: ditto.
|
||
|
|
||
|
* random.c: ditto.
|
||
|
|
||
|
* ruby.c: ditto.
|
||
|
|
||
|
* ext/openssl/ossl_bio.c: ditto.
|
||
|
|
||
|
* ext/pty/pty.c: ditto.
|
||
|
|
||
|
* ext/socket/init.c: ditto.
|
||
|
|
||
|
* ext/socket/socket.c: ditto.
|
||
|
|
||
|
* ext/socket/ancdata.c: ditto.
|
||
|
|
||
|
* ext/socket/unixsocket.c: ditto.
|
||
|
r32588:
|
||
|
* io.c (rb_update_max_fd): remove parentheses. they are not in
|
||
|
macro.
|
||
|
r32598:
|
||
|
* ext/socket/ancdata.c (discard_cmsg): workaround for MacOS X Lion.
|
||
|
r32638:
|
||
|
* io.c (rb_update_max_fd): validate fd.
|
||
|
|
||
|
* ext/socket/rubysocket.h (rsock_discard_cmsg_resource): add
|
||
|
msg_peek_p argument for the declaration.
|
||
|
|
||
|
* ext/socket/ancdata.c (discard_cmsg): add msg_peek_p argument.
|
||
|
assume FreeBSD, NetBSD and MacOS X doesn't generate passed fd
|
||
|
when MSG_PEEK.
|
||
|
(rsock_discard_cmsg_resource): add msg_peek_p argument.
|
||
|
(bsock_recvmsg_internal): call rsock_discard_cmsg_resource with
|
||
|
msg_peek_p argument.
|
||
|
|
||
|
* ext/socket/unixsocket.c (unix_recv_io): call
|
||
|
rsock_discard_cmsg_resource with msg_peek_p argument.
|
||
|
r32655:
|
||
|
* ext/socket/extconf.rb: test recvmsg allocates file descriptors for
|
||
|
fd passing even with MSG_PEEK.
|
||
|
|
||
|
* ext/socket/ancdata.c: use the above test result.
|
||
|
r32656:
|
||
|
* ext/socket/extconf.rb: fix the recvmsg test.
|
||
|
r32657:
|
||
|
* ext/socket/extconf.rb: refine the recvmsg test.
|
||
|
Sat Jul 9 19:25:02 2011 Yuki Sonoda (Yugui) <yugui@yugui.jp>
|
||
|
* ext/tk/extconf.rb: I gave up to fix the build issue of ext/tk with Windows
|
||
| io.c (working copy) | ||
|---|---|---|
|
};
|
||
|
static int max_file_descriptor = NOFILE;
|
||
|
#define UPDATE_MAXFD(fd) \
|
||
|
do { \
|
||
|
if (max_file_descriptor < (fd)) max_file_descriptor = (fd); \
|
||
|
} while (0)
|
||
|
void
|
||
|
rb_update_max_fd(int fd)
|
||
|
{
|
||
|
struct stat buf;
|
||
|
if (fstat(fd, &buf) != 0) {
|
||
|
rb_bug("rb_update_max_fd: invalid fd (%d) given.", fd);
|
||
|
}
|
||
|
if (max_file_descriptor < fd) max_file_descriptor = fd;
|
||
|
}
|
||
|
#define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
|
||
|
#define ARGF argf_of(argf)
|
||
| ... | ... | |
|
rb_sys_fail(0);
|
||
|
}
|
||
|
}
|
||
|
UPDATE_MAXFD(fd);
|
||
|
rb_update_max_fd(fd);
|
||
|
return fd;
|
||
|
}
|
||
| ... | ... | |
|
static inline int
|
||
|
rb_sysopen_internal(struct sysopen_struct *data)
|
||
|
{
|
||
|
return (int)rb_thread_blocking_region(sysopen_func, data, RUBY_UBF_IO, 0);
|
||
|
int fd;
|
||
|
fd = (int)rb_thread_blocking_region(sysopen_func, data, RUBY_UBF_IO, 0);
|
||
|
if (0 <= fd)
|
||
|
rb_update_max_fd(fd);
|
||
|
return fd;
|
||
|
}
|
||
|
static int
|
||
| ... | ... | |
|
rb_sys_fail(RSTRING_PTR(fname));
|
||
|
}
|
||
|
}
|
||
|
UPDATE_MAXFD(fd);
|
||
|
rb_update_max_fd(fd);
|
||
|
return fd;
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
if (ret == 0) {
|
||
|
UPDATE_MAXFD(pipes[0]);
|
||
|
UPDATE_MAXFD(pipes[1]);
|
||
|
rb_update_max_fd(pipes[0]);
|
||
|
rb_update_max_fd(pipes[1]);
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
| ... | ... | |
|
/* need to keep FILE objects of stdin, stdout and stderr */
|
||
|
if (dup2(fd2, fd) < 0)
|
||
|
rb_sys_fail_path(orig->pathv);
|
||
|
rb_update_max_fd(fd);
|
||
|
}
|
||
|
else {
|
||
|
fclose(fptr->stdio_file);
|
||
| ... | ... | |
|
fptr->fd = -1;
|
||
|
if (dup2(fd2, fd) < 0)
|
||
|
rb_sys_fail_path(orig->pathv);
|
||
|
rb_update_max_fd(fd);
|
||
|
fptr->fd = fd;
|
||
|
}
|
||
|
rb_thread_fd_close(fd);
|
||
| ... | ... | |
|
fp->mode = fmode;
|
||
|
io_check_tty(fp);
|
||
|
if (path) fp->pathv = rb_obj_freeze(rb_str_new_cstr(path));
|
||
|
rb_update_max_fd(fd);
|
||
|
return io;
|
||
|
}
|
||
| ... | ... | |
|
#else
|
||
|
if (fstat(fd, &st) == -1) rb_sys_fail(0);
|
||
|
#endif
|
||
|
UPDATE_MAXFD(fd);
|
||
|
rb_update_max_fd(fd);
|
||
|
#if defined(HAVE_FCNTL) && defined(F_GETFL)
|
||
|
ofmode = rb_io_oflags_fmode(oflags);
|
||
|
if (NIL_P(vmode)) {
|
||
| ... | ... | |
|
# endif
|
||
|
# if defined(F_DUPFD)
|
||
|
if (!io_p && retval != -1 && cmd == F_DUPFD) {
|
||
|
UPDATE_MAXFD(retval);
|
||
|
rb_update_max_fd(retval);
|
||
|
}
|
||
|
# endif
|
||
|
#else
|
||
| process.c (working copy) | ||
|---|---|---|
|
ERRMSG("dup");
|
||
|
return -1;
|
||
|
}
|
||
|
rb_update_max_fd(save_fd);
|
||
|
newary = rb_ary_entry(save, EXEC_OPTION_DUP2);
|
||
|
if (NIL_P(newary)) {
|
||
|
newary = hide_obj(rb_ary_new());
|
||
| ... | ... | |
|
ERRMSG("dup2");
|
||
|
goto fail;
|
||
|
}
|
||
|
rb_update_max_fd(pairs[j].newfd);
|
||
|
pairs[j].oldfd = -1;
|
||
|
j = pairs[j].older_index;
|
||
|
if (j != -1)
|
||
| ... | ... | |
|
ERRMSG("dup");
|
||
|
goto fail;
|
||
|
}
|
||
|
rb_update_max_fd(extra_fd);
|
||
|
}
|
||
|
else {
|
||
|
ret = redirect_dup2(pairs[i].oldfd, extra_fd);
|
||
| ... | ... | |
|
ERRMSG("dup2");
|
||
|
goto fail;
|
||
|
}
|
||
|
rb_update_max_fd(extra_fd);
|
||
|
}
|
||
|
pairs[i].oldfd = extra_fd;
|
||
|
j = pairs[i].older_index;
|
||
| ... | ... | |
|
ERRMSG("dup2");
|
||
|
goto fail;
|
||
|
}
|
||
|
rb_update_max_fd(ret);
|
||
|
pairs[j].oldfd = -1;
|
||
|
j = pairs[j].older_index;
|
||
|
}
|
||
| ... | ... | |
|
ERRMSG("open");
|
||
|
return -1;
|
||
|
}
|
||
|
rb_update_max_fd(fd2);
|
||
|
while (i < RARRAY_LEN(ary) &&
|
||
|
(elt = RARRAY_PTR(ary)[i], RARRAY_PTR(elt)[1] == param)) {
|
||
|
fd = FIX2INT(RARRAY_PTR(elt)[0]);
|
||
| ... | ... | |
|
ERRMSG("dup2");
|
||
|
return -1;
|
||
|
}
|
||
|
rb_update_max_fd(fd);
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
| ... | ... | |
|
ERRMSG("dup2");
|
||
|
return -1;
|
||
|
}
|
||
|
rb_update_max_fd(newfd);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
| ... | ... | |
|
ret = fcntl(fdp[i], F_DUPFD, min);
|
||
|
if (ret == -1)
|
||
|
return -1;
|
||
|
rb_update_max_fd(ret);
|
||
|
close(fdp[i]);
|
||
|
fdp[i] = ret;
|
||
|
}
|
||
| ... | ... | |
|
if (ret == -1) return -1;
|
||
|
if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
|
||
|
rb_update_max_fd(fd);
|
||
|
ioctl(fd, TIOCNOTTY, NULL);
|
||
|
close(fd);
|
||
|
}
|
||
| ext/pty/pty.c (working copy) | ||
|---|---|---|
|
{
|
||
|
int i = open("/dev/tty", O_RDONLY);
|
||
|
if (i < 0) rb_sys_fail("/dev/tty");
|
||
|
rb_update_max_fd(i);
|
||
|
if (ioctl(i, TIOCNOTTY, (char *)0))
|
||
|
perror("ioctl(TIOCNOTTY)");
|
||
|
close(i);
|
||
| ... | ... | |
|
perror("open: pty slave");
|
||
|
_exit(1);
|
||
|
}
|
||
|
rb_update_max_fd(slave);
|
||
|
close(master);
|
||
|
#endif
|
||
|
write(slave, "", 1);
|
||
| ... | ... | |
|
sigemptyset(&dfl.sa_mask);
|
||
|
if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
|
||
|
rb_update_max_fd(masterfd);
|
||
|
if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
|
||
|
if (grantpt(masterfd) == -1) goto grantpt_error;
|
||
|
if (sigaction(SIGCHLD, &old, NULL) == -1) goto error;
|
||
| ... | ... | |
|
if ((slavedevice = ptsname(masterfd)) == NULL) goto error;
|
||
|
if (no_mesg(slavedevice, nomesg) == -1) goto error;
|
||
|
if ((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error;
|
||
|
rb_update_max_fd(slavefd);
|
||
|
#if defined I_PUSH && !defined linux
|
||
|
if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
|
||
| ... | ... | |
|
if (!fail) return -1;
|
||
|
rb_raise(rb_eRuntimeError, "openpty() failed");
|
||
|
}
|
||
|
rb_update_max_fd(*master);
|
||
|
rb_update_max_fd(*slave);
|
||
|
if (no_mesg(SlaveName, nomesg) == -1) {
|
||
|
if (!fail) return -1;
|
||
|
rb_raise(rb_eRuntimeError, "can't chmod slave pty");
|
||
| ... | ... | |
|
if (!fail) return -1;
|
||
|
rb_raise(rb_eRuntimeError, "_getpty() failed");
|
||
|
}
|
||
|
rb_update_max_fd(*master);
|
||
|
*slave = open(name, O_RDWR);
|
||
|
/* error check? */
|
||
|
rb_update_max_fd(*slave);
|
||
|
strlcpy(SlaveName, name, DEVICELEN);
|
||
|
return 0;
|
||
| ... | ... | |
|
extern int grantpt(int);
|
||
|
if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
|
||
|
rb_update_max_fd(masterfd);
|
||
|
s = signal(SIGCHLD, SIG_DFL);
|
||
|
if(grantpt(masterfd) == -1) goto error;
|
||
|
signal(SIGCHLD, s);
|
||
| ... | ... | |
|
if((slavedevice = ptsname(masterfd)) == NULL) goto error;
|
||
|
if (no_mesg(slavedevice, nomesg) == -1) goto error;
|
||
|
if((slavefd = open(slavedevice, O_RDWR, 0)) == -1) goto error;
|
||
|
rb_update_max_fd(slavefd);
|
||
|
#if defined I_PUSH && !defined linux
|
||
|
if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
|
||
|
if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
|
||
| ... | ... | |
|
for (p = deviceNo; *p != NULL; p++) {
|
||
|
snprintf(MasterName, sizeof MasterName, MasterDevice, *p);
|
||
|
if ((masterfd = open(MasterName,O_RDWR,0)) >= 0) {
|
||
|
rb_update_max_fd(masterfd);
|
||
|
*master = masterfd;
|
||
|
snprintf(SlaveName, DEVICELEN, SlaveDevice, *p);
|
||
|
if ((slavefd = open(SlaveName,O_RDWR,0)) >= 0) {
|
||
|
rb_update_max_fd(slavefd);
|
||
|
*slave = slavefd;
|
||
|
if (chown(SlaveName, getuid(), getgid()) != 0) goto error;
|
||
|
if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error;
|
||
| ... | ... | |
|
wfptr->fd = dup(info.fd);
|
||
|
if (wfptr->fd == -1)
|
||
|
rb_sys_fail("dup()");
|
||
|
rb_update_max_fd(wfptr->fd);
|
||
|
wfptr->pathv = rfptr->pathv;
|
||
|
res = rb_ary_new2(3);
|
||
| ext/openssl/ossl_bio.c (working copy) | ||
|---|---|---|
|
if ((fd = dup(FPTR_TO_FD(fptr))) < 0){
|
||
|
rb_sys_fail(0);
|
||
|
}
|
||
|
rb_update_max_fd(fd);
|
||
|
if (!(fp = fdopen(fd, "r"))){
|
||
|
close(fd);
|
||
|
rb_sys_fail(0);
|
||
| ext/socket/rubysocket.h (working copy) | ||
|---|---|---|
|
#endif
|
||
|
#ifdef HAVE_ST_MSG_CONTROL
|
||
|
void rsock_discard_cmsg_resource(struct msghdr *mh);
|
||
|
void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p);
|
||
|
#endif
|
||
|
void rsock_init_basicsocket(void);
|
||
| ext/socket/init.c (working copy) | ||
|---|---|---|
|
#ifndef _WIN32
|
||
|
if (fstat(fd, &sbuf) < 0)
|
||
|
rb_sys_fail(0);
|
||
|
rb_update_max_fd(fd);
|
||
|
if (!S_ISSOCK(sbuf.st_mode))
|
||
|
rb_raise(rb_eArgError, "not a socket file descriptor");
|
||
|
#else
|
||
| ... | ... | |
|
fd = socket(domain, type, proto);
|
||
|
}
|
||
|
}
|
||
|
if (0 <= fd)
|
||
|
rb_update_max_fd(fd);
|
||
|
return fd;
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
rb_sys_fail("accept(2)");
|
||
|
}
|
||
|
rb_update_max_fd(fd2);
|
||
|
make_fd_nonblock(fd2);
|
||
|
return rsock_init_sock(rb_obj_alloc(klass), fd2);
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
rb_sys_fail(0);
|
||
|
}
|
||
|
rb_update_max_fd(fd2);
|
||
|
if (!klass) return INT2NUM(fd2);
|
||
|
return rsock_init_sock(rb_obj_alloc(klass), fd2);
|
||
|
}
|
||
| ext/socket/extconf.rb (working copy) | ||
|---|---|---|
|
have_type("PADDRINFO", %w[ ws2tcpip.h wspiapi.h ])
|
||
|
if checking_for("recvmsg() with MSG_PEEK allocate file descriptors") {try_run(cpp_include(headers) + <<'EOF')}
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <sys/socket.h>
|
||
|
#include <sys/un.h>
|
||
|
#include <unistd.h>
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
int ps[2], sv[2];
|
||
|
int ret;
|
||
|
ssize_t ss;
|
||
|
int s_fd, r_fd;
|
||
|
struct msghdr s_msg, r_msg;
|
||
|
union {
|
||
|
struct cmsghdr hdr;
|
||
|
char dummy[CMSG_SPACE(sizeof(int))];
|
||
|
} s_cmsg, r_cmsg;
|
||
|
struct iovec s_iov, r_iov;
|
||
|
char s_buf[1], r_buf[1];
|
||
|
struct stat s_statbuf, r_statbuf;
|
||
|
ret = pipe(ps);
|
||
|
if (ret == -1) { perror("pipe"); exit(EXIT_FAILURE); }
|
||
|
s_fd = ps[0];
|
||
|
ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv);
|
||
|
if (ret == -1) { perror("socketpair"); exit(EXIT_FAILURE); }
|
||
|
s_msg.msg_name = NULL;
|
||
|
s_msg.msg_namelen = 0;
|
||
|
s_msg.msg_iov = &s_iov;
|
||
|
s_msg.msg_iovlen = 1;
|
||
|
s_msg.msg_control = &s_cmsg;
|
||
|
s_msg.msg_controllen = CMSG_SPACE(sizeof(int));;
|
||
|
s_msg.msg_flags = 0;
|
||
|
s_iov.iov_base = &s_buf;
|
||
|
s_iov.iov_len = sizeof(s_buf);
|
||
|
s_buf[0] = 'a';
|
||
|
s_cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));
|
||
|
s_cmsg.hdr.cmsg_level = SOL_SOCKET;
|
||
|
s_cmsg.hdr.cmsg_type = SCM_RIGHTS;
|
||
|
memcpy(CMSG_DATA(&s_cmsg.hdr), (char *)&s_fd, sizeof(int));
|
||
|
ss = sendmsg(sv[0], &s_msg, 0);
|
||
|
if (ss == -1) { perror("sendmsg"); exit(EXIT_FAILURE); }
|
||
|
r_msg.msg_name = NULL;
|
||
|
r_msg.msg_namelen = 0;
|
||
|
r_msg.msg_iov = &r_iov;
|
||
|
r_msg.msg_iovlen = 1;
|
||
|
r_msg.msg_control = &r_cmsg;
|
||
|
r_msg.msg_controllen = CMSG_SPACE(sizeof(int));
|
||
|
r_msg.msg_flags = 0;
|
||
|
r_iov.iov_base = &r_buf;
|
||
|
r_iov.iov_len = sizeof(r_buf);
|
||
|
r_buf[0] = '0';
|
||
|
memset(&r_cmsg, 0xff, CMSG_SPACE(sizeof(int)));
|
||
|
ss = recvmsg(sv[1], &r_msg, MSG_PEEK);
|
||
|
if (ss == -1) { perror("recvmsg"); exit(EXIT_FAILURE); }
|
||
|
if (ss != 1) {
|
||
|
fprintf(stderr, "unexpected return value from recvmsg: %ld\n", (long)ss);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
if (r_buf[0] != 'a') {
|
||
|
fprintf(stderr, "unexpected return data from recvmsg: 0x%02x\n", r_buf[0]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
if (r_msg.msg_controllen < CMSG_LEN(sizeof(int))) {
|
||
|
fprintf(stderr, "unexpected: r_msg.msg_controllen < CMSG_LEN(sizeof(int)) not hold: %ld\n",
|
||
|
(long)r_msg.msg_controllen);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
if (r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int))) {
|
||
|
fprintf(stderr, "unexpected: r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int)) not hold: %ld\n",
|
||
|
(long)r_cmsg.hdr.cmsg_len);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
memcpy((char *)&r_fd, CMSG_DATA(&r_cmsg.hdr), sizeof(int));
|
||
|
if (r_fd < 0) {
|
||
|
fprintf(stderr, "negative r_fd: %d\n", r_fd);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
if (r_fd == s_fd) {
|
||
|
fprintf(stderr, "r_fd and s_fd is same: %d\n", r_fd);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
ret = fstat(s_fd, &s_statbuf);
|
||
|
if (ret == -1) { perror("fstat(s_fd)"); exit(EXIT_FAILURE); }
|
||
|
ret = fstat(r_fd, &r_statbuf);
|
||
|
if (ret == -1) { perror("fstat(r_fd)"); exit(EXIT_FAILURE); }
|
||
|
if (s_statbuf.st_dev != r_statbuf.st_dev ||
|
||
|
s_statbuf.st_ino != r_statbuf.st_ino) {
|
||
|
fprintf(stderr, "dev/ino doesn't match: s_fd:%ld/%ld r_fd:%ld/%ld\n",
|
||
|
(long)s_statbuf.st_dev, (long)s_statbuf.st_ino,
|
||
|
(long)r_statbuf.st_dev, (long)r_statbuf.st_ino);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|
||
|
EOF
|
||
|
$defs << "-DFD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK"
|
||
|
end
|
||
|
getaddr_info_ok = (enable_config("wide-getaddrinfo") && :wide) ||
|
||
|
(checking_for("wide getaddrinfo") {try_run(<<EOF)} && :os)
|
||
|
#{cpp_include(headers)}
|
||
| ext/socket/socket.c (working copy) | ||
|---|---|---|
|
if (ret < 0) {
|
||
|
rb_sys_fail("socketpair(2)");
|
||
|
}
|
||
|
rb_update_max_fd(sp[0]);
|
||
|
rb_update_max_fd(sp[1]);
|
||
|
s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]);
|
||
|
s2 = rsock_init_sock(rb_obj_alloc(klass), sp[1]);
|
||
| ext/socket/ancdata.c (working copy) | ||
|---|---|---|
|
#if defined(HAVE_ST_MSG_CONTROL)
|
||
|
static void
|
||
|
discard_cmsg(struct cmsghdr *cmh, char *msg_end)
|
||
|
discard_cmsg(struct cmsghdr *cmh, char *msg_end, int msg_peek_p)
|
||
|
{
|
||
|
# if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
|
||
|
/*
|
||
|
* FreeBSD 8.2.0, NetBSD 5 and MacOS X Snow Leopard doesn't
|
||
|
* allocate fds by recvmsg with MSG_PEEK.
|
||
|
* [ruby-dev:44189]
|
||
|
* http://redmine.ruby-lang.org/issues/5075
|
||
|
*
|
||
|
* Linux 2.6.38 allocate fds by recvmsg with MSG_PEEK.
|
||
|
*/
|
||
|
if (msg_peek_p)
|
||
|
return;
|
||
|
# endif
|
||
|
if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
|
||
|
int *fdp = (int *)CMSG_DATA(cmh);
|
||
|
int *end = (int *)((char *)cmh + cmh->cmsg_len);
|
||
|
while ((char *)fdp + sizeof(int) <= (char *)end &&
|
||
|
(char *)fdp + sizeof(int) <= msg_end) {
|
||
|
rb_update_max_fd(*fdp);
|
||
|
close(*fdp);
|
||
|
fdp++;
|
||
|
}
|
||
| ... | ... | |
|
#endif
|
||
|
void
|
||
|
rsock_discard_cmsg_resource(struct msghdr *mh)
|
||
|
rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p)
|
||
|
{
|
||
|
#if defined(HAVE_ST_MSG_CONTROL)
|
||
|
struct cmsghdr *cmh;
|
||
| ... | ... | |
|
msg_end = (char *)mh->msg_control + mh->msg_controllen;
|
||
|
for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
|
||
|
discard_cmsg(cmh, msg_end);
|
||
|
discard_cmsg(cmh, msg_end, msg_peek_p);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
| ... | ... | |
|
VALUE io;
|
||
|
if (fstat(fd, &stbuf) == -1)
|
||
|
rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS");
|
||
|
rb_update_max_fd(fd);
|
||
|
if (S_ISSOCK(stbuf.st_mode))
|
||
|
io = rsock_init_sock(rb_obj_alloc(rb_cSocket), fd);
|
||
|
else
|
||
| ... | ... | |
|
/* there are big space bug truncated.
|
||
|
* file descriptors limit? */
|
||
|
if (!gc_done) {
|
||
|
rsock_discard_cmsg_resource(&mh);
|
||
|
rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
|
||
|
goto gc_and_retry;
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
#endif
|
||
|
if (grown) {
|
||
|
rsock_discard_cmsg_resource(&mh);
|
||
|
rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
|
||
|
goto retry;
|
||
|
}
|
||
|
else {
|
||
|
grow_buffer = 0;
|
||
|
if (flags != orig_flags) {
|
||
|
rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
|
||
|
flags = orig_flags;
|
||
|
rsock_discard_cmsg_resource(&mh);
|
||
|
goto retry;
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
if (request_scm_rights)
|
||
|
make_io_for_unix_rights(ctl, cmh, msg_end);
|
||
|
else
|
||
|
discard_cmsg(cmh, msg_end);
|
||
|
discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
|
||
|
rb_ary_push(ret, ctl);
|
||
|
}
|
||
|
}
|
||
| ext/socket/unixsocket.c (working copy) | ||
|---|---|---|
|
(int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
|
||
|
}
|
||
|
if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
|
||
|
rsock_discard_cmsg_resource(&arg.msg);
|
||
|
rsock_discard_cmsg_resource(&arg.msg, 0);
|
||
|
rb_raise(rb_eSocket,
|
||
|
"file descriptor was not passed (cmsg_len=%d, %d expected)",
|
||
|
(int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
|
||
| ... | ... | |
|
#if FD_PASSING_BY_MSG_CONTROL
|
||
|
memcpy(&fd, CMSG_DATA(&cmsg.hdr), sizeof(int));
|
||
|
#endif
|
||
|
rb_update_max_fd(fd);
|
||
|
if (klass == Qnil)
|
||
|
return INT2FIX(fd);
|
||
| ruby.c (working copy) | ||
|---|---|---|
|
if ((fd = open(fname, mode)) < 0) {
|
||
|
rb_load_fail(fname);
|
||
|
}
|
||
|
rb_update_max_fd(fd);
|
||
|
f = rb_io_fdopen(fd, mode, fname);
|
||
|
}
|
||
| file.c (working copy) | ||
|---|---|---|
|
if ((tmpfd = open(StringValueCStr(path), 0)) < 0) {
|
||
|
rb_sys_fail(RSTRING_PTR(path));
|
||
|
}
|
||
|
rb_update_max_fd(tmpfd);
|
||
|
if (chsize(tmpfd, pos) < 0) {
|
||
|
close(tmpfd);
|
||
|
rb_sys_fail(RSTRING_PTR(path));
|
||
| ... | ... | |
|
int ret = 1;
|
||
|
int fd = open(path, O_RDONLY);
|
||
|
if (fd == -1) return 0;
|
||
|
rb_update_max_fd(fd);
|
||
|
#if !defined DOSISH
|
||
|
{
|
||
|
struct stat st;
|
||
| random.c (working copy) | ||
|---|---|---|
|
|O_NOCTTY
|
||
|
#endif
|
||
|
)) >= 0) {
|
||
|
rb_update_max_fd(fd);
|
||
|
if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
|
||
|
(void)read(fd, seed, DEFAULT_SEED_LEN);
|
||
|
}
|
||
- « Previous
- 1
- 2
- Next »