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!