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:
- mount partition /dev/sda1
open()
// creates an empty file Xwrite()
// write some bytes to itclose()
// close the fileprocessFile()
// Perform some operationremove()
// 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 str开发者_如何学编程eam 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.
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.
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.
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.
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;
精彩评论