Bug 7932
Summary: | POSIX conformance error: fscanf(3) + O_NONBLOCK + empty pipe | ||
---|---|---|---|
Product: | [Retired] Red Hat Linux | Reporter: | Jay Turner <jturner> |
Component: | glibc | Assignee: | Jakub Jelinek <jakub> |
Status: | CLOSED CURRENTRELEASE | QA Contact: | |
Severity: | low | Docs Contact: | |
Priority: | low | ||
Version: | 6.0 | CC: | fweimer, srevivo |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2002-12-13 19:19:04 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Glen Foster
1999-12-21 18:15:46 UTC
this looks correct to me. Did any process have the pipe open for writting? If not, returning 0 is the right thing to do, as the paragraph you quoted states. Please send complete small testcase and repoen if disagree. The pipe in the listed code fragment *is* open for writing; it's in p[1], the write-side of the pipe (it was never closed). I have included below a more detailed test-case that proves the point of the original defect filed. Note that when compiled "as is" *and* when compiled -DREAD_ONLY (to close the write-side of the pipe before calling scanf()), BOTH cases result in errno 29 (ESPIPE == Illegal seek) from the scanf() call. This return is acceptable if the write-side is closed but POSIX clearly states that when the write-side is open, errno EAGAIN is to be returned when there's (a) no data available and (b) O_NONBLOCK is set. Newer test code follows -- let me know if you have any questions. (Glen) [snip] #include <stdio.h> #include <fcntl.h> #include <errno.h> #define STRING "This is a string" main() { int flags, val, p[2], len = strlen(STRING); FILE *fp; char inbuf[64]; if (pipe(p) < 0) { perror("pipe"); exit(1); } if ((flags = fcntl(p[0], F_GETFL)) < 0) { perror("fcntl(F_GETFL)"); exit(1); } if (fcntl(p[0], F_SETFL, flags | O_NONBLOCK) < 0) { perror("fcntl(F_SETFL)"); exit(1); } if ((fp = fdopen(p[0], "r")) == (FILE *) NULL) { perror("fdopen"); exit(1); } #ifdef READ_ONLY printf("DEBUG: Closing write-side of pipe...\n"); if (close(p[1]) < 0) { perror("close"); exit(1); } #endif /* READ_ONLY */ #ifdef FORCE_FEED printf("DEBUG: Forcing data into pipe: \"%s\"\n", STRING); if (write(p[1], STRING, len) != len) { perror("write"); exit(1); } #elif DEBUG_READ printf("DEBUG: calling read() instead of fscanf()\n"); if (read(p[0], inbuf, BUFSIZ) < 0) { perror("read"); if (errno == EAGAIN) { printf("Proper return failure from read()\n"); exit(0); } } exit(1); #endif /* DEBUG_READ */ if ((val = fscanf(fp, "%s", inbuf)) == EOF) { if (errno != EAGAIN) { perror("fscanf"); exit(1); } printf("errno = EAGAIN (%d), correct ala POSIX\n", errno); exit(0); } fprintf(stderr, "fscanf() returns %d\n", val); fprintf(stderr, "fscanf() found data: \"%s\"\n", inbuf); #ifdef FORCE_FEED exit(0); #endif /* FORCE_FEED */ exit(1); } reprioritize assign to jakub |