j10
j10

Reputation: 2271

Do multiple close calls for one fd in the same function matter?

I just want to know what is the behavior of having two consecutive close on a fd.

e.g.-

close(fd);
close(fd);

[fd is an int]

Upvotes: 24

Views: 21044

Answers (5)

Mario The Spoon
Mario The Spoon

Reputation: 4869

If the value of fd remains the same the second call will return an error that the fd is not valid (EBADF - as dasblinkenlight pointed out)

Think of doing somthing likg

if fd != -1 )
{
   close (fd );
   fd = -1;
}

Upvotes: 1

Guido
Guido

Reputation: 2634

Closing the same fd twice should be non-fatal as others have pointed out, but beware of code like this

close(fd);
/* ... */
newfd = open(....);
/* ... */
close(fd);

By the second close, you can't be sure if fd is actually the same as newfd! This would lead to crashes whenever you tried to use newfd.

So (if there's code between both close calls) it's not safe to do this. Always closefile descriptors exactly once. Always free buffers exactly once.

Upvotes: 7

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

The first call should return 0; the second call should return -1, and set errno to EBADF.

You should prevent the second call from happening by setting fd to a known bad number, e.g. a -1 immediately after the first call of close, and subsequently checking fd before making the second call (and not making the call if fd is -1):

close(fd);
fd = -1;
...
// More code
...
if (fd != -1) {
    close(fd)
    fd = -1;
}

This code pattern will help when you need to make calls to close from multiple places, but you are not sure if the file is open, or if it has been closed already. Passing -1 to close is harmless (you would get an EBADF, of course).

Upvotes: 24

Art
Art

Reputation: 20402

It should be harmless unless you're threaded or doing something between the two calls to close. Then you might end up closing an fd that something else in your program has opened.

The way threading is relevant is that libraries almost always do weird things behind your back. Libc will open files for looking up error messages or other locale dependent stuff, the resolver can open configuration files, etc. If you close a file descriptor and close it again, in a threaded environment you can easily end up in a situation where the file descriptor has been reused by a library and you close it behind its back.

Upvotes: 10

Anirudh Ramanathan
Anirudh Ramanathan

Reputation: 46768

Second call will fail with Errno: EBADF when because by then, fd is not an active file descriptor.

It should have no effect at all on execution. However, if any error number was set by the first close, that will be lost, so you shouldn't close the file-descriptor twice.

Upvotes: 4

Related Questions