The code below returns EFAULT (errno == 14). I would appreciate help figuring out why.
I've also tried to implement the code using select() but still got the same error code.
I've got very similar code running on Python with no issues.
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
int read_fail1(int fd)
{
int n;
char buf[500];
for (;;)
{
buf[strlen(buf)-1] = 0;
n = read(fd, buf, strlen(buf)-1);
if (n == -1)
{
if (errno == EFAULT)
{
fprintf(stderr, "EFAULT");
return 42;
}
}
else if (n > 0)
{
fprintf(stderr, "%s", buf);
}
}
}
int main(int argc, const char *argv[])
{
const char *myfifo = "pipeMUD";
mkfifo(myfifo, 0666);
int fd = open(myfifo, O_RDWR | O_NONBLOCK);
if (fd <= 0)
return 42;
read_fail1(fd);
return 0;
}
POST ANSWER EDIT:
As mentioned in the post linked below, if an invalid address is passed to the kernel, it throws the EFAULT. I guess that on Linux, based on the above code, passing a 0 length count parameter to read() will also cause EFAULT to be retured.
This line:
buf[strlen(buf)-1] = 0;
buf
if a local variable, and thus is not initialized in C.
strlen
looks for '\0' (null character) value, and thus will give unpredictable result on uninitialized array.
But, as long as you declare buf
statically as you do, you can use sizeof
instead.
Though it would be a better practice to use a macro instead:
#define READ_BUFFER_SIZE 500
char buf[READ_BUFFER_SIZE];
n = read(fd, buf, READ_BUFFER_SIZE - 1);