发布时间:2025-12-09 13:49:31 浏览次数:4
试验目的:
1、向管道写端写入数据前,关闭管道写端fd,errno值会是什么?
2、向管道写端写入数据后,关闭管道写端fd,从管道读端读取数据时,是否能正常读取数据?
3、向管道写端写入数据后,关闭管道读端fd,从管道读端读取数据时,会发生什么?errno是什么?
4、向管道写端写入输入前,关闭管道读端fd,是否会触发SIGPIPE信号?程序如何不崩溃?errno值是否会为EPIPE?
1、创建一个管道pipefd[2]
2、向管道写端pipefd[1]写入数据
3、从管道读端pipefd[0]读取数据
4、正常关闭管道写端和读端
1、errno=8, 写端fd报:Bad file descriptor。不会触发SIGPIPE, errno也不会为EPIPE
2、可以正常读取到写入的数据
3、和1情况一样。errno=8, 读端fd报:Bad file descriptor。不会触发SIGPIPE, errno也不会为EPIPE
4、会触发SIGPIPE。
如果程序不处理SIGPIPE或者按照默认方式处理SIGPIPE,则程序会退出。
如果忽略SIGPIPE( 使用signal(SIGPIPE, SIG_IGN); ),则程序不会因为系统触发SIGPIPE而退出,会继续执行完。
在向管道写端写入数据时,errno=8, 为EPIPE, 报:Broken pipe
1、程序中忽略 SIGPIPE信号。
2、向管道写端写入数据时,可以检测errno是否为EPIPE,如果是,可以关闭管道写端fd。
/* * pipe_op.c * * Created on: Jun 24, 2014 * Author: lingyun */#include "pipe_op.h"#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <assert.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <bits/signum.h>#include <signal.h>#define BUFFER_SIZE 1024voidpipe_create(int pipefd[2]) { int ret; ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd); assert(ret != -1);}voidpipe_close(int pipefd) { if (pipefd > 0) { close(pipefd); }}voidpipe_func_test() { //忽略SIGPIP信号 signal(SIGPIPE, SIG_IGN); //按照默认处理方式处理SIGPIP信号 //signal(SIGPIPE, SIG_DFL); int pipefd[2]; pipe_create(pipefd); int pipe_read_fd = pipefd[0]; int pipe_write_fd = pipefd[1]; printf("pipe read end: %d\n", pipe_read_fd); printf("pipe write end: %d\n", pipe_write_fd); //write msg to write_pipe, and read from read_pipe char buf[BUFFER_SIZE]; memset(buf, '/** pipe_op.c** Created on: Jun 24, 2014* Author: lingyun*/#include "pipe_op.h"#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <assert.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <bits/signum.h>#include <signal.h>#define BUFFER_SIZE 1024voidpipe_create(int pipefd[2]) {int ret;ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd);assert(ret != -1);}voidpipe_close(int pipefd) {if (pipefd > 0) {close(pipefd);}}voidpipe_func_test() {//忽略SIGPIP信号signal(SIGPIPE, SIG_IGN);//按照默认处理方式处理SIGPIP信号//signal(SIGPIPE, SIG_DFL);int pipefd[2];pipe_create(pipefd);int pipe_read_fd = pipefd[0];int pipe_write_fd = pipefd[1];printf("pipe read end: %d\n", pipe_read_fd);printf("pipe write end: %d\n", pipe_write_fd);//write msg to write_pipe, and read from read_pipechar buf[BUFFER_SIZE];memset(buf, '\0', BUFFER_SIZE);const char* message = "hello, i'm lingyun";int message_len = strlen(message);strncpy(buf, message, message_len);printf("buf message: %s\n", buf);//1. 向管道写端写数据前, 关闭管道写端fd//pipe_close(pipe_write_fd);//4. 向管道写端写数据前, 关闭管道读端fdpipe_close(pipe_read_fd);ssize_t writed = 0;writed = write(pipe_write_fd, buf, message_len);int save_errno;if (writed == -1) {save_errno = errno;if (errno == EPIPE) {printf("pipe_write_fd is closed, write to this fd has EPIPE error\n");}perror("write");goto failed;}printf("want write message len: %d\n", message_len);printf("writed %d char\n", writed);memset(buf, '\0', BUFFER_SIZE);ssize_t readed = 0;//2. 向管道写端写完数据后, 关闭管道写端fd//pipe_close(pipe_write_fd);//3. 向管道写端写完数据后, 从管道读端读取数据前, 关闭管道读端fd//pipe_close(pipe_read_fd);readed = read(pipe_read_fd, buf, writed);if (readed == -1) {save_errno = errno;if (errno == EPIPE) {printf("pipe_write_fd is closed, read from pipe_read_fd has EPIPE error\n");}perror("read");goto failed;}printf("want read message len: %d\n", writed);printf("readed %d char\n", readed);printf("after read, buf message: %s\n", buf);failed:if(pipe_read_fd != -1) {pipe_close(pipe_read_fd);}if(pipe_write_fd != -1) {pipe_close(pipe_write_fd);}}int main() {pipe_func_test();return 0;}
', BUFFER_SIZE); const char* message = "hello, i'm lingyun"; int message_len = strlen(message); strncpy(buf, message, message_len); printf("buf message: %s\n", buf); //1. 向管道写端写数据前, 关闭管道写端fd //pipe_close(pipe_write_fd); //4. 向管道写端写数据前, 关闭管道读端fd pipe_close(pipe_read_fd); ssize_t writed = 0; writed = write(pipe_write_fd, buf, message_len); int save_errno; if (writed == -1) { save_errno = errno; if (errno == EPIPE) { printf("pipe_write_fd is closed, write to this fd has EPIPE error\n"); } perror("write"); goto failed; } printf("want write message len: %d\n", message_len); printf("writed %d char\n", writed); memset(buf, '/** pipe_op.c** Created on: Jun 24, 2014* Author: lingyun*/#include "pipe_op.h"#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/types.h>#include <assert.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <bits/signum.h>#include <signal.h>#define BUFFER_SIZE 1024voidpipe_create(int pipefd[2]) {int ret;ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd);assert(ret != -1);}voidpipe_close(int pipefd) {if (pipefd > 0) {close(pipefd);}}voidpipe_func_test() {//忽略SIGPIP信号signal(SIGPIPE, SIG_IGN);//按照默认处理方式处理SIGPIP信号//signal(SIGPIPE, SIG_DFL);int pipefd[2];pipe_create(pipefd);int pipe_read_fd = pipefd[0];int pipe_write_fd = pipefd[1];printf("pipe read end: %d\n", pipe_read_fd);printf("pipe write end: %d\n", pipe_write_fd);//write msg to write_pipe, and read from read_pipechar buf[BUFFER_SIZE];memset(buf, '\0', BUFFER_SIZE);const char* message = "hello, i'm lingyun";int message_len = strlen(message);strncpy(buf, message, message_len);printf("buf message: %s\n", buf);//1. 向管道写端写数据前, 关闭管道写端fd//pipe_close(pipe_write_fd);//4. 向管道写端写数据前, 关闭管道读端fdpipe_close(pipe_read_fd);ssize_t writed = 0;writed = write(pipe_write_fd, buf, message_len);int save_errno;if (writed == -1) {save_errno = errno;if (errno == EPIPE) {printf("pipe_write_fd is closed, write to this fd has EPIPE error\n");}perror("write");goto failed;}printf("want write message len: %d\n", message_len);printf("writed %d char\n", writed);memset(buf, '\0', BUFFER_SIZE);ssize_t readed = 0;//2. 向管道写端写完数据后, 关闭管道写端fd//pipe_close(pipe_write_fd);//3. 向管道写端写完数据后, 从管道读端读取数据前, 关闭管道读端fd//pipe_close(pipe_read_fd);readed = read(pipe_read_fd, buf, writed);if (readed == -1) {save_errno = errno;if (errno == EPIPE) {printf("pipe_write_fd is closed, read from pipe_read_fd has EPIPE error\n");}perror("read");goto failed;}printf("want read message len: %d\n", writed);printf("readed %d char\n", readed);printf("after read, buf message: %s\n", buf);failed:if(pipe_read_fd != -1) {pipe_close(pipe_read_fd);}if(pipe_write_fd != -1) {pipe_close(pipe_write_fd);}}int main() {pipe_func_test();return 0;}
', BUFFER_SIZE); ssize_t readed = 0; //2. 向管道写端写完数据后, 关闭管道写端fd //pipe_close(pipe_write_fd); //3. 向管道写端写完数据后, 从管道读端读取数据前, 关闭管道读端fd //pipe_close(pipe_read_fd); readed = read(pipe_read_fd, buf, writed); if (readed == -1) { save_errno = errno; if (errno == EPIPE) { printf("pipe_write_fd is closed, read from pipe_read_fd has EPIPE error\n"); } perror("read"); goto failed; } printf("want read message len: %d\n", writed); printf("readed %d char\n", readed); printf("after read, buf message: %s\n", buf);failed: if(pipe_read_fd != -1) { pipe_close(pipe_read_fd); } if(pipe_write_fd != -1) { pipe_close(pipe_write_fd); }}int main() { pipe_func_test(); return 0;}