37

You can use command lsof to get file descriptors for all running processes, but what I would like to do is to close some of those descriptors without being inside that process. This can be done on Windows, so you can easily unblock some application.

Is there any command or function for that?

Seb
  • 17,141
  • 7
  • 38
  • 27

5 Answers5

90

I don't know why you are trying to do this, but you should be able to attach to the process using gdb and then call close() on the fd. Example:

In one shell: cat

In another shell:

$pidof cat
7213

$gdb -p 7213

...
lots of output
...

(gdb)

Now you tell gdb to execute close(0):

(gdb) p close(0)

$1 = 0

(gdb) c

Continuing.

Program exited with code 01.
(gdb)

In the first shell I get this output:

cat: -: Bad file descriptor

cat: closing standard input: Bad file descriptor
crb
  • 8,132
  • 6
  • 37
  • 48
Andreas
  • 901
  • 5
  • 2
  • 3
    Better late than never, but this tip works perfectly when Eclipse decides to run out of fd's at the most badly timed moments. Cheers :) – Benjamin Apr 01 '10 at 09:05
  • 1
    @Seb, I think this should be the accepted answer - it actually gives an answer to the question. – Yonatan Feb 16 '15 at 01:14
  • What is the p command before the close(0) ? Does that print the returned value of the close syscall? – GL2014 Apr 27 '15 at 21:28
  • @GL2014 Yes, `p` in gdb prints an expression out, so gdb must evaluate the expression in order to print out its result. Hence `close(0)` is kind of called inadvertently, in that the actual purpose of `p` is not to cause side effects but just to determine values. – fuzzyTew Dec 20 '16 at 17:02
  • BTW, don't do this on your active X server while you are in X. Doesn't work very well. – Tim Jones Oct 06 '17 at 22:13
  • from https://incoherency.co.uk/blog/stories/closing-a-socket.html, seems shutdown is better than close? – SOFe Sep 30 '22 at 08:22
3

I don't think so but lsof gives you the PID of the process that has opened the file, so what you can do is entirely kill the process or at least send a signal to let it exit.

Fernando Miguélez
  • 11,196
  • 6
  • 36
  • 54
  • 1
    I have init (pid 1) with a dir open on an external hd somehow. I can't kill init, and want to cleanly unmount the drive before shutdown. – fuzzyTew Dec 20 '16 at 16:54
2

In Windows you can use a program to do it because someone wrote a program that inserts a device driver into the running kernel to do it. By the way it can be dangerous to do this, because after you close a handle that a broken application was using, the application doesn't know that the handle was closed, and when the application opens some other unrelated object it doesn't know that the same handle might now refer to some other unrelated object. You really want to kill the broken application as soon as possible.

In Linux surely you can use the same kind of technique. Write a program that inserts a module into the running kernel. Communicate with the module and tell it which handles to close. It will be equally dangerous to do so.

Windows programmer
  • 7,871
  • 1
  • 22
  • 23
2

I doubt it. File descriptors are process-local, stdout is 1 to all processes, yet they still reference unique streams of course.

Perhaps more detail would be useful, about the blocking problem you're trying to solve.

unwind
  • 391,730
  • 64
  • 469
  • 606
2

There is much less need to do this on Unix than on Windows.

On Windows, most programs tend to "lock" (actually deny sharing) the files they open, so they cannot be read/written/deleted by another program.

On Unix, most of the time this does not happen. File locking on Unix is mostly advisory, and will only block other locking attempts, not normal read/write/delete operations. You can even remove the current directory of a process.

About the only situation this comes up in normal usage in Unix is when trying to umount a filesystem (any reference at all to the mounted filesystem can block the umount).

CesarB
  • 43,947
  • 7
  • 63
  • 86