c read() 導致錯誤的文件描述符錯誤 (c read() causing bad file descriptor error)


問題描述

c read() 導致錯誤的文件描述符錯誤 (c read() causing bad file descriptor error)

Context for this is that the program is basically reading through a filestream, 4K chunks at a time, looking for a certain pattern. It starts by reading in 4k, and if doesn't find the pattern there, it starts a loop which reads in the next 4k chunk (rinse and repeat until EOF or pattern is found). On many files the code is working properly, but some files are getting errors. 

The code below is obviously highly redacted, which I know might be annoying, but it includes ALL lines that reference the file descriptor or the file itself. I know you don't want to take my word for it, since I'm the one with the problem...

Having done a LITTLE homework before crying for help, I've found:

  1. The file descriptor happens to always = 6 (it's also 6 for the files that are working), and that number isn't getting changed through the life of execution. Don't know if that's useful info or not.

  2. By inserting print statements after every operation that accesses the file descriptor, I've also found that successful files go through the following cycle "open-read-close-close" (i.e. the pattern was found in the first 4K) Unsuccessful files go "open-read-read ERROR (Bad File Descriptor)-close." So no premature close, and it's getting in the first read successfully, but the second read causes the Bad File Descriptor error.

.

int function(char *file)
{

int len, fd, go = 0;
char buf[4096];

if((fd = open(file, O_RDONLY)) <= 0)
{
    my_error("Error opening file %s: %s", file, strerror(errno));
    return NULL;
}

//first read
if((len = read(fd, buf, 4096)) <= 0)
{
    my_error("Error reading from file %s: %s", file, strerror(errno));
    close(fd); return NULL;
}

//pattern-searching

if(/*conditions*/)
{
    /* we found it, no need to keep looking*/
    close(fd);
}

else
{
    //reading loop
    while(!go)
    {
        if(/*conditions*/)
        {
            my_error("cannot locate pattern in file %s", file);
            close(fd); return NULL;
        }

        //next read
        if((len = read(fd, buf, 4096)) <= 0) /**** FAILS HERE *****/
        {
            my_error("Error reading from file, possible bad message %s: %s",
                file, strerror(errno));    
            close(fd); return NULL;
        }

        if(/*conditions*/)
        {
            close(fd);
            break;
        }

        //pattern searching

        if(/*conditions*/)
        {
             /* found the pattern */
            go++; //break us out of the while loop

            //stuff

            close(fd);
        }
        else
        {
            //stuff, and we will loop again for the next chunk
        }
    } /*end while loop*/
}/*end else statement*/

close(fd);
}

.

Try not to worry about the pattern-reading logic - all operations are done on the char buffer, not on the file, so it ought to have no impact on this problem.


參考解法

方法 1:

EOF returns 0 (falls into if ... <= 0), but does not set errno, which may have an out of date code in it.

Try testing for 0 and negative (error, -1) values seperately.


Regarding "strace":  I've used it a little at home, and in previous jobs.  Unfortunately, it's not installed in my current work environment.  It is a useful tool, when it's available.  Here, I took the "let's read the fine manual" (man read) approach with the questioner  :-)

(by VMillsRoboprog)

參考文件

  1. c read() causing bad file descriptor error (CC BY-SA 3.0/4.0)

#file-descriptor #C






相關問題

在 Android 中持久化文件描述符 (Persisting File Descriptors in Android)

無法理解 select() 系統調用 (failure to understand select() system call)

文件描述符中實際存儲了多少信息? (How much information is actually stored in a file descriptor?)

為同一個文件描述符創建兩個文件是否定義明確? (Is creating two FILEs for the same file descriptor well-defined?)

Android文件描述符洩漏調試 (Android file descriptor leakage debuging)

C中的文件描述符分配 (File Descriptor Assignment in C)

在某些 linux 程序中關閉奇怪的描述符 (Strange descriptor closing in some linux programs)

c read() 導致錯誤的文件描述符錯誤 (c read() causing bad file descriptor error)

C中系統調用的文件句柄問題 (Filehandle issue with system call in C)

使用 copy_file_range 進行複制加速 (Copy acceleration with copy_file_range)

打開文件過多錯誤,但 99.5% 的 inode 是免費的 (Too many open files error but 99.5% inodes are free)

SIGPIPE 由於文件描述符和進程替換 (SIGPIPE due to file descriptors and process substitution)







留言討論