Linux匿名管道

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux匿名管道相关的知识,希望对你有一定的参考价值。

http://blog.chinaunix.net/uid-26000296-id-3408970.html

 

/*
 * \File
 *   main.c
 * \Descript
 *   father-process reads input file and sends to child-process by anonymous-pipe
 *   client-process transform and write into output file
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

FILE* fp_in = NULL;
FILE* fp_out = NULL;
#define TESTF_IN "test.dat"
#define TESTF_OUT "out.dat"
#define MAX_LINE 512
#define OP_LEN 100

/*
 * \File
 * trans.h 
 * \Descript 
 * 
 */ 
    
#ifndef __TRANS_H__ 
#define __TRANS_H__ 
                                                                                          
int trans_lower2upper(char* buf_in, char* buf_out, int len);
      
#endif


/*
 * \Func
 * main
 * \Descript
 *
 */
 
 
int main(char argc, char* argv[])
{
  int pidstatus;
  int fdfile_in, fdfile_out;

  int fdpipe_a[2];
  int fdpipe_b[2];
  int pid_trans = -1, pid_write = -1;


  /* Create anonymous-pipe */
  if( (pipe(fdpipe_a) < 0) || (pipe(fdpipe_b) < 0))   //创建两个管道
  {
    printf("open pipe failed.\n");
    exit(1);
  }

  if ( (fp_in = fopen(TESTF_IN, "r")) < 0 )  //打开test.dat文件,用于读
  {
    printf("open input file failed: %s\n", TESTF_IN);
    exit(1);
  }

  if ( (fp_out = fopen(TESTF_OUT, "w")) < 0 )   //新建out.dat文件,用于写
  {
    printf("open input file failed: %s\n", TESTF_OUT);
    exit(1);
  }

  if ( (pid_trans = fork()) && (pid_write = fork()) )    //创建两个子进程,父进程工作内容
  {
    /* 
     * PARENT_PROCESS: 
     * read data from in-file, write it into anonymos-pipe.
     */

     int s_read = 0, s_write;
     char bufparent[512];    

     while((s_read = fread(bufparent, sizeof(char), OP_LEN ,fp_in) ) ) //读test.dat文件
     {
       printf("***** %d, %s\n", s_read, bufparent);
       if ( (s_write = write(fdpipe_a[1], bufparent, s_read)) < 0 )//向管道写
       {
         printf("write pipe failed.\n");
         exit(1);
       }
       memset(bufparent, 0, 512);
       if( feof(fp_in) != 0 )  //检查文件是否结束
       {
         printf("\n***** read test.dat over ******\n");
         exit(1);
       }
     }
  }
  else if ( pid_trans == 0 )
  {
    /* 
     * TRANS_PROCESS: 
     * read anonymous-pipe, transcode, write anonymos-pipe. 
     */

    char buftrans_in[512], buftrans_out[512];
    int size_read, size_write;
    int ret;

    while(size_read = read(fdpipe_a[0], buftrans_in, OP_LEN)) //读管道
    {
      ret = trans_lower2upper(buftrans_in, buftrans_out, size_read);

      if ( (size_write = write(fdpipe_b[1], buftrans_out, size_read)) < 0 )  //写管道
      {
        printf("trans-process write failed.\n");
        exit(2);
       }
    }
  }
  else if ( pid_write == 0 )
  {
    /* 
     * WRITE_PROCESS:
     * read anonymous-pipe, write it into out-file
     */
    int s_read, s_write;
    char bufwrite[512];

    while ( s_read = read(fdpipe_b[0], bufwrite, OP_LEN) )  //读管道
    {
      if( (s_write = fwrite(bufwrite, sizeof(char), s_read, fp_out)) < 0) //写out.dat文件
      {
        printf("..... write error.\n");
        exit(3);
      }
      if(s_read < OP_LEN) 
      {
        break;
      }
    }
  }
  else
  {
      printf("fork process failed.\n");
      exit(1);
  }
   
  waitpid(pid_trans, &pidstatus, 0);
  waitpid(pid_write, &pidstatus, 0);
  
  fclose(fp_out);
  fclose(fp_in);

  int s_read2 = 0;
  char bufparent2[512];   
  if ( (fp_out = fopen(TESTF_OUT, "r")) < 0 )   //新建out.dat文件,用于写
  {
    printf("open input file failed: %s\n", TESTF_OUT);
    exit(1);
  }
 
  s_read2 = fread(bufparent2, sizeof(char), OP_LEN ,fp_out);
  printf("***** %d, %s\n", s_read2, bufparent2);
  if( feof(fp_out) != 0 )  //检查文件是否结束
       {
         printf("\n***** pirint out.dat over ******\n");
         exit(1);
       }
 
  fclose(fp_out);
 
  return 0;
   
}   

/*
 * \Func
 * trans_lower2upper
 * \Descript
 * Lowercase turn uppercase
 */
int trans_lower2upper(char* buf_in, char* buf_out, int buf_len) //逐个字符转换成大写字母
{
  int len = buf_len;
  char* cp_in = buf_in;
  char* cp_out = buf_out;
  char atom;
  char offset;

  while(len--)
  {
    atom = *(cp_in++);
    
    if( (atom >= a) && (atom <= z) )
    {
      offset = atom - a;
      atom = A + offset;
    }
    *(cp_out++) = atom;
  }

  return 0;
}

运行结果如下 

技术分享

 出现的问题是 打印out.dat文件内容时,打印了[email protected]:$

 

以上是关于Linux匿名管道的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )(代码片段

Linux匿名管道

linux进程间通信:匿名管道&&命名管道

linux中有名管道与匿名管道的实现

[linux] 详解linux进程间通信

[linux] 详解linux进程间通信