I am running linux and I am trying to do the following:
- Run ls in the current directory (using popen)
- Print the result to the buffer (using fread from the channel descriptor)
- close the pipe (using pclose).
Everything works fine (the buffer is filled correctly with the result ls), but when I check the Result pclose () returns -1, and errno - 10 (without child processes). I donβt know why this is happening, but I cannot ignore it (unless there is a reasonable explanation of why this is happening).
My code is:
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 code (buffer write function):
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; }
Thanks in advance! EDIT: ERR_RETURN is just a macro that checks if the condition of the first parameter is true, and if so, type a line in the second parameter and return -1. A.