Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

c - reading from non-blocking named pipe gives EFAULT (14) in Ubuntu

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.

unix socket error 14: EFAULT (bad address)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This line:

buf[strlen(buf)-1] = 0;

buf if a local variable, and thus is not initialized in C. strlen looks for '' (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);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...