用popen()打开的文件描述符上的pclose()返回errno 10(没有子进程)

问题描述 投票:4回答:2

我正在运行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。

c linux popen fread pclose
2个回答
0
投票

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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.