Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pv__transfer_write() seems not handling all EINTR/EAGAIN properly #5

Open
lsun100 opened this issue Dec 14, 2020 · 0 comments
Open

Comments

@lsun100
Copy link

lsun100 commented Dec 14, 2020

In the latest code below, it was found that pv__transfer_write_repeated() could return 0 due to EINTR. When it happens, the data is not moving any more.

487 static int pv__transfer_write(pvstate_t state, int fd,
488                               int *eof_in, int *eof_out,
489                               long *lineswritten)
490 {
491         ssize_t nwritten;
492
493         signal(SIGALRM, SIG_IGN);
494         alarm(1);
495
496         nwritten = pv__transfer_write_repeated(STDOUT_FILENO,
497                                                state->transfer_buffer +
498                                                state->write_position,
499                                                state->to_write);
500
501         alarm(0);
502
503         if (0 == nwritten) {
504                 /*
505                  * Write returned 0 - EOF on stdout.
506                  */
507                 *eof_out = 1;
508                 return 1;
509         } else if (nwritten > 0) {
510                 /*

An experiment below seems solving the problem... Could you kindly check whether this is the case>

diff --git a/src/pv/transfer.c b/src/pv/transfer.c
index ee33df0..38b7df5 100644
--- a/src/pv/transfer.c
+++ b/src/pv/transfer.c
@@ -501,6 +501,14 @@ static int pv__transfer_write(pvstate_t state, int fd,
alarm(0);

    if (0 == nwritten) {
  •           if ((EINTR == errno) || (EAGAIN == errno)) {
    
  •                   struct timeval tv;
    
  •                   tv.tv_sec = 0;
    
  •                   tv.tv_usec = 10000;
    
  •                   select(0, NULL, NULL, NULL, &tv);
    
  •                   return 0;
    
  •           }
    
  •           /*
               * Write returned 0 - EOF on stdout.
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant