pipe, popen, dup, dup2

pipe和popen可以帮助我们实现类似shell下面的,如 cat file | cksum | echo 等管道操作。
下面是例子:
1. 运行cksum imagename,得到其输出进行处理
static bool check_image(char * imagename, char * crc, char * len)
{
    FILE * fp;
    char command[120];
    char buf[200], tImagename[120];
    char tCrc[10], tLen[10];
    bool ret;

    sprintf(command, "cksum %s", imagename);
    fp = popen(command, "r");
    if(fp == NULL) return false;

    fgets(buf, 200, fp);
    fprintf(stdout, "Check Image:  %s... Done\n", buf);
    sscanf(buf, "%s %s %s", tCrc, tLen, tImagename);
    pclose(fp);
    ret = (strcmp(crc, tCrc) == 0) && (strcmp(len, tLen) == 0);
    if(!ret)
    {
        fprintf(stderr, "Err: check image crc failed\n");
    }
    return ret;
}

2. 读取数据给chksum,然后处理输出

static bool check_write(char * devname, char * crc, char * len)
{
     FILE * fp;
     char command[120];
     int old = -1, pipefd[2];
     bool result = false;

     char *pbuf;
     int length;
     int count;

     if(pipe(pipefd) != 0)
         return false;

     if((old = dup(STDOUT_FILENO)) == -1) //back up stdout to old
         goto fail2;

     if(dup2(pipefd[1], STDOUT_FILENO) == -1) //set stdout to pipefd[1]
       goto fail2;

     sprintf(command, "cksum");
     fp = popen(command, "w");
     if(fp == NULL) goto fail2;

     /*---------------------------- read data and write to pipe -----------------*/
     length = atoi(len);
     fprintf(stderr, "length = %d\n", length);
     pbuf = malloc(length);
     if(pbuf == NULL) goto fail2;
     if(flash_read(devname, pbuf, length) == 0)
     {
         count = fwrite(pbuf, 1, length, fp);
         if(count != length) fprintf(stderr, "Err: fwrite did not wrote %d(but %d)\n", length, count);
     }
     else
     {
         fprintf(stderr, "Err: flash_read failed\n");
     }
     free(pbuf);
     /*---------------------------- end -----------------------------------------*/

     pclose(fp);

     //read and check result
     memset(command, 0, 100);
    read(pipefd[0], command, 100);
     if(strstr(command, crc) == command)
     {
        result = true;
     }

fail2:
     if(old != -1) dup2(old, STDOUT_FILENO); //recover stdout to old
     close(pipefd[0]);
     close(pipefd[1]);
     if(result) fprintf(stdout, "Check Result: %s... Done\n", command);
     else   fprintf(stdout, "Check Result: %s... Fail\n", command);
     return result;
}

另备:
上述代码是在实现image_update时运用的,当写入文件较大,比如50M,出现类似下面的问题,查不出原因,暂时采取其它解决方法:
../image_update: can't resolve symbol 'pread'
cksum: can't resolve symbol 'close'
sh: can't resolve symbol 'free'
[  477.950000] Kernel panic - not syncing: Attempted to kill init!

 

你可能感兴趣的:(职场,pipe,休闲)