Mail Archives: cygwin/2004/12/09/18:41:57
>> I've discovered that fread(ptr, size, nitems, stream) sometimes returns a
>> value less than "nitems", but does not set feof() nor ferror(). As I
>A simple, compilable test case with results shown on both linux and
>cygwin would prove your theory.
Here you go; example follows. Test run on Linux:
---
Got 66 bytes:
/bin/ls: /somebogus: Filen eller katalogen finns inte
/etc/passwd
|EOF has been reached.
---
Test run on Cygwin:
---
$ ./a.exe
Got 9 bytes:
/bin/ls: |
---
As you can see, the result is partial, and there is no EOF nor error.
I guess this is the problem described at
http://sources.redhat.com/ml/newlib/2004/msg00477.html. Perhaps you can
apply the suggested patch?
Example code follows.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
void checked_close(int fd)
{
if (close(fd) == -1) {
perror("close");
exit(1);
}
}
void checked_pipe(int filedes[2])
{
if (pipe(filedes) == -1) {
perror("filedes");
exit(1);
}
}
int checked_dup2(int oldfd, int newfd)
{
int ret;
if ((ret = dup2(oldfd, newfd)) == -1) {
perror("dup2");
exit(1);
}
return ret;
}
int main()
{
int c2p[2];
int errpipe[2];
pid_t pid;
char errpipe_buf[16];
char buf[16394];
ssize_t errpipe_count;
size_t count;
FILE *output;
checked_pipe(c2p);
checked_pipe(errpipe);
fcntl(errpipe[1], F_SETFD, FD_CLOEXEC);
pid = fork();
switch (pid) {
case -1:
perror("fork");
exit(1);
break;
case 0:
/* child */
checked_close(c2p[0]);
checked_close(errpipe[0]);
dup2(c2p[1], 1);
dup2(c2p[1], 2);
checked_close(c2p[1]);
execlp("/bin/ls", "/bin/ls", "/etc/passwd", "/somebogus");
/* If we are still around, exec failed */
write(errpipe[1], "1", 1);
_exit(255);
break;
default:
/* parent */
break;
}
checked_close(errpipe[1]);
checked_close(c2p[1]);
errpipe_count = read(errpipe[0], errpipe_buf, 1);
switch (errpipe_count) {
case -1:
perror("read");
exit(1);
break;
case 0:
/* EOF, good */
break;
default:
/* Our "1", exec failed */
fprintf(stderr, "exec in child failed\n");
exit(1);
break;
}
/* now read output from child, via a FILE stream */
if ((output = fdopen(c2p[0], "rb")) == NULL) {
perror("fdopen");
exit(1);
}
setvbuf(output, 0, _IONBF, 0);
clearerr(output);
count = fread(buf, 1, sizeof(buf), output);
if (count >= 0) {
fprintf(stderr, "Got %d bytes:\n", count);
fprintf(stderr, "%s|", buf);
}
if (feof(output)) {
fprintf(stderr, "EOF has been reached.\n");
}
if (ferror(output)) {
fprintf(stderr, "An error occured.\n");
}
return 0;
}
/Peter Åstrand <astrand AT lysator DOT liu DOT se>
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -