pipe

子进程从终端读取一个文件名, 通过管道将文件名传递给父进程

父进程收到文件名后, 读取文件内容并通过管道传递给子进程

子进程接收到文件内容并输出到终端

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
#include <sys/wait.h> #define MAXLINE 4096
void err_quit(char *fmt,...){
int errno_save;
errno_save=errno; va_list list;
va_start(list,fmt);
vfprintf(stderr,fmt,list);
if(errno != 0)
fprintf(stderr," :%s",strerror(errno_save));
va_end(list);
exit(1);
}
void Pipe(int *fds){
if(pipe(fds)<0)
err_quit("pipe error");
}
void Close(int fd){
if(close(fd)<0)
err_quit("close error");
}
pid_t Waitpid(pid_t pid,int *statloc,int option){
pid_t retpid=waitpid(pid,statloc,option);
if(retpid == -1)
err_quit("waipid error");
return retpid;
}
char *Fgets(char *buf,int n,FILE *fp){
char *rptr=fgets(buf,n,fp);
if(rptr == NULL && ferror(fp))
err_quit("fgets error");
return rptr;
}
ssize_t Read(int fd,void *buf,size_t nbytes){
ssize_t nread=read(fd,buf,nbytes);
if(nread == -1)
err_quit("read error");
return nread;
}
void Write(int fd,void *buf,size_t nbytes){
if(write(fd,buf,nbytes) != nbytes)
err_quit("write error");
} void client(int,int), server(int,int);
int main(int argc, char *argv[]){
int pipe1[2],pipe2[2];
pid_t childpid; Pipe(pipe1);
Pipe(pipe2); if((childpid=fork())<0)
err_quit("fork error");
else if(childpid == 0){
Close(pipe1[1]);
Close(pipe2[0]); server(pipe1[0],pipe2[1]);
}else{
Close(pipe1[0]);
Close(pipe2[1]); client(pipe2[0],pipe1[1]);
Waitpid(childpid,NULL,0);
}
exit(0);
} void client(int readfd,int writefd){
size_t len;
ssize_t n;
char buf[MAXLINE]; Fgets(buf,MAXLINE,stdin);
len=strlen(buf);
if(buf[len-1] == '\n')
len--;
Write(writefd,buf,len); while((n=Read(readfd,buf,MAXLINE))>0)
Write(STDOUT_FILENO,buf,n);
}
void server(int readfd,int writefd){
int fd;
ssize_t n;
char buff[MAXLINE]; if((n=Read(readfd,buff,MAXLINE))==0)
err_quit("end-of-file while reading pathname");
buff[n]='\0'; if((fd=open(buff,O_RDONLY))<0){
snprintf(buff+n,sizeof(buff)-n,":can't open, %s\n",
strerror(errno));
n=strlen(buff);
Write(writefd,buff,n);
}else{
while((n=Read(fd,buff,MAXLINE))>0)
Write(writefd,buff,n);
Close(fd);
}
}

popen/pclose

popen的打开属性为读或写

写时表示向子进程传递命令, 读时表示从子进程读取命令的执行结果

//头文件和其它包裹函数同pipe
void Fputs(const char *ptr,FILE *fp){
if(fputs(ptr,fp)==EOF)
err_quit("fputs errro");
}
FILE *Popen(const char *command,const char *type){
FILE *fp;
if((fp=popen(command,type)) == NULL)
err_quit("popen error");
return fp;
}
void Pclose(FILE *fp){
if(pclose(fp) == -1)
err_quit("pclose error");
} int main(int argc, char *argv[]){
size_t n;
char buff[MAXLINE],command[MAXLINE];
FILE *fp; Fgets(buff,MAXLINE,stdin);
n=strlen(buff);
if(buff[n-1]=='\n')
n--; snprintf(command,sizeof(command),"cat %s",buff);
fp=Popen(command,"r"); while(Fgets(buff,MAXLINE,fp) != NULL)
Fputs(buff,stdout); Pclose(fp);
exit(0);
}

FIFO

在管道的基础上, 增加了管道命名, 在物理磁盘上会多出一个管道文件, 可用于非亲代进程之间传递消息

mkfifo函数用于创建命名管道, 默认含有O_CREAT | O_EXCL属性, 要么创建新管道文件, 要么出错返回EEXIST

管道文件打开模式要么只读要么只写, 不支持lseek

//头文件和其它包裹函数同pipe
#include <sys/types.h>
#include <sys/stat.h> int Open(const char *pathname,int flag,mode_t mode){
int fd;
if((fd=open(pathname,flag,mode)) == -1)
err_quit("open error");
return fd;
}
void Unlink(const char *pathname){
if(unlink(pathname) == -1)
err_quit("unlink error");
} #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define FIFO1 "./fifo.1"
#define FIFO2 "./fifo.2"
int main(int argc, char *argv[]){
int readfd,writefd;
pid_t childpid; if((mkfifo(FIFO1,FILE_MODE)) && (errno != EEXIST))
err_quit("can't create %s",FIFO1);
if((mkfifo(FIFO2,FILE_MODE)<0) && (errno != EEXIST)){
Unlink(FIFO1);
err_quit("can't create %s",FIFO2);
} if((childpid=fork())<0)
err_quit("fork error");
else if(childpid==0){
readfd=Open(FIFO1,O_RDONLY,0);
writefd=Open(FIFO2,O_WRONLY,0); server(readfd,writefd);
exit(0);
} writefd=Open(FIFO1,O_WRONLY,0);
readfd=Open(FIFO2,O_RDONLY,0); client(readfd,writefd); Waitpid(childpid,NULL,0); Close(readfd);
Close(writefd); Unlink(FIFO1);
Unlink(FIFO2);
exit(0);
}

管道和FIFO的更多相关文章

  1. 第四章:管道与FIFO

    4.1:概述 管道是最初的Unix IPC形式,可追溯到1973年的Unix第三版.尽管对于许多操作来说很有用,但它们的根本局限在于没有名字,从而只能由亲缘关系的进程使用.这一点随FIFO的加入得改正 ...

  2. linux进程间通信-有名管道(FIFO)

    有名管道(FIFO) 命名管道也被称为FIFO文件,是一种特殊的文件.由于linux所有的事物都可以被视为文件,所以对命名管道的使用也就变得与文件操作非常统一. (1)创建命名管道 用如下两个函数中的 ...

  3. 第4章 管道和FIFO

    4.1 管道 管道是由pipe函数创建的,提供一个单向数据流. 头文件 #include <unistd.h> 函数原型 int pipe(int fd[2]); 返回值 成功则为0,出错 ...

  4. Linux系统编程——进程间通信:命名管道(FIFO)

    命名管道的概述 无名管道,因为没有名字,仅仅能用于亲缘关系的进程间通信(很多其它详情.请看<无名管道>).为了克服这个缺点.提出了命名管道(FIFO).也叫有名管道.FIFO 文件. 命名 ...

  5. 第4章 管道与FIFO

    4.1 概述 管道只在亲缘进程间使用,FIFO在任意进程间使用 4.2 管道 #include <unistd.h> ]) fd[0]用来读管道,fd[1]用来写管道 1)命令who |  ...

  6. [转] IPC之管道、FIFO、socketpair

    管道和FIFO作为最初的UNIX IPC形式,现在已用得较少.SocketPair可作为全双工版本的管道,较为常用,这里简单做个笔记 管道 * 只用于有亲缘关系的进程间通信 * 单向,即半双工 (双向 ...

  7. linux 有名管道(FIFO)

    http://blog.csdn.net/firefoxbug/article/details/8137762 linux 有名管道(FIFO) 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时 ...

  8. UNIX环境高级编程——管道和FIFO限制

    系统加于管道和FIFO的唯一限制为: OPEN_MAX     一个进程在任意时刻打开的最大描述符数: PIPE_BUF       可原子的写往一个管道或FIFO的最大数据量. OPEN_MAX的值 ...

  9. UNIX环境高级编程——管道和FIFO的额外属性

    一个描述符能以两种方式设置成非阻塞. (1)调用open时可以指定O_NONBLOCK标志. writefd = open(FIFO1,O_WRONLY | O_NONBLOCK,0); (2)如果一 ...

  10. 管道和FIFO 一

    管道和FIFO   管道(pipe)       管道在Unix及Linux进程间通信是最基础的,很容易理解.管道就像一个自来水管,一端注入水,一端放出水,水只能在一个方向上流动,而不能双向流动.管道 ...

随机推荐

  1. Tomcat内存设置详解

    Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...

  2. 《Cortex-M0权威指南》之体系结构---程序映像和启动流程

    转载请注明来源:cuixiaolei的技术博客 我们先来看看程序映像. 通常,Cortex-M0处理器的程序映像时从地址0x00000000处开始的. 程序映像开始处时向量表,其中包含了异常的其实地址 ...

  3. python 基础——generate生成器

    通过列表表达式可以直接生成列表,不过列表一旦生成就需要为所有元素分配内存,有时候会很消耗资源. 所以,如果列表元素可以按照某种算法推算出来,这样就不必创建完整的list,从而节省大量的内存空间. 在P ...

  4. python 打包exe注意的问题

    教程百度.谷歌都有,本文讲讲安装时出错的问题. 教程:http://keliang.blog.51cto.com/3359430/661884 1.cxfreeze 找不到路径时: 需要修改Scrip ...

  5. Jquery AJax Post 返回值问题

    var msg=0; Validater('abc'); function Validater(Name) { var itemId = 1; $.ajax({ url: 'adminmenu/Val ...

  6. Server.UrlEncode、HttpUtility.UrlDecode的区别

    Server.UrlEncode.HttpUtility.UrlDecode的区别 在对URL进行编码时,该用哪一个?这两都使用上有什么区别吗? 测试: string file="文件上(传 ...

  7. highcharts 图表库的简单使用

    Highcharts简介: Highcharts是一款纯javascript编写的图表库,能够很简单便捷的在Web网站或Web应用中添加交互性的图表,Highcharts目前支持直线图.曲线图.面积图 ...

  8. netbeans 优化设置

    下面我就以Windows上的NetBeans安装为例,说说如何配置字体. 1.NetBeans界面上的普通字体大小,可以通过配置NetBeans安装目录下netbeans.conf启动文件来实现,这个 ...

  9. Mac下github的使用

    新建github账户   新建Repository,如下图:   建立连接github的秘钥 打开mac的shell cd ~ mkdir .ssh cd .ssh ssh-keygen -t rsa ...

  10. Toad for Oracle Authorization key

    Authorization key :    0-63920-00993-29060-08749 sit         message  :     li