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. 《Cortex-M0权威指南》之体系结构---栈空间操作

    转载请注明来源:cuixiaolei的技术博客 栈空间作为一种存储器使用机制,是"先入先出"的结构,在系统空间中用作临时数据的存储.栈空间操作的关键之一为栈指针寄存器,每次执行栈操 ...

  2. angularJs中将字符串转换为HTML格式

    首先定义一个filter: .filter( 'to_trusted', ['$sce', function ($sce) { return function (text) { return $sce ...

  3. nodejs7-buffer

    buffer:js在后台操作的必须用到二进制,buffer类就是用于帮助我们处理这种情况   创建buffer对象: new Buffer(size):创建buff对象,有length属性 buf.f ...

  4. iOS 通过tag查找控件

    //比如创建一个UIImageView到view上 UIImageView *imageView = [[UIImageView allc] init]; imageView.tag = 10001; ...

  5. 关于div 浮动在select,或table控件之上

    <div style="position:absolute; display:none; z-index:99999" id="d3" onmouseov ...

  6. MVC System.Web.Mvc.ModelClientValidationRule”同时存在

    错误 2280 类型“System.Web.Mvc.ModelClientValidationRule”同时存在于“C:\Program Files\Microsoft ASP.NET\ASP.NET ...

  7. Game start

    今天开始有计划的码代码吧!!我可是以后要进微软或者google的男人.初步计划先学习编程之美吧,每天码一到题的解法,每天每天每天..然后是ACM竞赛基础,每天一节同上.最后..不对,冷静冷静,我已经没 ...

  8. 使用vhd灌装系统——测试系统专用

    需要使用工具imagex.exe 一. 创建虚拟磁盘: 1.diskpart 2.create vdisk file=c:\test\leiyue.vhd maximum=20000 [tpye=ex ...

  9. 20141016--for 菱形

    Console.Write("请输入一个数:"); int n = int.Parse(Console.ReadLine()); ; i <= n; i++) { ; b & ...

  10. UI1_UITableViewHomeWork

    // // AppDelegate.m // UI1_UITableViewHomeWork // // Created by zhangxueming on 15/7/14. // Copyrigh ...