Select () returns an invalid argument

I successfully read the tube from another thread and print the output (in the ncurses window when this happens).

I need to do this one character at a time, for various reasons, and I use select () for FD for the read end of the channel, as well as several other FDs (like stdin).

My idea is to try to read from the pipe only when it is soon ready to read, instead of processing any input data. It seems to work - at least for a start. select () sets fd_set, and if FD_ISSET, I do a read () of 1 byte from FD. But select () says yes, too many, and read () blocks.

So my question is this: why would select () indicate that fd is ready to read if subsequent blocks are read ()?

(approximately) The same code worked fine when the other end of the pipe was connected to a forked process, if that helps.

I can send the code on request, but this is a standard swamp. Configure fd_set, copy it, select a copy if FD is set to call a function that reads a byte from the same FD ... otherwise return a copy of fd_set

EDIT: on request here is the code:

Setting up my fd_set:

fd_set fds;
FD_ZERO(&fds); 
FD_SET(interp_output[0], &fds);
FD_SET(STDIN_FILENO, &fds);
struct timeval timeout, tvcopy; timeout.tv_sec=1;
int maxfd=interp_output[0]+1; //always >stdin+1
fd_set read_fds;
FD_COPY(&fds, &read_fds);

In the loop:

if (select(maxfd, &read_fds, NULL, NULL, &timeout)==-1) {perror("couldn't select"); return;}
if (FD_ISSET(interp_output[0], &read_fds)) {
    handle_interp_out();
} else if (FD_ISSET(STDIN_FILENO, &read_fds)) {
//waddstr(cmdwin, "stdin!"); wrefresh(cmdwin);
    handle_input();
}

FDCOPY(&fds, &read_fds);

handle_interp_out ():

void handle_interp_out() {
    int ch;
    read(interp_output[0], &ch, 1);
    if (ch>0) {
            if (ch=='\n') { if (cmd_curline>=cmdheight) cmdscroll(); wmove(cmdwin, ++cmd_curline, 1); }
            else waddch(cmdwin, ch);
            wrefresh(cmdwin);
    }
}

EDIT 2: The write code is just fprintf in FILE *, opened with fdopen (interp_output [1], "w") is a different thread. All I get is my "invitation>" - it prints all this correctly, but does another iteration, which it should not. I turned off buffering, which gave me other problems.

EDIT 3: select(). , -1 errno " ". () . select()? , ...

4: , . - .tv_sec = 1 . , . - - , . NULL, , .

+3
4

, , O_NONBLOCK fd.

, . . , .

. , 0.

:

struct timeval timeout = {1, 0};

, , Linux , . , , reset 1 .

+6

man-:

-1, errno ; - undefined, .

select().

, select() (errno = EINTR) , FD "read" fd_set, , .

, // . "read_fds" , "".

+3

. . select() Linux, : http://linux.die.net/man/2/select

" Linux, select() " ", , , "

- NON-BLOCKING.

+2

: " ". , , . - .

, , , , , , .

, , - , .

-, . , , , read() EWOULDBLOCK.

, , fd_set. ? ?

0

Source: https://habr.com/ru/post/1778691/


All Articles