我最近读到了一个post.在这篇文章中,Soner关闭了父进程和子进程的管道的读取端.但当写入管道时,似乎没有生成SIGPIPE信号.
我修改了代码,以确保读取管道的末端是真正关闭的,并且write调用返回时没有任何错误.
以下是我的代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <signal.h>
#define BUFSIZE 100
char const * errMsgPipe = "signal handled SIGPIPE\n";
int errMsgPipeLen;
void handler(int x) {
write(2, errMsgPipe, errMsgPipeLen);
}
int main(void) {
errMsgPipeLen = strlen(errMsgPipe);
char bufin[BUFSIZE] = "empty";
char bufout[] = "hello soner";
int bytesin;
pid_t childpid;
int fd[2];
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = 0;
sigfillset(&sa.sa_mask);
sa.sa_handler = handler;
sigaction(SIGPIPE, &sa, 0);
if (pipe(fd) == -1) {
perror("Failed to create the pipe");
return 1;
}
bytesin = strlen(bufin);
childpid = fork();
if (childpid == -1) {
perror("Failed to fork");
return 1;
}
close(fd[0]);
if (childpid) {
int ret = write(fd[1], bufout, strlen(bufout)+1);
if (ret < 0) {
perror("write");
} else {
printf("write success, ret: %d\n", ret );
}
wait(NULL);
}
else{
bytesin = read(fd[0], bufin, BUFSIZE);
if(bytesin == -1) {
perror("child: read");
}
}
fprintf(stderr, "[%ld]:my bufin is {%.*s}, my bufout is {%s}\n",
(long)getpid(), bytesin, bufin, bufout);
return 0;
}
输出:
write success, ret: 12
child: read: Bad file descriptor
[9168]:my bufin is {empty}, my bufout is {hello soner}
[9167]:my bufin is {empty}, my bufout is {hello soner}
我对代码进行了如下修改:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#define BUFSIZE 100
char const * errMsgPipe = "signal handled SIGPIPE\n";
int errMsgPipeLen;
void handler(int x) {
write(2, errMsgPipe, errMsgPipeLen);
}
int main(void) {
errMsgPipeLen = strlen(errMsgPipe);
char bufin[BUFSIZE] = "empty";
char bufout[] = "hello soner";
int bytesin;
pid_t childpid;
int fd[2];
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = 0;
sigfillset(&sa.sa_mask);
sa.sa_handler = handler;
sigaction(SIGPIPE, &sa, 0);
if (pipe(fd) == -1) {
perror("Failed to create the pipe");
return 1;
}
close(fd[0]);
bytesin = strlen(bufin);
childpid = fork();
if (childpid == -1) {
perror("Failed to fork");
return 1;
}
if (childpid) {
int flag = fcntl(fd[0], F_GETFD);
if(flag = -1) {
printf("pid:[%d], fcntl: %s\n", getpid(), strerror(errno));
} else {
printf("pip: [%d], fd[0] is not closed\n");
}
if (write(fd[1], bufout, strlen(bufout)+1) < 0) {
perror("write");
}
//
}
else{
int flag = fcntl(fd[0], F_GETFD);
if(flag = -1) {
printf("pid:[%d], fcntl: %s\n", getpid(), strerror(errno));
} else {
printf("pip: [%d], fd[0] is not closed\n");
}
bytesin = read(fd[0], bufin, BUFSIZE);
if(bytesin == -1) {
perror("read");
}
}
fprintf(stderr, "[%ld]:my bufin is {%.*s}, my bufout is {%s}\n",
(long)getpid(), bytesin, bufin, bufout);
return 0;
}
但当我多次运行该程序时,它产生了不同的结果. 例如:
pid:[9200], fcntl: Bad file descriptor
signal handled SIGPIPE
write: Broken pipe
pid:[9201], fcntl: Bad file descriptor
[9200]:my bufin is {empty}, my bufout is {hello soner}
read: Bad file descriptor
[9201]:my bufin is {empty}, my bufout is {hello soner}
另一个结果是:
pid:[9189], fcntl: Bad file descriptor
[9189]:my bufin is {empty}, my bufout is {hello soner}
pid:[9190], fcntl: Bad file descriptor
read: Bad file descriptor
[9190]:my bufin is {empty}, my bufout is {hello soner}