Module_DMAP::Transmitting_Result Module_DMAP::receive_from_previous(int id) { Transmitting_Result result; result = recv_output(my_rank-1,id); return result; }
/* * Play on @sock. * The session must be in the playing phase. * Return 0 when the session ended, -1 on error. */ int play(int sock) { /* * Player input flows from INPUT_FD through recv_input() into ring * buffer INBUF, which drains into SOCK. This must not block. * Server output flows from SOCK into recv_output(). Reading SOCK * must not block. */ struct sigaction sa; struct ring inbuf; /* input buffer, draining to SOCK */ int eof_fd0; /* read fd 0 hit EOF? */ int partial_line_sent; /* partial input line sent? */ fd_set rdfd, wrfd; int n; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sa.sa_handler = intr; sigaction(SIGINT, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); ring_init(&inbuf); eof_fd0 = partial_line_sent = send_eof = send_intr = 0; input_fd = 0; sysdep_stdin_init(); for (;;) { FD_ZERO(&rdfd); FD_ZERO(&wrfd); /* * Want to read player input only when we don't need to send * cookies, and INPUT_FD is still open, and INBUF can accept * some. */ if (!send_intr && !send_eof && input_fd >= 0 && ring_space(&inbuf)) FD_SET(input_fd, &rdfd); /* Want to send player input only when we have something */ if (send_intr || send_eof || ring_len(&inbuf)) FD_SET(sock, &wrfd); /* Always want to read server output */ FD_SET(sock, &rdfd); n = select(MAX(input_fd, sock) + 1, &rdfd, &wrfd, NULL, NULL); if (n < 0) { if (errno != EINTR) { perror("select"); return -1; } } if ((send_eof || send_intr) && partial_line_sent && ring_putc(&inbuf, '\n') != EOF) partial_line_sent = 0; if (send_eof && !partial_line_sent && ring_putm(&inbuf, EOF_COOKIE, sizeof(EOF_COOKIE) - 1) >= 0) send_eof--; if (send_intr && !partial_line_sent && ring_putm(&inbuf, INTR_COOKIE, sizeof(INTR_COOKIE) - 1) >= 0) { send_intr = 0; if (input_fd) { /* execute aborted, switch back to fd 0 */ close(input_fd); input_fd = eof_fd0 ? -1 : 0; } } if (n < 0) continue; /* read player input */ if (input_fd >= 0 && FD_ISSET(input_fd, &rdfd)) { n = recv_input(input_fd, &inbuf); if (n < 0) { perror("read stdin"); /* FIXME stdin misleading, could be execing */ n = 0; } if (n == 0) { /* EOF on input */ send_eof++; if (input_fd) { /* execute done, switch back to fd 0 */ close(input_fd); input_fd = eof_fd0 ? -1 : 0; } else { /* stop reading input, drain socket ring buffers */ eof_fd0 = 1; input_fd = -1; sa.sa_handler = SIG_DFL; sigaction(SIGINT, &sa, NULL); } } else partial_line_sent = ring_peek(&inbuf, -1) != '\n'; } /* send it to the server */ if (FD_ISSET(sock, &wrfd)) { n = ring_to_file(&inbuf, sock); if (n < 0) { perror("write socket"); return -1; } } /* read server output and print it */ if (FD_ISSET(sock, &rdfd)) { n = recv_output(sock); if (n < 0) { perror("read socket"); return -1; } if (n == 0) return 0; } } }