我使用简单的管道。我读了一会儿,一次一个字符,我想我每次读一个字母都会覆盖一些东西
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main () {
int pipefd[2];
int cpid;
char buf[31];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("cpid");
exit(EXIT_FAILURE);
}
if (cpid == 0) { // child reads from pipe
close (pipefd[1]); // close unused write end
int i = 0;
while (read (pipefd[0], &(buf[i++]), 1)>0);
printf ("Server receives: %s", buf);
close (pipefd[0]);
exit (EXIT_SUCCESS);
}
else { // parent writes to pipe
close (pipefd[0]); // closing unused read end;
char buf2[30];
printf("Server transmits: ");
scanf ("%s", buf2);
write (pipefd[1], buf2, strlen(buf2)+1);
close(pipefd[1]);
wait(NULL);
exit(EXIT_SUCCESS);
}
return 0;
}
现在修复了代码,这已经过时了:例如,如果我输入:“Flowers”,它会打印F然后打印~6个不可打印的字符
BUT:正在发生的一件奇怪的事情,我只是使用了超过30的字符串方式,并且它根本没有产生任何错误,它确实设法写出整个字符串。虽然我的缓冲区都比这个要小得多。
答案 0 :(得分:1)
这里看起来不对
while (read (pipefd[0], &buf, 1)>0);
你一遍又一遍地读一个字符到缓冲区的第一个位置
相反,您应该增加放置读取字符的位置
e.g。
int i = 0;
while (read(pipefd[0], buf + i, 1) >0 ) ++i;
buf[i] = 0; // end string
也许还可以检查不会大于buf大小。
while (read(pipefd[0], buf + i, 1) >0 && i < sizeof(buf)) ++i;
答案 1 :(得分:1)
(按照安德斯的建议。)
使用GCC 4.6.3,我的代码:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main () {
int pipefd[2];
int cpid;
char buf[31];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1)
{
perror("cpid");
exit(EXIT_FAILURE);
}
if (cpid == 0) { // child reads from pipe
close (pipefd[1]); // close unused write end
int i=0;
while (read(pipefd[0], &(buf[i++]), 1) != 0);
printf ("Server receives: %s\n", buf);
close (pipefd[0]);
exit (EXIT_SUCCESS);
}
else { // parent writes to pipe
close (pipefd[0]); // closing unused read end;
char buf2[30];
printf("Server transmits: ");
scanf ("%s", buf2);
write (pipefd[1], buf2, strlen(buf2)+1);
close(pipefd[1]);
wait(NULL);
exit(EXIT_SUCCESS);
}
return 0;
}
产地:
[user@host tmp]$ gcc pipes.c -o pipes && ./pipes
Server transmits: Flowers
Server receives: Flowers
(我也同意他对边界检查的看法。)
编辑:根据您的评论,如果您更改以下行(35为我)
scanf("%s", buf2);
到
fgets(buf2, 30, stdin);
你获得两项福利。 (a)通过限制将复制到buf2
的字节数来消除缓冲区溢出漏洞。 (b)您可以“接受”非换行空格(空格和制表符),而使用scanf
则不是:
[user@host tmp]$ gcc pipes.c -o pipes && ./pipes
Server transmits: Flowers smell nice
Server receives: Flowers smell nice