4

我正在运行 linux,我尝试执行以下操作:

  1. 在当前目录上运行 ls(使用 popen)
  2. 将结果输出到缓冲区(使用管道描述符中的 fread)
  3. 关闭管道(使用 pclose)。

一切正常(缓冲区已正确填充 ls 结果),但是当我检查 pclose() 结果时,它返回 -1 并且 errno 设置为 10(无子进程)。不知道为什么会发生这种情况,但我不能忽略它(除非对为什么会发生这种情况有合理的解释)。

我的代码:

FILE * lsoutput = NULL;
lsoutput = popen("ls -ltr", "r");
if (readFromPipeOrFile(lsOutput, pSendBuf, pSendActualSize) == -1)
{
        printf("readFromPipeOrFile failed.");
        pclose(lsOutput);
        safeFree(pSendBuf);
        return -1;
}

if (pclose(lsOutput) == -1) // No idea why it returns -1 but it does...
{
        printf("pclose failed");
        printf("errno: %d\n", errno);
        printf("strerror: '%s'", strerror(errno));
        return -1;
}

readFromPipeOrFile 的代码(写入缓冲区的函数):

int readFromPipeOrFile(FILE * pipeOrFile, char ** pSendBuf, size_t * pSendActualSize)
{
     int multiplication = 1;
     char * pSendBufCurrentLocation = NULL;
     ERR_RETURN(pipeOrFile == NULL || pSendBuf == NULL || pSendActualSize == NULL,
                     "No values should be NULL.");
     ERR_RETURN(*pSendBuf != NULL, "*pSendBuf should be NULL");

     *pSendBuf = (char *) calloc (MAX_READ_FROM_STREAM * multiplication, sizeof(char));
     ERR_RETURN(*pSendBuf == NULL, "Failed allocating sendBuf");

     pSendBufCurrentLocation = *pSendBuf;
     while (fread(pSendBufCurrentLocation, MAX_READ_FROM_STREAM, 1, pipeOrFile) == 1)
     {
             ++multiplication;
             *pSendBuf = realloc(*pSendBuf, MAX_READ_FROM_STREAM * multiplication);
             ERR_RETURN(*pSendBuf == NULL, "Failed re-allocating sendBuf");

             pSendBufCurrentLocation = *pSendBuf + (MAX_READ_FROM_STREAM * (multiplication - 1));
             memset(pSendBufCurrentLocation, '\0', MAX_READ_FROM_STREAM);
     }

     ERR_RETURN(!feof(pipeOrFile), "Hasn't reached eof but fread stopped");
     ERR_RETURN(ferror(pipeOrFile), "Error in fread");

     *pSendActualSize = MAX_READ_FROM_STREAM * multiplication;

     return 0;
}

提前致谢!编辑:ERR_RETURN 只是一个宏,它检查第一个参数的条件是否为真,如果是,则在第二个参数中打印字符串并返回 -1。

4

2 回答 2

2

signal(SIGCHLD, SIG_IGN)将导致 pclose() 结果返回 -1 并且 errno 设置为 10(无子进程)。

于 2014-06-09T13:21:05.343 回答
0

根据文档pclose()-1如果wait4返回错误,则返回。但是,它没有说明设置errno(除了设置ECHILD如果它无法获得子状态),所以我不太确定你可以指望strerror()字符串是准确的。

这意味着ls退出时出现错误代码,这意味着ls访问子目录时遇到问题(权限错误?)。因此,您有结果,因为ls返回了它可以读取的内容,但它是不完整的读取,因为它无法访问递归中的子目录。

于 2013-04-13T22:35:06.097 回答