Skip to content

Commit

Permalink
Report error when file descriptor number is too large for select (PR#…
Browse files Browse the repository at this point in the history
…18634).

git-svn-id: https://svn.r-project.org/R/trunk@85687 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information
kalibera committed Dec 15, 2023
1 parent 01dd63b commit b4b9706
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
14 changes: 10 additions & 4 deletions src/library/parallel/src/fork.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* R : A Computer Language for Statistical Data Analysis
* (C) Copyright 2008-2011 Simon Urbanek
* Copyright 2011-2022 R Core Team.
* Copyright 2011-2023 R Core Team.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -816,6 +816,8 @@ SEXP mc_send_child_stdin(SEXP sPid, SEXP what)
void fdcopy(fd_set *dst, fd_set *src, int nfds)
{
FD_ZERO(dst);
if (nfds > FD_SETSIZE)
error("file descriptor is too large for select()");
for(int i = 0; i < nfds; i++)
if (FD_ISSET(i, src)) FD_SET(i, dst);
}
Expand Down Expand Up @@ -847,7 +849,7 @@ SEXP mc_select_children(SEXP sTimeout, SEXP sWhich)
unsigned int k = 0;
while (k < wlen) {
if (which[k++] == ci->pid) {
if (ci->pfd > FD_SETSIZE)
if (ci->pfd >= FD_SETSIZE)
error("file descriptor is too large for select()");
FD_SET(ci->pfd, &fs);
if (ci->pfd > maxfd) maxfd = ci->pfd;
Expand All @@ -860,7 +862,7 @@ SEXP mc_select_children(SEXP sTimeout, SEXP sWhich)
}
} else {
/* not sure if this should be allowed */
if (ci->pfd > FD_SETSIZE)
if (ci->pfd >= FD_SETSIZE)
error("file descriptor is too large for select()");
FD_SET(ci->pfd, &fs);
if (ci->pfd > maxfd) maxfd = ci->pfd;
Expand Down Expand Up @@ -1061,7 +1063,11 @@ SEXP mc_read_children(SEXP sTimeout)
while (ci) {
if (!ci->detached && ci->ppid == ppid) {
if (ci->pfd > maxfd) maxfd = ci->pfd;
if (ci->pfd >= 0) FD_SET(ci->pfd, &fs);
if (ci->pfd >= 0) {
if (ci->pfd >= FD_SETSIZE)
error("file descriptor is too large for select()");
FD_SET(ci->pfd, &fs);
}
}
ci = ci -> next;
}
Expand Down
9 changes: 7 additions & 2 deletions src/unix/sys-std.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ int R_SelectEx(int n, fd_set *readfds, fd_set *writefds,
platforms. If this still turns out to be limiting we will
probably need to rewrite internals to use poll() instead of
select(). LT */
if (n > FD_SETSIZE)
if (n >= FD_SETSIZE)
error("file descriptor is too large for select()");

if (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)
Expand Down Expand Up @@ -229,6 +229,8 @@ addInputHandler(InputHandler *handlers, int fd, InputHandlerProc handler,
input = R_Calloc(1, InputHandler);

input->activity = activity;
if (fd >= FD_SETSIZE)
error("file descriptor is too large for select()");
input->fileDescriptor = fd;
input->handler = handler;

Expand Down Expand Up @@ -382,8 +384,11 @@ setSelectMask(InputHandler *handlers, fd_set *readMask)
FD_ZERO(readMask);

/* If we are dealing with BasicInputHandler always put stdin */
if(handlers == &BasicInputHandler)
if(handlers == &BasicInputHandler) {
handlers->fileDescriptor = fileno(stdin);
if (handlers->fileDescriptor >= FD_SETSIZE)
error("file descriptor is too large for select()");
}

while(tmp) {
FD_SET(tmp->fileDescriptor, readMask);
Expand Down

0 comments on commit b4b9706

Please sign in to comment.