[Linux管道和IPC]管道的实际应用2

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <limits.h>
#include <string.h>
#include <sys/wait.h>
#include <error.h>

#define DEF_PAGER "/bin/more"   //定义处理函数
#define MAXLINE  4096   //行最大字符数

int main(int argc, char *argv[])
{
  int     n;
  int     fd[2];
  pid_t   pid;
  char    *pager, *argv0;
  char    line[MAXLINE];
  FILE    *fp;
  if (argc != 2)  //如果参数不正确
  {
    printf("请输入正确的命令:<pathname>\n");
    exit(1);
  }
  if ((fp = fopen(argv[1], "r")) == NULL)  //如果以只读打开argv[1]指向的文件出错
  {
    printf("不能打开文件%s", argv[1]);
    exit(1);
  }
  if (pipe(fd) < 0)  //创建管道失败
  {
    printf("创建管道失败\n");
    exit(0);
  }
  if ((pid = fork()) < 0)  //创建子进程失败
  {
    printf("创建子进程失败\n");
    exit(0);
  }
  else if (pid > 0)
  {                               //父进程
    close(fd[0]);           //关闭读文件描述符
    //将argv[1]通过管道发送
    while (fgets(line, MAXLINE, fp) != NULL)
    {
      n = strlen(line);
      if (write(fd[1], line, n) != n)
      {
        printf("写管道失败\n");
        exit(1);
      }
    }
    if (ferror(fp))  //如果文件描述符出错
    {
        printf("fgets 失败\n");
        exit(1);
    }
    close(fd[1]);   //
    if (waitpid(pid, NULL, 0) < 0)
    {
        printf("waitpid失败\n");
        exit(1);
    }
    exit(0);
  }
  else  //子进程
  {
    close(fd[1]);
    if (fd[0] != STDIN_FILENO)
    {
      if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
      {
        printf("dup2到标准输入失败\n");
        exit(1);
      }
      close(fd[0]);   /* don‘t need this after dup2 */
    }
    //exec函数的参数
    if ((pager = getenv("PAGER")) == NULL)
    {
      pager = DEF_PAGER;
    }
    if ((argv0 = strrchr(pager, ‘/‘)) != NULL)
    {
      argv0++;
    }
    else
    {
      argv0 = pager;
    }
    if (execl(pager, argv0, (char *)0) < 0)
    {
      printf("调用execl失败%s", pager);
      exit(1);
    }
  }
  exit(0);
}
时间: 2024-10-13 11:55:28

[Linux管道和IPC]管道的实际应用2的相关文章

练习--LINUX进程间通信之无名管道PIPE

IBM上放的这个系统不错,刚好可以系统回温一下LINUX的系统知识. http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/ 感觉年纪大了,前几年看的LINUX内核和系统的东东,忘了很多,要慢慢转化成永久记忆才可以. 今天,又拿起<LINUX内核设计与实现>,慢慢啃下去. ~~~~~~~~~~~~~~ 进程通信有如下一些目的:A.数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间B.共享数据:多个进程想

linux系统编程之管道(一):匿名管道(pipe)

原文地址:http://www.cnblogs.com/mickole/p/3192210.html 一,什么是管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: 管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. 数据的读

Unix/Linux进程间通信(二):匿名管道、有名管道 pipe()、mkfifo()

1. 管道概述及相关API应用 1.1 管道相关的关键概念 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: 管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出.

Linux环境进程间通信(一):管道及有名管道

在本系列序中作者概述了 linux 进程间通信的几种主要手段.其中管道和有名管道是最早的进程间通信机制之一,管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信. 认清管道和有名管道的读写规则是在程序中应用它们的关键,本文在详细讨论了管道和有名管道的通信机制的基础上,用实例对其读写规则进行了程序验证,这样做有利于增强读者对读写规则的感性认识,同时也提供了应用范例. 1. 管道概述及相关API应用 1.1 管道相关的关

Linux管道和命名管道

本系列序中作者概述了 linux 进程间通信的几种主要手段.其中管道和有名管道是最早的进程间通信机制之一,管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信. 认清管道和有名管道的读写规则是在程序中应用它们的关键,本文在详细讨论了管道和有名管道的通信机制的基础上,用实例对其读写规则进行了程序验证,这样做有利于增强读者对读写规则的感性认识,同时也提供了应用范例. 1 管道概述及相关API应用 1.1 管道相关的关键概

linux应用开发-无名管道编程

linux应用开发-无名管道编程 一 linux进程间通信(ipc) 1 UNIX进程间通信 2 基于System V的通信 3 POSIX通信 二 七种通信方式 1 管道 一个进程在管道的尾部写入数据,另一个进程从管道的头部 读出数据.管道包括无名管道和有名管道两种,前者只能用 于父进程和子进程间的通信,后者可用于运行于同一系统中 的任意两个进程间的通信. 分类: 无名管道(pipo):用于父进程和子进程间的通信 有名管道(FIFO):用于运行于同一系统中的任意两个进程间的通信 特点: 1 管

进程-IPC 管道 (一)

详见:https://github.com/ZhangzheBJUT/linux/blob/master/IPC(%E4%B8%80).md 一 IPC 概述 进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么两方都能够訪问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相訪问的,唯一的例外是共享内存区.系统空间是"公共场所".所以内核显然能够提供这种条件,例如以下图所看到的. 除此以外,那就是两方都能够訪问的外设了.两个进程能够通过磁盘上的普通文件交换信息.

Linux进程间通信 -- 使用命名管道

在前一篇文章—— Linux进程间通信 -- 使用匿名管道 中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关的的进程之间交换数据带来了不方便.这里将会介绍进程的另一种通信方式——命名管道,来解决不相关进程间的通信问题. 一.什么是命名管道 命名管道也被称为FIFO文件,它是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但是它的行为却和之前所讲的没有名字的管道(匿名管道)类似. 由于Linux中所有

Linux学习记录--命名管道通信

命名管道通信 什么是命名管道 一个主要的限制是,它是匿名管道的应用还没有名字,因此,只有它可以用于进程间通信的方式与亲缘关系.在命名管道(named pipe或FIFO)提出后,该限制得到了克服.FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中. 这样,即使与FIFO的创建进程不存在亲缘关系的进程,仅仅要可以訪问该路径,就行彼此通过FIFO相互通信 有名管道创建 int mkfifo(const char * pathname, mode_t mode)