免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3028 | 回复: 4
打印 上一主题 下一主题

[Linux] 父进程重定向子进程标准输出失败问题求助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-08 10:49 |只看该作者 |倒序浏览
走过路过,都来帮忙看看哈,谢谢

小弟在编个原型程序,要求父进程能把子进程的stdin/stdout都重定向到管道里,这样子进程可以从stdin读入父进程管道给的数据,stdout写出到父进程的管道中。
调试中发现子进程可以获得数据,但是父进程一直拿不到数据。困惑中,求各位大神帮助

父进程code

file:enc_dec_test.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

#include <fcntl.h>
/*****************MACRO*******************/

#define BUFFER_SIZE 100
#define STDIN_FILENO 0
#define STDOUT_FILENO 1

#define USE_PIPE

/******************variable******************/

/******************function******************/


int main(int argc, char *argv[])
{
    char buffer[BUFFER_SIZE];
    char *pRead;
    int i, len;
    int child = 0;

    pid_t proc_enc, proc_dec;
    int pipe_in_enc[2];
    int pipe_out_enc[2];
    int pipe_in_dec[2];
    int pipe_out_dec[2];
    char *arg_enc[] = {"./enc_dec_test_sub", "enc", NULL};
    char *arg_dec[] = {"./enc_dec_test_sub", "dec", NULL};
    int status;

    /* create enc pipe */
    pipe(pipe_in_enc);
    pipe(pipe_out_enc);
    if (0 == (proc_enc = fork()))
    {
        child = 1;
        int fd_out = open("out.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

        close(pipe_in_enc[0]);      // 1رո¸½ø3ìμĶá1üμàμÄ×ó½ø3ì¶á¶Ë
        close(pipe_out_enc[1]);     // 1رո¸½ø3ìμÄD′1üμàμÄ×ó½ø3ìD′¶Ë
#ifdef USE_PIPE
        dup2(pipe_out_enc[0], STDIN_FILENO);        // ¸′ÖƸ¸½ø3ìμÄD′1üμàμ½×ó½ø3ìμıê×¼êäèë
        close(pipe_out_enc[0]);     // 1رÕòѸ′ÖÆμÄD′1üμà

#if 0
        dup2(fd_out, STDOUT_FILENO);    // ¸′ÖƸ¸½ø3ìμĶá1üμàμ½×ó½ø3ìμıê×¼êä3ö
        close(fd_out);       // 1رÕòѸ′ÖÆμĶá1üμà
#else
        dup2(pipe_in_enc[1], STDOUT_FILENO);        // ¸′ÖƸ¸½ø3ìμĶá1üμàμ½×ó½ø3ìμıê×¼êä3ö
        close(pipe_in_enc[1]);             // 1رÕòѸ′ÖÆμĶá1üμà
#endif
#endif

        execve(arg_enc[0], arg_enc, NULL);
    }
    else
    {        // ¸¸½ø3ì
        close(pipe_in_enc[1]);        // 1رնá1üμàμÄD′¶Ë
        close(pipe_out_enc[0]);        // 1رÕD′1üμàμĶá¶Ë
    }

    if (!child)
    {
        sleep(1);
        write(pipe_out_enc[1], argv[0], strlen(argv[0]));
        fprintf(stdout, "write %s to enc\n", argv[0]);
        for (i = 0; i < 100; i++)
        {
            if (read(pipe_in_enc[0], buffer, sizeof(buffer) ))
                fprintf(stdout, "get %s from enc\n", buffer);
         }

        waitpid(proc_enc, &status, 0);
    }

    return 0;
}

子进程code
file:enc_dec_test_sub.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/*****************MACRO*******************/

#define BUFFER_SIZE 100
#define USE_PIPE

/******************variable******************/

/******************function******************/

int main(int argc, char *argv[])
{
    char buffer[BUFFER_SIZE];
    char *pRead=NULL;
   
    /* process arguments */
    if (argc < 2)
    {
        fprintf(stderr, "usage: %s sub_id\n", argv[0]);
        return -1;
    }

    do
    {
        pRead = fgets(buffer, BUFFER_SIZE, stdin);
        if (NULL != pRead)
            fprintf(stdout, "[%s -> %s(%s)]\n", buffer, argv[0], argv[1]);
        fflush(stdout);
    }while(1);

    return 0;
}

Makefile
object:enc_dec_test.c enc_dec_test_sub.c
        gcc -g -o enc_dec_test -lpthread enc_dec_test.c
        gcc -g -o enc_dec_test_sub -lpthread enc_dec_test_sub.c



论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
2 [报告]
发表于 2014-05-08 11:53 |只看该作者
本帖最后由 timespace 于 2014-05-08 11:54 编辑

回复 1# 江南愚人
麻烦用code标签把代码格式化,与人方便与己方便。


   

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
3 [报告]
发表于 2014-05-08 13:14 |只看该作者
死锁了。父进程write没有写‘\n’,子进程fgets无法返回。
“write(pipe_out_enc[1], argv[0], strlen(argv[0]));”

其他就不吐槽了,属于C语言基础(返回值,C str边界等等),不是Linux系统编程。这功能学习研究可以写写,真实项目直接用popen。

论坛徽章:
0
4 [报告]
发表于 2014-05-09 09:31 |只看该作者
回复 3# timespace
感谢指导,已经解决
可是boss的要求和这个不符,需要支持任意二进制文件,所以我不能用fgets,改用read。
修改后的问题是,父进程读不到子进程的输出。

enc_dec_test.c
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<unistd.h>

  5. #include <fcntl.h>
  6. /*****************MACRO*******************/

  7. #define BUFFER_SIZE 10

  8. #define USE_PIPE

  9. /******************variable******************/

  10. /******************function******************/

  11. void dumpMem(char *name, char *pdata, int len)
  12. {
  13.     int i;

  14.     fprintf(stderr, "%s %x:", name, (int)pdata);
  15.     for (i = 0; i < len; i++)
  16.     {
  17.         if (0 == (i % 16))
  18.             fprintf(stderr, "\n");
  19.         fprintf(stderr, "0x%02x  ", pdata[i]);
  20.     }
  21.     fprintf(stderr, "\n");
  22. }

  23. int main(int argc, char *argv[])
  24. {
  25.     char buffer[BUFFER_SIZE];
  26.     char buffer_enc[BUFFER_SIZE];
  27.     char buffer_dec[BUFFER_SIZE];
  28.     int  read_cnt, total;
  29.     int i, len;
  30.     int child = 0;

  31.     pid_t proc_enc, proc_dec;
  32.     int pipe_in_enc[2];
  33.     int pipe_out_enc[2];
  34.     int pipe_in_dec[2];
  35.     int pipe_out_dec[2];
  36.     char *arg_enc[] = {"./enc_dec_test_sub", "enc", NULL};
  37.     char *arg_dec[] = {"./enc_dec_test_sub", "dec", NULL};

  38.     /* create enc pipe */
  39.     pipe(pipe_in_enc);
  40.     pipe(pipe_out_enc);
  41.     if(!(proc_enc = fork()))
  42.     {
  43.         child = 1;
  44.         close(pipe_in_enc[0]);      // 1رո¸½ø3ìμĶá1üμàμÄ×ó½ø3ì¶á¶Ë
  45.         close(pipe_out_enc[1]);     // 1رո¸½ø3ìμÄD′1üμàμÄ×ó½ø3ìD′¶Ë
  46. #ifdef USE_PIPE
  47.         close(STDOUT_FILENO);
  48.         dup2(pipe_in_enc[1], STDOUT_FILENO);        // ¸′ÖƸ¸½ø3ìμĶá1üμàμ½×ó½ø3ìμıê×¼êä3ö
  49. //        close(pipe_in_enc[1]);             // 1رÕòѸ′ÖÆμĶá1üμà

  50.         close(STDIN_FILENO);
  51.         dup2(pipe_out_enc[0], STDIN_FILENO);        // ¸′ÖƸ¸½ø3ìμÄD′1üμàμ½×ó½ø3ìμıê×¼êäèë
  52. //        close(pipe_out_enc[0]);     // 1رÕòѸ′ÖÆμÄD′1üμà
  53. #endif
  54.         execve(arg_enc[0], arg_enc, NULL);
  55.         printf("enc pid is %d\n", getpid());
  56.     }else {        // ¸¸½ø3ì
  57.         close(pipe_in_enc[1]);        // 1رնá1üμàμÄD′¶Ë
  58.         close(pipe_out_enc[0]);        // 1رÕD′1üμàμĶá¶Ë
  59.     }
  60. #if 1
  61.     /* create dec pipe */
  62.     pipe(pipe_in_dec);
  63. //    pipe(pipe_out_dec);
  64.     if(!(proc_dec = fork()))
  65.     {
  66.         child = 1;

  67. //        close(pipe_in_enc[0]);
  68.         close(pipe_in_enc[1]);
  69.         close(pipe_out_enc[0]);
  70.         close(pipe_out_enc[1]);
  71.         
  72.         close(pipe_in_dec[0]);      // 1رո¸½ø3ìμĶá1üμàμÄ×ó½ø3ì¶á¶Ë
  73. //        close(pipe_out_dec[1]);     // 1رո¸½ø3ìμÄD′1üμàμÄ×ó½ø3ìD′¶Ë
  74. #ifdef USE_PIPE
  75.         close(STDOUT_FILENO);
  76.         dup2(pipe_in_dec[1], STDOUT_FILENO);        // ¸′ÖƸ¸½ø3ìμĶá1üμàμ½×ó½ø3ìμıê×¼êä3ö
  77. //        close(pipe_in_dec[1]);             // 1رÕòѸ′ÖÆμĶá1üμà

  78.         close(STDIN_FILENO);
  79.         dup2(pipe_in_enc[0], STDIN_FILENO);        // ¸′ÖƸ¸½ø3ìμÄD′1üμàμ½×ó½ø3ìμıê×¼êäèë
  80. //        close(pipe_in_enc[0]);     // 1رÕòѸ′ÖÆμÄD′1üμà
  81. #endif
  82.         execve(arg_dec[0], arg_dec, NULL);
  83.     }else {        // ¸¸½ø3ì
  84.         close(pipe_in_dec[1]);        // 1رնá1üμàμÄD′¶Ë
  85. //        close(pipe_out_dec[0]);        // 1رÕD′1üμàμĶá¶Ë
  86.     }
  87. #endif
  88.     if (!child)
  89.     {
  90.         total = 0;
  91.         do
  92.         {
  93.             read_cnt = read(STDIN_FILENO, buffer,BUFFER_SIZE);
  94.             if (read_cnt)
  95.             {
  96.                 write(pipe_out_enc[1], buffer, read_cnt);
  97. //                read(pipe_in_enc[0], buffer_enc, read_cnt);
  98. //                printf("get %d bytes\n", total);
  99. //                write(1, buffer, read_cnt);
  100. #if 1
  101. //                fprintf(stdout, "get %d bytes:%s from enc\n", strlen(buffer_enc), buffer_enc);
  102. //                write(pipe_out_dec[1], buffer_enc, read_cnt);
  103.                 memset(buffer_dec, 0x5a, BUFFER_SIZE);
  104.                 read(pipe_in_dec[0], buffer_dec, read_cnt);
  105.                 total+=read_cnt;
  106.                 printf("parent get %d bytes\n", total);
  107.                 if (memcmp(buffer, buffer_dec, read_cnt))
  108.                 {
  109.                     printf("different data\n");
  110.                     dumpMem("parent orign", buffer, read_cnt);
  111.                     dumpMem("parent dec", buffer_dec, read_cnt);
  112.                 }
  113. #endif
  114.             }
  115.         }while(read_cnt);

  116. //        printf("loop over\n");

  117.         //enc
  118.         close(pipe_out_enc[1]);        // 1رÕD′1üμà
  119.         close(pipe_in_enc[0]);        // 1رնá1üμà
  120.         //dec
  121.         close(pipe_out_enc[1]);        // 1رÕD′1üμà
  122.         close(pipe_in_enc[0]);        // 1رնá1üμà

  123.         /* ê1óÃwaitÏμáDoˉêyμè′y×ó½ø3ìíË3ö2¢è¡μÃíË3ö′úÂë */
  124.         wait4(proc_enc, NULL, 0, NULL);
  125.         wait4(proc_dec, NULL, 0, NULL);
  126.     }

  127.     return 0;
  128. }
复制代码
enc_dec_test_sub.c
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>

  4. /*****************MACRO*******************/

  5. #define BUFFER_SIZE 10
  6. #define XOR 0X5A
  7. /******************variable******************/

  8. /******************function******************/

  9. void dumpMem(char *name, char *pdata, int len)
  10. {
  11.     int i;

  12.     fprintf(stderr, "%s %x:", name, (int)pdata);
  13.     for (i = 0; i < len; i++)
  14.     {
  15.         if (0 == (i % 16))
  16.             fprintf(stderr, "\n");
  17.         fprintf(stderr, "0x%02x  ", pdata[i]);
  18.     }
  19.     fprintf(stderr, "\n");
  20. }

  21. int main(int argc, char *argv[])
  22. {
  23.     char buffer[BUFFER_SIZE];
  24.     int cnt = 0;
  25.     int i, total;
  26.    
  27.     /* process arguments */
  28.     if (argc < 2)
  29.     {
  30.         fprintf(stderr, "usage: %s sub_id\n", argv[0]);
  31.         return -1;
  32.     }

  33.     total = 0;
  34.     do
  35.     {
  36.         cnt = read(0, buffer, BUFFER_SIZE);
  37.         if (cnt)
  38.         {
  39.                 total += cnt;
  40. //                fprintf(stderr, "%s got %d bytes\n", argv[1], total);
  41.                 dumpMem(argv[1], buffer, cnt);
  42. //            fprintf(stdout, "%s", buffer);
  43.                 for (i = 0; i < cnt; i++)
  44.                 {
  45.                     buffer[i]^=XOR;
  46.                 }
  47. //                dumpMem(argv[1], buffer, cnt);
  48.                 write(1, buffer, cnt);
  49. //                fflush(stdout);
  50.         }
  51.     }while(cnt);

  52.     exit (0);
  53. }
复制代码
makefile
  1. object:enc_dec.c
  2.         gcc -g -o enc_dec -lpthread enc_dec.c
  3.         gcc -g -o enc_dec_test -lpthread enc_dec_test.c
  4.         gcc -g -o enc_dec_test_sub -lpthread enc_dec_test_sub.c
复制代码
运行结果
  1. [root@linux enc_dec]# ./enc_dec_test
  2. a
  3. parent get 2 bytes
  4. different data
  5. parent orign bfbadb26:
  6. 0x61  0x0a
  7. parent dec bfbadb12:
  8. 0x00  0x00
  9. enc bfcdc5ce:
  10. 0x61  0x0a
  11. enc bfcdc5ce:
  12. 0x3b  0x50
  13. dec bfacad5e:
  14. 0x3b  0x50
  15. dec bfacad5e:
  16. 0x61  0x0a
复制代码

论坛徽章:
0
5 [报告]
发表于 2014-05-20 13:58 |只看该作者
你们BOSS要求的是什么?怎么感觉你这个实现的想法好别扭啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP