简体   繁体   中英

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" (ie 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.

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:-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM