Linux中的C ++代码留下的文件句柄

时间:2009-11-05 13:13:54

标签: c++ c linux

我正在尝试调试代码中的问题。我有一个持续运行的流程A,直到我要求它停止。

Inside A我做了以下事情:

  • mount partition / dev / sda1
  • open() //创建一个空文件X
  • write() //给它写一些字节
  • close() //关闭文件
  • processFile() //执行一些操作
  • remove() //删除文件
  • umount / dev / sda1

注意我在上面的每个操作之后测试是否成功或未前进。 当我lsof | grep A时,它显示进程A拥有的X的文件句柄。我也看到它有一个(已删除)。这可以防止我卸载分区。为什么会发生这种情况?如何解决这个问题呢?

编辑:谢谢大家。以下是代码片段:

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;

注意我甚至尝试过打开,关闭和删除。但我仍然看到进程持有的句柄。

4 个答案:

答案 0 :(得分:5)

问题在于以下几点:

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

这只会在tarFileDesc < 0时关闭文件描述符。你的意思是如果tarFileDesc >= 0然后关闭它,因为它是一个有效的文件描述符,所以尝试将此代码更改为:

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

这样,如果文件描述符无效,则返回false,否则如果无法关闭它,则返回false。

答案 1 :(得分:1)

谢谢大家。以下是代码片段:

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;

注意我甚至尝试过打开,关闭和删除。但我仍然看到进程持有的句柄。

答案 2 :(得分:0)

您可能需要发布一些代码。但是这里有一个很棒的技巧 - 如果你在Unix / Linux / Mac OS X中创建一个临时文件,你可以立即删除它,你仍然可以写入它,阅读它等,但是一旦你关闭它就会走开。如果在您关闭它之前某些错误会导致您的程序失效,它也会消失。

答案 3 :(得分:0)

这看起来很可疑:

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

查看代码的顶部,您已经检查了0 > tarFileDesc,如果为true,则返回false。所以我认为这部分检查是多余的?即,这应该是:

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