⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pipe.c

📁 Linux平台下的用c语言实现pipe(进程间通信的一种)
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <limits.h>		// for PIPE_BUF#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#define BUFFER_SIZE	PIPE_BUFtypedef struct file_info{  unsigned long filenamesize;  unsigned long filesize;} file_info_t;int global_exit_flag = 0;void parent_process_main(int fd, char *filename);void child_process_main(int fd);void signal_handler(int s);int main(int argc, char **argv){  int fds[2];  if (argc < 2)  {    fprintf(stdout, "Usage: %s <filename>\n", argv[0]);    exit(0);  }  //int pipe(int fildes[2]);  if (pipe(fds) < 0)  {    fprintf(stderr, "Create a pipe failed: %s\n", strerror(errno));    exit(1);  }  fprintf(stdout, "write endpoint: %d\n", fds[1]);  fprintf(stdout, "read endpoint: %d\n", fds[0]);  pid_t pid;  //pid_t fork(void);  if ((pid = fork()) < 0)  {    fprintf(stderr, "fork() failed: %s\n", strerror(errno));    exit(1);  }  else if (pid == 0)  {    // XXX: child process, close write endpoint    close(fds[1]);    child_process_main(fds[0]);    exit(0);  }  else  {    // XXX: parent process, close read endpoint    close(fds[0]);    parent_process_main(fds[1], argv[1]);  }  close(fds[0]);  close(fds[1]);  return 0;}void parent_process_main(int fd, char *filename){  char buffer[BUFFER_SIZE];  ssize_t written;  ssize_t offset = 0;  //int length;  int source_fd;  struct stat s;  // int open(const char *pathname, int flags, mode_t mode);  if ((source_fd = open(filename, O_RDONLY)) < 0)  {    fprintf(stderr, "open source file failed: %s\n", strerror(errno));    exit(1);  }  //int fstat(int filedes, struct stat *buf);  if (fstat(source_fd, &s) < 0)  {    // On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.    fprintf(stderr, "fstat() failed: %s\n", strerror(errno));    exit(1);  }  file_info_t f;  memset(&f, 0, sizeof(f));  f.filenamesize = strlen(filename);  f.filesize = s.st_size;  signal(SIGINT, signal_handler);  signal(SIGTERM, signal_handler);  // FIXME: check return value of write  // ssize_t write(int fd, const void *buf, size_t count);  write(fd, &f, sizeof(f));  write(fd, filename, strlen(filename));  ssize_t read_bytes;  //char *fgets(char *s, int size, FILE * stream);  //ssize_t read(int fildes, void *buf, size_t nbyte);  while (1)  {  retry:    if ((read_bytes = read(source_fd, buffer, BUFFER_SIZE)) < 0)    {      if (errno == EINTR)      {	goto retry;      }      else      {	fprintf(stderr, "[%d]read from source file failed: %s\n", getpid(), strerror(errno));	// FIXME: 	break;      }    }    else if (read_bytes == 0)    {      // end of file      break;    }    else    {      offset = 0;      while (offset < read_bytes)      {      again:	//ssize_t write(int fd, const void *buf, size_t count);	if ((written = write(fd, buffer + offset, read_bytes - offset)) < 0)	{	  if (errno == EINTR)	  {	    fprintf(stdout, "[%d]Got a signal, retry.\n", getpid());	    goto again;	  }	  else	  {	    fprintf(stderr, "[%d]write() failed: %s\n", getpid(), strerror(errno));	    // FIXME: 	    exit(1);	  }	}	else	{	  offset += written;	}      }    }    fprintf(stdout, "[%d]written %d bytes to pipe.\n", getpid(), read_bytes);    if (global_exit_flag)    {      break;    }  }  fprintf(stdout, "[%d]out of fetch string from stdin.\n", getpid());}void child_process_main(int fd){  char buffer[BUFFER_SIZE];  ssize_t n;  //int get_file_info = 0;  int total_read_bytes = 0;  for (;;)  {  again:    //ssize_t read(int fd, void *buf, size_t count);    if ((n = read(fd, buffer + total_read_bytes, sizeof(file_info_t) - total_read_bytes)) < 0)    {      if (errno == EINTR)      {	goto again;      }      else      {	fprintf(stderr, "read() failed from pipe: %s\n", strerror(errno));	exit(1);      }    }    else if (n == 0)    {      // TODO:    }    else    {      total_read_bytes += n;      if (total_read_bytes >= sizeof(file_info_t))      {	break;      }    }  }  int file_name_length = ((file_info_t *) buffer)->filenamesize;  int file_size = ((file_info_t *) buffer)->filesize;  fprintf(stdout, "[%d]file_name_length = %d\n", getpid(), file_name_length);  fprintf(stdout, "[%d]file_size = %d\n", getpid(), file_size);  // TODO: get filename  // TODO: read file content and write a file}void signal_handler(int s){  fprintf(stdout, "Caught signal %d, exiting...\n", s);  global_exit_flag = 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -