[英]Pipe to and from child process is not working
I am trying to learn pipes and I am trying out this program: 我正在尝试学习管道,并且正在尝试该程序:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<fcntl.h>
#define MAXLINE 100
void main(){
int pipe1[2],pipe2[2];
pid_t childpid;
if(pipe(pipe1)<0){
perror("Unable to create the pipe for pipe1");
exit(-1);
}
if(pipe(pipe2)<0){
perror("Unable to create the pipe for pipe1");
exit(-1);
}
childpid=fork();
printf("The child PID is:%d\n",childpid);
if(childpid==0){
printf("In the child process");
close(pipe1[1]);
close(pipe2[0]);
server(pipe1[0],pipe2[1]);
exit(0);
}
close(pipe1[0]);
close(pipe2[1]);
client(pipe2[0],pipe1[1]);
waitpid(childpid,NULL,0);
exit(0);
}
void client(int readfd,int writefd){
int n,len;
char buff[MAXLINE];
printf("Please enter the name of the file to be read:");
fgets(buff,MAXLINE,stdin);
len=strlen(buff);
if(buff[len-1]=='\n')
len--;
write(writefd,buff,len);
printf("File name written into the pipe\n");
printf("The num of bytes written are:\n",read(readfd,buff,MAXLINE));
while((n-read(readfd,buff,MAXLINE))>0){
printf("Trying to read the content\n");
write(STDOUT_FILENO,buff,n);
}
}
void server(int readfd,int writefd){
int fd,n;
char buff[MAXLINE + 1];
write(writefd,"Yello in the server process",strlen("Yello in the server process"));
if((n=read(readfd,buff,MAXLINE))==0)
perror("End of file while reading");
buff[n]='\0';
if((fd=fopen(buff,O_RDONLY))<0){
snprintf(buff+n,sizeof(buff)-n,"Can't open, %s",strerror(errno));
n=strlen(buff);
write(writefd,buff,n);
}
while( (n=read(fd,buff,MAXLINE))>0){
write(writefd,buff,n);
close(fd);
}
}
The problem is I enter the file name and the program just exits. 问题是我输入了文件名,程序刚刚退出。 I tried to gdb the child process by setting set "follow-fork-mode child", and still nothing happens.
我试图通过设置set“ follow-fork-mode child”来gdb子进程,但仍然没有任何反应。 Any ideas as to where I could be going wrong?
关于我可能会出错的任何想法?
Ok, some more additional debugging info is: I set the follow-fork-mode to child.and it is causing a segmentation fault at the opening of the file. 好的,更多其他调试信息是:我将Follow-fork-mode设置为child。,这在文件打开时导致分段错误。
Program received signal SIGSEGV, Segmentation fault. 程序收到信号SIGSEGV,分段故障。 [Switching to process 28025] 0x00197f08 in _IO_file_fopen () from /lib/libc.so.6
[切换到处理28025] /lib/libc.so.6中_IO_file_fopen()中的0x00197f08
This code in client()
looks suspicious: client()
代码可疑:
while((n-read(readfd,buff,MAXLINE))>0){
Surely, that should be: 当然应该是:
while ((n = read(readfd, buff, MAXLINE)) > 0)
{
The change from -
to =
is the important one, of course; 当然,从
-
到=
的变化是重要的。 the rest are cosmetic (and one is even controversial). 其余的都是化妆品(甚至是有争议的)。
You should also pay attention to compiler warnings. 您还应该注意编译器警告。 Given:
鉴于:
int fd,n;
...
if((fd=fopen(buff,O_RDONLY))<0){
There's no way this should be compiling without major warnings; 没有重大警告,就不可能编译它。
fopen()
returns a FILE *
, not a file descriptor ( int
). fopen()
返回FILE *
,而不是文件描述符( int
)。
You also seem to have some odd communications. 您似乎也有一些奇怪的交流。 The server sends a message to the client before reading the file name from the client.
在从客户端读取文件名之前,服务器会向客户端发送一条消息。 The client, OTOH, does not necessarily read that message separately;
客户端OTOH不必单独读取该消息; it gets a glob of information and reports how many bytes it got.
它获得一堆信息并报告获得了多少字节。 That may have included some of the file as well as the introductory message.
这可能包括一些文件以及介绍性消息。
You shouldn't close a file in the loop that is reading from it: 您不应该在正在读取的循环中关闭文件:
while( (n=read(fd,buff,MAXLINE))>0){
write(writefd,buff,n);
close(fd);
}
The close should be outside the loop. 关闭应该在循环之外。
This code more or less works; 该代码或多或少有效。 it is messier than I'd like, but it does more or less work.
它比我想要的更混乱,但是它或多或少地完成了工作。
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAXLINE 100
static void server(int readfd, int writefd);
static void client(int readfd, int writefd);
int main(void)
{
int pipe1[2], pipe2[2];
pid_t childpid;
if (pipe(pipe1)<0)
{
perror("Unable to create the pipe for pipe1");
exit(-1);
}
if (pipe(pipe2)<0)
{
perror("Unable to create the pipe for pipe2");
exit(-1);
}
childpid = fork();
printf("The child PID is:%d\n", childpid);
if (childpid == 0)
{
printf("In the child process\n");
close(pipe1[1]);
close(pipe2[0]);
server(pipe1[0], pipe2[1]);
exit(0);
}
close(pipe1[0]);
close(pipe2[1]);
client(pipe2[0], pipe1[1]);
waitpid(childpid, NULL, 0);
return 0;
}
static void client(int readfd, int writefd)
{
int n, len;
char buff[MAXLINE];
printf("Please enter the name of the file to be read:");
fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if (buff[len-1]=='\n')
len--;
write(writefd, buff, len);
printf("File name (%.*s) written into the pipe\n", len, buff);
printf("The num of bytes written are: %d\n", (int)read(readfd, buff, MAXLINE));
while ((n = read(readfd, buff, MAXLINE)) > 0)
{
printf("Trying to read the content\n");
write(STDOUT_FILENO, buff, n);
}
}
static void server(int readfd, int writefd)
{
int fd, n;
char buff[MAXLINE + 1];
fprintf(stderr, "Server: %d\n", (int)getpid());
write(writefd, "Yello in the server process", strlen("Yello in the server process"));
if ((n = read(readfd, buff, MAXLINE))==0)
perror("End of file while reading");
buff[n] = '\0';
if ((fd = open(buff, O_RDONLY)) < 0)
{
snprintf(buff+n, sizeof(buff)-n, "Can't open, %s", strerror(errno));
n = strlen(buff);
write(writefd, buff, n);
}
else
{
while ((n = read(fd, buff, MAXLINE)) > 0)
{
if (write(writefd, buff, n) != n)
{
fprintf(stderr, "Write failed in server\n");
break;
}
}
close(fd);
}
}
Note that the code does not try using a file descriptor that it fails to open. 请注意,该代码不会尝试使用无法打开的文件描述符。 It does not crash;
它不会崩溃; the
n-read(...)
problem is one major part of the trouble, comments notwithstanding. 尽管有评论,但
n-read(...)
问题是麻烦的主要部分。 The misuse of fopen()
for open()
was another major part of the trouble. 将
fopen()
误用于open()
是麻烦的另一个主要部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.