Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File handle left behind by C++ code in Linux

Tags:

c++

c

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:

  • mount partition /dev/sda1
  • open() // creates an empty file X
  • write() // write some bytes to it
  • close() // close the file
  • processFile() // Perform some operation
  • remove() // remove file
  • umount /dev/sda1

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.

like image 514
Vtirum Avatar asked Jun 19 '26 08:06

Vtirum


2 Answers

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.

like image 151
Matt Joiner Avatar answered Jun 20 '26 22:06

Matt Joiner


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.

like image 26
Vtirum Avatar answered Jun 20 '26 22:06

Vtirum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!