Project

General

Profile

Backport #5075 ยป 5075-1.9.2.patch

akr (Akira Tanaka), 07/24/2011 11:22 PM

View differences:

include/ruby/intern.h (working copy)
439 439
void rb_write_error2(const char*, long);
440 440
void rb_close_before_exec(int lowfd, int maxhint, VALUE noclose_fds);
441 441
int rb_pipe(int *pipes);
442
void rb_update_max_fd(int fd);
442 443
/* marshal.c */
443 444
VALUE rb_marshal_dump(VALUE, VALUE);
444 445
VALUE rb_marshal_load(VALUE);
ChangeLog (working copy)
1
Sun Jul 24 22:47:10 2011  Tanaka Akira  <akr@fsij.org>
2

  
3
	* backport r32579, r32581, r32587, r32588, r32598, r32638, r32655,
4
	  r32656, r32657 from trunk.
5

  
6
	r32579:
7
	* io.c (rb_update_max_fd): new function.
8

  
9
	r32581:
10
	* io.c (UPDATE_MAXFD): removed.
11

  
12
	r32587:
13
	* include/ruby/intern.h (rb_update_max_fd): declared.
14
	
15
	* file.c: ditto.
16
	
17
	* io.c: call rb_update_max_fd for each new fds.
18
	
19
	* process.c: ditto.
20
	
21
	* random.c: ditto.
22
	
23
	* ruby.c: ditto.
24
	
25
	* ext/openssl/ossl_bio.c: ditto.
26
	
27
	* ext/pty/pty.c: ditto.
28
	
29
	* ext/socket/init.c: ditto.
30
	
31
	* ext/socket/socket.c: ditto.
32
	
33
	* ext/socket/ancdata.c: ditto.
34
	
35
	* ext/socket/unixsocket.c: ditto.
36

  
37
	r32588:
38
	* io.c (rb_update_max_fd): remove parentheses. they are not in
39
	  macro.
40

  
41
	r32598:
42
	* ext/socket/ancdata.c (discard_cmsg): workaround for MacOS X Lion.
43

  
44
	r32638:
45
	* io.c (rb_update_max_fd): validate fd.
46
	
47
	* ext/socket/rubysocket.h (rsock_discard_cmsg_resource): add
48
	  msg_peek_p argument for the declaration.
49
	
50
	* ext/socket/ancdata.c (discard_cmsg): add msg_peek_p argument.
51
	  assume FreeBSD, NetBSD and MacOS X doesn't generate passed fd
52
	  when MSG_PEEK. 
53
	  (rsock_discard_cmsg_resource): add msg_peek_p argument.
54
	  (bsock_recvmsg_internal): call rsock_discard_cmsg_resource with
55
	  msg_peek_p argument.
56
	
57
	* ext/socket/unixsocket.c (unix_recv_io): call
58
	  rsock_discard_cmsg_resource with msg_peek_p argument.
59

  
60
	r32655:
61
	* ext/socket/extconf.rb: test recvmsg allocates file descriptors for
62
	  fd passing even with MSG_PEEK.
63
	
64
	* ext/socket/ancdata.c: use the above test result.
65

  
66
	r32656:
67
	* ext/socket/extconf.rb: fix the recvmsg test.
68

  
69
	r32657:
70
	* ext/socket/extconf.rb: refine the recvmsg test.
71

  
1 72
Sat Jul  9 19:25:02 2011  Yuki Sonoda (Yugui)  <yugui@yugui.jp>
2 73

  
3 74
	* ext/tk/extconf.rb: I gave up to fix the build issue of ext/tk with Windows
io.c (working copy)
155 155
};
156 156

  
157 157
static int max_file_descriptor = NOFILE;
158
#define UPDATE_MAXFD(fd) \
159
    do { \
160
        if (max_file_descriptor < (fd)) max_file_descriptor = (fd); \
161
    } while (0)
158
void
159
rb_update_max_fd(int fd)
160
{
161
    struct stat buf;
162
    if (fstat(fd, &buf) != 0) {
163
        rb_bug("rb_update_max_fd: invalid fd (%d) given.", fd);
164
    }
165
    if (max_file_descriptor < fd) max_file_descriptor = fd;
166
}
162 167

  
163 168
#define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
164 169
#define ARGF argf_of(argf)
......
514 519
	    rb_sys_fail(0);
515 520
	}
516 521
    }
517
    UPDATE_MAXFD(fd);
522
    rb_update_max_fd(fd);
518 523
    return fd;
519 524
}
520 525

  
......
4528 4533
static inline int
4529 4534
rb_sysopen_internal(struct sysopen_struct *data)
4530 4535
{
4531
    return (int)rb_thread_blocking_region(sysopen_func, data, RUBY_UBF_IO, 0);
4536
    int fd;
4537
    fd = (int)rb_thread_blocking_region(sysopen_func, data, RUBY_UBF_IO, 0);
4538
    if (0 <= fd)
4539
        rb_update_max_fd(fd);
4540
    return fd;
4532 4541
}
4533 4542

  
4534 4543
static int
......
4554 4563
	    rb_sys_fail(RSTRING_PTR(fname));
4555 4564
	}
4556 4565
    }
4557
    UPDATE_MAXFD(fd);
4566
    rb_update_max_fd(fd);
4558 4567
    return fd;
4559 4568
}
4560 4569

  
......
4846 4855
        }
4847 4856
    }
4848 4857
    if (ret == 0) {
4849
        UPDATE_MAXFD(pipes[0]);
4850
        UPDATE_MAXFD(pipes[1]);
4858
        rb_update_max_fd(pipes[0]);
4859
        rb_update_max_fd(pipes[1]);
4851 4860
    }
4852 4861
    return ret;
4853 4862
}
......
5740 5749
	    /* need to keep FILE objects of stdin, stdout and stderr */
5741 5750
	    if (dup2(fd2, fd) < 0)
5742 5751
		rb_sys_fail_path(orig->pathv);
5752
            rb_update_max_fd(fd);
5743 5753
	}
5744 5754
	else {
5745 5755
            fclose(fptr->stdio_file);
......
5747 5757
            fptr->fd = -1;
5748 5758
            if (dup2(fd2, fd) < 0)
5749 5759
                rb_sys_fail_path(orig->pathv);
5760
            rb_update_max_fd(fd);
5750 5761
            fptr->fd = fd;
5751 5762
	}
5752 5763
	rb_thread_fd_close(fd);
......
6325 6336
    fp->mode = fmode;
6326 6337
    io_check_tty(fp);
6327 6338
    if (path) fp->pathv = rb_obj_freeze(rb_str_new_cstr(path));
6339
    rb_update_max_fd(fd);
6328 6340

  
6329 6341
    return io;
6330 6342
}
......
6473 6485
#else
6474 6486
    if (fstat(fd, &st) == -1) rb_sys_fail(0);
6475 6487
#endif
6476
    UPDATE_MAXFD(fd);
6488
    rb_update_max_fd(fd);
6477 6489
#if defined(HAVE_FCNTL) && defined(F_GETFL)
6478 6490
    ofmode = rb_io_oflags_fmode(oflags);
6479 6491
    if (NIL_P(vmode)) {
......
7378 7390
# endif
7379 7391
# if defined(F_DUPFD)
7380 7392
    if (!io_p && retval != -1 && cmd == F_DUPFD) {
7381
        UPDATE_MAXFD(retval);
7393
	rb_update_max_fd(retval);
7382 7394
    }
7383 7395
# endif
7384 7396
#else
process.c (working copy)
1868 1868
            ERRMSG("dup");
1869 1869
            return -1;
1870 1870
        }
1871
        rb_update_max_fd(save_fd);
1871 1872
        newary = rb_ary_entry(save, EXEC_OPTION_DUP2);
1872 1873
        if (NIL_P(newary)) {
1873 1874
            newary = hide_obj(rb_ary_new());
......
1984 1985
                ERRMSG("dup2");
1985 1986
                goto fail;
1986 1987
            }
1988
            rb_update_max_fd(pairs[j].newfd);
1987 1989
            pairs[j].oldfd = -1;
1988 1990
            j = pairs[j].older_index;
1989 1991
            if (j != -1)
......
2022 2024
                ERRMSG("dup");
2023 2025
                goto fail;
2024 2026
            }
2027
            rb_update_max_fd(extra_fd);
2025 2028
        }
2026 2029
        else {
2027 2030
            ret = redirect_dup2(pairs[i].oldfd, extra_fd);
......
2029 2032
                ERRMSG("dup2");
2030 2033
                goto fail;
2031 2034
            }
2035
            rb_update_max_fd(extra_fd);
2032 2036
        }
2033 2037
        pairs[i].oldfd = extra_fd;
2034 2038
        j = pairs[i].older_index;
......
2039 2043
                ERRMSG("dup2");
2040 2044
                goto fail;
2041 2045
            }
2046
            rb_update_max_fd(ret);
2042 2047
            pairs[j].oldfd = -1;
2043 2048
            j = pairs[j].older_index;
2044 2049
        }
......
2094 2099
            ERRMSG("open");
2095 2100
            return -1;
2096 2101
        }
2102
        rb_update_max_fd(fd2);
2097 2103
        while (i < RARRAY_LEN(ary) &&
2098 2104
               (elt = RARRAY_PTR(ary)[i], RARRAY_PTR(elt)[1] == param)) {
2099 2105
            fd = FIX2INT(RARRAY_PTR(elt)[0]);
......
2108 2114
                    ERRMSG("dup2");
2109 2115
                    return -1;
2110 2116
                }
2117
                rb_update_max_fd(fd);
2111 2118
            }
2112 2119
            i++;
2113 2120
        }
......
2138 2145
            ERRMSG("dup2");
2139 2146
            return -1;
2140 2147
        }
2148
        rb_update_max_fd(newfd);
2141 2149
    }
2142 2150
    return 0;
2143 2151
}
......
2404 2412
            ret = fcntl(fdp[i], F_DUPFD, min);
2405 2413
            if (ret == -1)
2406 2414
                return -1;
2415
            rb_update_max_fd(ret);
2407 2416
            close(fdp[i]);
2408 2417
            fdp[i] = ret;
2409 2418
        }
......
3447 3456
    if (ret == -1) return -1;
3448 3457

  
3449 3458
    if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
3459
        rb_update_max_fd(fd);
3450 3460
	ioctl(fd, TIOCNOTTY, NULL);
3451 3461
	close(fd);
3452 3462
    }
ext/pty/pty.c (working copy)
184 184
    {
185 185
        int i = open("/dev/tty", O_RDONLY);
186 186
        if (i < 0) rb_sys_fail("/dev/tty");
187
        rb_update_max_fd(i);
187 188
        if (ioctl(i, TIOCNOTTY, (char *)0))
188 189
            perror("ioctl(TIOCNOTTY)");
189 190
        close(i);
......
206 207
        perror("open: pty slave");
207 208
        _exit(1);
208 209
    }
210
    rb_update_max_fd(slave);
209 211
    close(master);
210 212
#endif
211 213
    write(slave, "", 1);
......
297 299
    sigemptyset(&dfl.sa_mask);
298 300

  
299 301
    if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
302
    rb_update_max_fd(masterfd);
300 303
    if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
301 304
    if (grantpt(masterfd) == -1) goto grantpt_error;
302 305
    if (sigaction(SIGCHLD, &old, NULL) == -1) goto error;
......
304 307
    if ((slavedevice = ptsname(masterfd)) == NULL) goto error;
305 308
    if (no_mesg(slavedevice, nomesg) == -1) goto error;
306 309
    if ((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error;
310
    rb_update_max_fd(slavefd);
307 311

  
308 312
#if defined I_PUSH && !defined linux
309 313
    if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
......
335 339
	if (!fail) return -1;
336 340
	rb_raise(rb_eRuntimeError, "openpty() failed");
337 341
    }
342
    rb_update_max_fd(*master);
343
    rb_update_max_fd(*slave);
338 344
    if (no_mesg(SlaveName, nomesg) == -1) {
339 345
	if (!fail) return -1;
340 346
	rb_raise(rb_eRuntimeError, "can't chmod slave pty");
......
350 356
	if (!fail) return -1;
351 357
	rb_raise(rb_eRuntimeError, "_getpty() failed");
352 358
    }
359
    rb_update_max_fd(*master);
353 360

  
354 361
    *slave = open(name, O_RDWR);
362
    /* error check? */
363
    rb_update_max_fd(*slave);
355 364
    strlcpy(SlaveName, name, DEVICELEN);
356 365

  
357 366
    return 0;
......
365 374
    extern int grantpt(int);
366 375

  
367 376
    if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
377
    rb_update_max_fd(masterfd);
368 378
    s = signal(SIGCHLD, SIG_DFL);
369 379
    if(grantpt(masterfd) == -1) goto error;
370 380
    signal(SIGCHLD, s);
......
372 382
    if((slavedevice = ptsname(masterfd)) == NULL) goto error;
373 383
    if (no_mesg(slavedevice, nomesg) == -1) goto error;
374 384
    if((slavefd = open(slavedevice, O_RDWR, 0)) == -1) goto error;
385
    rb_update_max_fd(slavefd);
375 386
#if defined I_PUSH && !defined linux
376 387
    if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
377 388
    if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
......
395 406
    for (p = deviceNo; *p != NULL; p++) {
396 407
	snprintf(MasterName, sizeof MasterName, MasterDevice, *p);
397 408
	if ((masterfd = open(MasterName,O_RDWR,0)) >= 0) {
409
            rb_update_max_fd(masterfd);
398 410
	    *master = masterfd;
399 411
	    snprintf(SlaveName, DEVICELEN, SlaveDevice, *p);
400 412
	    if ((slavefd = open(SlaveName,O_RDWR,0)) >= 0) {
413
                rb_update_max_fd(slavefd);
401 414
		*slave = slavefd;
402 415
		if (chown(SlaveName, getuid(), getgid()) != 0) goto error;
403 416
		if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error;
......
565 578
    wfptr->fd = dup(info.fd);
566 579
    if (wfptr->fd == -1)
567 580
        rb_sys_fail("dup()");
581
    rb_update_max_fd(wfptr->fd);
568 582
    wfptr->pathv = rfptr->pathv;
569 583

  
570 584
    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 32
	if (!(fp = fdopen(fd, "r"))){
32 33
	    close(fd);
33 34
	    rb_sys_fail(0);
ext/socket/rubysocket.h (working copy)
286 286
#endif
287 287

  
288 288
#ifdef HAVE_ST_MSG_CONTROL
289
void rsock_discard_cmsg_resource(struct msghdr *mh);
289
void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p);
290 290
#endif
291 291

  
292 292
void rsock_init_basicsocket(void);
ext/socket/init.c (working copy)
48 48
#ifndef _WIN32
49 49
    if (fstat(fd, &sbuf) < 0)
50 50
        rb_sys_fail(0);
51
    rb_update_max_fd(fd);
51 52
    if (!S_ISSOCK(sbuf.st_mode))
52 53
        rb_raise(rb_eArgError, "not a socket file descriptor");
53 54
#else
......
250 251
	    fd = socket(domain, type, proto);
251 252
	}
252 253
    }
254
    if (0 <= fd)
255
        rb_update_max_fd(fd);
253 256
    return fd;
254 257
}
255 258

  
......
491 494
	}
492 495
        rb_sys_fail("accept(2)");
493 496
    }
497
    rb_update_max_fd(fd2);
494 498
    make_fd_nonblock(fd2);
495 499
    return rsock_init_sock(rb_obj_alloc(klass), fd2);
496 500
}
......
537 541
	}
538 542
	rb_sys_fail(0);
539 543
    }
544
    rb_update_max_fd(fd2);
540 545
    if (!klass) return INT2NUM(fd2);
541 546
    return rsock_init_sock(rb_obj_alloc(klass), fd2);
542 547
}
ext/socket/extconf.rb (working copy)
124 124

  
125 125
have_type("PADDRINFO", %w[ ws2tcpip.h wspiapi.h ])
126 126

  
127
if checking_for("recvmsg() with MSG_PEEK allocate file descriptors") {try_run(cpp_include(headers) + <<'EOF')}
128
#include <stdlib.h>
129
#include <stdio.h>
130
#include <string.h>
131
#include <sys/types.h>
132
#include <sys/stat.h>
133
#include <sys/socket.h>
134
#include <sys/un.h>
135
#include <unistd.h>
136

  
137
int main(int argc, char *argv[])
138
{
139
    int ps[2], sv[2];
140
    int ret;
141
    ssize_t ss;
142
    int s_fd, r_fd;
143
    struct msghdr s_msg, r_msg;
144
    union {
145
        struct cmsghdr hdr;
146
        char dummy[CMSG_SPACE(sizeof(int))];
147
    } s_cmsg, r_cmsg;
148
    struct iovec s_iov, r_iov;
149
    char s_buf[1], r_buf[1];
150
    struct stat s_statbuf, r_statbuf;
151

  
152
    ret = pipe(ps);
153
    if (ret == -1) { perror("pipe"); exit(EXIT_FAILURE); }
154

  
155
    s_fd = ps[0];
156

  
157
    ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv);
158
    if (ret == -1) { perror("socketpair"); exit(EXIT_FAILURE); }
159

  
160
    s_msg.msg_name = NULL;
161
    s_msg.msg_namelen = 0;
162
    s_msg.msg_iov = &s_iov;
163
    s_msg.msg_iovlen = 1;
164
    s_msg.msg_control = &s_cmsg;
165
    s_msg.msg_controllen = CMSG_SPACE(sizeof(int));;
166
    s_msg.msg_flags = 0;
167

  
168
    s_iov.iov_base = &s_buf;
169
    s_iov.iov_len = sizeof(s_buf);
170

  
171
    s_buf[0] = 'a';
172

  
173
    s_cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));
174
    s_cmsg.hdr.cmsg_level = SOL_SOCKET;
175
    s_cmsg.hdr.cmsg_type = SCM_RIGHTS;
176
    memcpy(CMSG_DATA(&s_cmsg.hdr), (char *)&s_fd, sizeof(int));
177

  
178
    ss = sendmsg(sv[0], &s_msg, 0);
179
    if (ss == -1) { perror("sendmsg"); exit(EXIT_FAILURE); }
180

  
181
    r_msg.msg_name = NULL;
182
    r_msg.msg_namelen = 0;
183
    r_msg.msg_iov = &r_iov;
184
    r_msg.msg_iovlen = 1;
185
    r_msg.msg_control = &r_cmsg;
186
    r_msg.msg_controllen = CMSG_SPACE(sizeof(int));
187
    r_msg.msg_flags = 0;
188

  
189
    r_iov.iov_base = &r_buf;
190
    r_iov.iov_len = sizeof(r_buf);
191

  
192
    r_buf[0] = '0';
193

  
194
    memset(&r_cmsg, 0xff, CMSG_SPACE(sizeof(int)));
195

  
196
    ss = recvmsg(sv[1], &r_msg, MSG_PEEK);
197
    if (ss == -1) { perror("recvmsg"); exit(EXIT_FAILURE); }
198

  
199
    if (ss != 1) {
200
        fprintf(stderr, "unexpected return value from recvmsg: %ld\n", (long)ss);
201
        exit(EXIT_FAILURE);
202
    }
203
    if (r_buf[0] != 'a') {
204
        fprintf(stderr, "unexpected return data from recvmsg: 0x%02x\n", r_buf[0]);
205
        exit(EXIT_FAILURE);
206
    }
207

  
208
    if (r_msg.msg_controllen < CMSG_LEN(sizeof(int))) {
209
        fprintf(stderr, "unexpected: r_msg.msg_controllen < CMSG_LEN(sizeof(int)) not hold: %ld\n",
210
                (long)r_msg.msg_controllen);
211
        exit(EXIT_FAILURE);
212
    }
213
    if (r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int))) {
214
        fprintf(stderr, "unexpected: r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int)) not hold: %ld\n",
215
                (long)r_cmsg.hdr.cmsg_len);
216
        exit(EXIT_FAILURE);
217
    }
218
    memcpy((char *)&r_fd, CMSG_DATA(&r_cmsg.hdr), sizeof(int));
219

  
220
    if (r_fd < 0) {
221
        fprintf(stderr, "negative r_fd: %d\n", r_fd);
222
        exit(EXIT_FAILURE);
223
    }
224

  
225
    if (r_fd == s_fd) {
226
        fprintf(stderr, "r_fd and s_fd is same: %d\n", r_fd);
227
        exit(EXIT_FAILURE);
228
    }
229

  
230
    ret = fstat(s_fd, &s_statbuf);
231
    if (ret == -1) { perror("fstat(s_fd)"); exit(EXIT_FAILURE); }
232

  
233
    ret = fstat(r_fd, &r_statbuf);
234
    if (ret == -1) { perror("fstat(r_fd)"); exit(EXIT_FAILURE); }
235

  
236
    if (s_statbuf.st_dev != r_statbuf.st_dev ||
237
        s_statbuf.st_ino != r_statbuf.st_ino) {
238
        fprintf(stderr, "dev/ino doesn't match: s_fd:%ld/%ld r_fd:%ld/%ld\n",
239
                (long)s_statbuf.st_dev, (long)s_statbuf.st_ino,
240
                (long)r_statbuf.st_dev, (long)r_statbuf.st_ino);
241
        exit(EXIT_FAILURE);
242
    }
243

  
244
    return EXIT_SUCCESS;
245
}
246
EOF
247
  $defs << "-DFD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK"
248
end
249

  
127 250
getaddr_info_ok = (enable_config("wide-getaddrinfo") && :wide) ||
128 251
  (checking_for("wide getaddrinfo") {try_run(<<EOF)} && :os)
129 252
#{cpp_include(headers)}
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 124

  
123 125
    s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]);
124 126
    s2 = rsock_init_sock(rb_obj_alloc(klass), sp[1]);
ext/socket/ancdata.c (working copy)
1377 1377

  
1378 1378
#if defined(HAVE_ST_MSG_CONTROL)
1379 1379
static void
1380
discard_cmsg(struct cmsghdr *cmh, char *msg_end)
1380
discard_cmsg(struct cmsghdr *cmh, char *msg_end, int msg_peek_p)
1381 1381
{
1382
# if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
1383
    /* 
1384
     * FreeBSD 8.2.0, NetBSD 5 and MacOS X Snow Leopard doesn't
1385
     * allocate fds by recvmsg with MSG_PEEK.
1386
     * [ruby-dev:44189]
1387
     * http://redmine.ruby-lang.org/issues/5075
1388
     *
1389
     * Linux 2.6.38 allocate fds by recvmsg with MSG_PEEK.
1390
     */
1391
    if (msg_peek_p)
1392
        return;
1393
# endif
1382 1394
    if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1383 1395
        int *fdp = (int *)CMSG_DATA(cmh);
1384 1396
        int *end = (int *)((char *)cmh + cmh->cmsg_len);
1385 1397
        while ((char *)fdp + sizeof(int) <= (char *)end &&
1386 1398
               (char *)fdp + sizeof(int) <= msg_end) {
1399
            rb_update_max_fd(*fdp);
1387 1400
            close(*fdp);
1388 1401
            fdp++;
1389 1402
        }
......
1392 1405
#endif
1393 1406

  
1394 1407
void
1395
rsock_discard_cmsg_resource(struct msghdr *mh)
1408
rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p)
1396 1409
{
1397 1410
#if defined(HAVE_ST_MSG_CONTROL)
1398 1411
    struct cmsghdr *cmh;
......
1404 1417
    msg_end = (char *)mh->msg_control + mh->msg_controllen;
1405 1418

  
1406 1419
    for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
1407
        discard_cmsg(cmh, msg_end);
1420
        discard_cmsg(cmh, msg_end, msg_peek_p);
1408 1421
    }
1409 1422
#endif
1410 1423
}
......
1426 1439
            VALUE io;
1427 1440
            if (fstat(fd, &stbuf) == -1)
1428 1441
                rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS");
1442
            rb_update_max_fd(fd);
1429 1443
            if (S_ISSOCK(stbuf.st_mode))
1430 1444
                io = rsock_init_sock(rb_obj_alloc(rb_cSocket), fd);
1431 1445
            else
......
1602 1616
                /* there are big space bug truncated.
1603 1617
                 * file descriptors limit? */
1604 1618
                if (!gc_done) {
1605
		    rsock_discard_cmsg_resource(&mh);
1619
		    rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1606 1620
                    goto gc_and_retry;
1607 1621
		}
1608 1622
            }
......
1623 1637
	}
1624 1638
#endif
1625 1639
	if (grown) {
1626
            rsock_discard_cmsg_resource(&mh);
1640
            rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1627 1641
	    goto retry;
1628 1642
	}
1629 1643
	else {
1630 1644
            grow_buffer = 0;
1631 1645
            if (flags != orig_flags) {
1646
                rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1632 1647
                flags = orig_flags;
1633
                rsock_discard_cmsg_resource(&mh);
1634 1648
                goto retry;
1635 1649
            }
1636 1650
        }
......
1670 1684
            if (request_scm_rights)
1671 1685
                make_io_for_unix_rights(ctl, cmh, msg_end);
1672 1686
            else
1673
                discard_cmsg(cmh, msg_end);
1687
                discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
1674 1688
            rb_ary_push(ret, ctl);
1675 1689
        }
1676 1690
    }
ext/socket/unixsocket.c (working copy)
367 367
		 (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
368 368
    }
369 369
    if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
370
	rsock_discard_cmsg_resource(&arg.msg);
370
	rsock_discard_cmsg_resource(&arg.msg, 0);
371 371
	rb_raise(rb_eSocket,
372 372
		 "file descriptor was not passed (cmsg_len=%d, %d expected)",
373 373
		 (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
......
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 387

  
387 388
    if (klass == Qnil)
388 389
	return INT2FIX(fd);
ruby.c (working copy)
1519 1519
	if ((fd = open(fname, mode)) < 0) {
1520 1520
	    rb_load_fail(fname);
1521 1521
	}
1522
        rb_update_max_fd(fd);
1522 1523

  
1523 1524
	f = rb_io_fdopen(fd, mode, fname);
1524 1525
    }
file.c (working copy)
3867 3867
	if ((tmpfd = open(StringValueCStr(path), 0)) < 0) {
3868 3868
	    rb_sys_fail(RSTRING_PTR(path));
3869 3869
	}
3870
        rb_update_max_fd(tmpfd);
3870 3871
	if (chsize(tmpfd, pos) < 0) {
3871 3872
	    close(tmpfd);
3872 3873
	    rb_sys_fail(RSTRING_PTR(path));
......
5013 5014
    int ret = 1;
5014 5015
    int fd = open(path, O_RDONLY);
5015 5016
    if (fd == -1) return 0;
5017
    rb_update_max_fd(fd);
5016 5018
#if !defined DOSISH
5017 5019
    {
5018 5020
	struct stat st;
random.c (working copy)
488 488
            |O_NOCTTY
489 489
#endif
490 490
            )) >= 0) {
491
        rb_update_max_fd(fd);
491 492
        if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
492 493
            (void)read(fd, seed, DEFAULT_SEED_LEN);
493 494
        }