Vtirum
Vtirum

Reputation: 41

File handle left behind by C++ code in Linux

I am trying to debug an issue in my code. I have a process A which runs continuously till I ask it to stop.

Inside A I do the following:

Note I test after each operation above if it was successful or not befor moving forward. When I do lsof | grep A it shows the file handle of X being owned by process A. I also see it has a (deleted). This prevents me from umounting the partition. Why is this happening and how can I get around this issue?

EDIT: Thanks all. Here is the snippet of the code:

tarFileDesc = _pSysCall->open("test.tar", O_CREAT | O_RDWR | O_APPEND, 0777);    
 if (0 > tarFileDesc)
  return false;

 ... some logging here

 // Write http stream to tar file, istr is an argument to my function     
 int read_buffer_size = 0;     
 buffer = new char[4096];     
 while (!istr.eof() && count < content_length)
 {      
    if ((content_length - count) >= 4096)
        read_buffer_size = 4096;
    else
        read_buffer_size = content_length - count;

    memset(buffer, 0, 4096);
    istr.read(buffer, read_buffer_size);
    std::streamsize in_bytes = istr.gcount();
    if (istr.fail() || istr.bad())
    {
        status = false;
        break;
    }

    if (write(tarFileDesc, buffer, in_bytes) != in_bytes)
    {
        status = false;
        break;
    }
    count += in_bytes;
}
// Cleanup buffer
delete[] buffer;

if ((0 > tarFileDesc) && (0 != close(tarFileDesc)))
    return false;   

if (0 != system("tar C /test -xvf test.tar"))
    return false;

if (0 != remove("test.tar"))
      return false;

Note I even tried just doing the open, close and remove. But I still see the handle being held by process.

Upvotes: 3

Views: 1073

Answers (4)

Callie J
Callie J

Reputation: 31316

This look suspicious:

if ((0 > tarFileDesc) && (0 != close(tarFileDesc)))
    return false;   

Looking towards the top of your code, you already do a check for 0 > tarFileDesc, and if true return false right at that point. So I'm thinking that this part of the check is redundant? i.e., should this simply read:

if (0 != close(tarFileDesc)))
    return false;

Upvotes: 0

Matt Joiner
Matt Joiner

Reputation: 118590

The issue lies in these lines:

if ((0 > tarFileDesc) && (0 != close(tarFileDesc)))
    return false;   

This will only close the file descriptor if tarFileDesc < 0. What you mean is if tarFileDesc >= 0 then close it as it's a valid file descriptor, so try changing this code to:

if ((0 > tarFileDesc) || (0 != close(tarFileDesc)))
    return false;

This way you return false if the file descriptor is invalid, otherwise you return false if you're unable to close it.

Upvotes: 5

Vtirum
Vtirum

Reputation: 41

Thanks all. Here is the snippet of the code:

tarFileDesc = _pSysCall->open("test.tar", O_CREAT | O_RDWR | O_APPEND, 0777);    
 if (0 > tarFileDesc)
  return false;

 ... some logging here

 // Write http stream to tar file, istr is an argument to my function     
 int read_buffer_size = 0;     
 buffer = new char[4096];     
 while (!istr.eof() && count < content_length)
 {      
    if ((content_length - count) >= 4096)
        read_buffer_size = 4096;
    else
        read_buffer_size = content_length - count;

    memset(buffer, 0, 4096);
    istr.read(buffer, read_buffer_size);
    std::streamsize in_bytes = istr.gcount();
    if (istr.fail() || istr.bad())
    {
        status = false;
        break;
    }

    if (write(tarFileDesc, buffer, in_bytes) != in_bytes)
    {
        status = false;
        break;
    }
    count += in_bytes;
}
// Cleanup buffer
delete[] buffer;

if ((0 > tarFileDesc) && (0 != close(tarFileDesc)))
    return false;   

if (0 != system("tar C /test -xvf test.tar"))
    return false;

if (0 != remove("test.tar"))
      return false;

Note I even tried just doing the open, close and remove. But I still see the handle being held by process.

Upvotes: 1

Paul Tomblin
Paul Tomblin

Reputation: 182802

You'll probably have to post some code. But here's a great trick for you - if you create a temporary file in Unix/Linux/Mac OS X, you can delete it IMMEDIATELY and you can still write to it, read it, etc, but as soon as you close it it will go away. It will also go away if some error kills your program before you get around to closing it.

Upvotes: 0

Related Questions