Reputation: 3
I'm having some trouble reading from a pipe. Well not exactly. I'm reading fine its just the output is globbed up.
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int pfd[2];
int main(void)
{
pid_t pid;
int status;
char readbuf[1024];
int bytes_read = 0;
pipe(pfd);
switch((pid = fork())) {
case -1:
perror("fork");
break;
case 0:
/* child */
close(pfd[0]);
dup2(pfd[1], 1); /* stdout */
/* mkdir -p /home/edgar/testdir */
chdir("/home/edgar/testdir");
/* for file in a b c d e f g h i j k l m n o p q r s t u v w x y z;
* do
* touch $file
* done
*/
execl("/bin/ls", "ls", "-l", (char *)NULL);
exit(1);
default:
/* parent */
close(pfd[1]);
dup2(pfd[0], 0);
pid = wait(&status);
/* get input back from ls */
while ((bytes_read = read(pfd[0], readbuf, sizeof readbuf) > 0)) {
fprintf(stdout, "%s\n", readbuf);
}
printf("child exit status: %d\n", WEXITSTATUS(status));
}
return 0;
}
Here is an example of globbed up output:
laptop$ ./test1
-rw-r--r-- 1 edgar edgar 0 Jan 31 09:15 u
-rw-r--r-- 1 edgar edgar 0 Jan 31 09:15 v
-rw-r--r-- 1 edgar edgarp��
0 Jan 31 09:15 w -rw-r--r-- 1 edgar edgar 0 Jan 31 09:15 x
-rw-r--r-- 1 edgar edgar 0 Jan 31 09:15 y
-rw-r--r-- 1 edgar edgar 0 Jan 31 09:15 z
1 edgar edgar 0 Jan 31 09:15 d
-rw-r--r-- 1 edgar edgar 0 Jan 31 09:15 e
It read from a-v fine and then w-z is weird and then it started over at d. I added the extra newlines above for readability.
Upvotes: 0
Views: 3295
Reputation: 3
This seems to have corrected the problem:
do {
bytes_read = read(pfd[0], readbuf, sizeof(readbuf));
readbuf[bytes_read] = '\0';
printf("%s", readbuf);
} while (bytes_read > 0);
Thanks for the assisstance.
Upvotes: 0
Reputation: 8142
What is one of the most important things to remember about strings in C? They're meant to be NUL
terminated!
read
doesn't add a NUL
your string - it deals with chunks of raw data, so you have to do that yourself. This also means that you can't pass in the full size of the buffer as you'll need to leave space for the NUL
to be added
while ((bytes_read = read(pfd[0], readbuf, sizeof(readbuf)-1) > 0)) {
readbuf[bytes_read]='\0';
fprintf(stdout, "%s\n", readbuf);
}
Upvotes: 2