5

What I have is process id and a file descriptor from that process. Is there any way apart from sendmsg to duplicate (or reopen) that process's file descriptor for use by another process in Linux?

Windows has DuplicateHandle for this purpose and I wonder if there is something similiar on Linux.

Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
Sergey
  • 403
  • 1
  • 5
  • 13
  • 1
    Short and only answer is: No. The reason is that a file descriptor is simply an index into a table, and as each table is unique per process you can not simply use a descriptor from one process in another. – Some programmer dude Apr 04 '13 at 11:04
  • I've updated my question. I want to reopen the file descriptor in another process. Something like what is described [here](http://stackoverflow.com/questions/2358684/can-i-share-a-file-descriptor-to-another-process-on-linux-or-are-they-local-to-t) but without sendmsg – Sergey Apr 04 '13 at 11:09
  • 1
    The answer is still no. If you want to duplicate a handle in another process, you have use the `sendmsg` method. Can't the other process just open the same file by itself instead of trying to get the descriptor from the first process? – Some programmer dude Apr 04 '13 at 11:11
  • the file can be unlinked or replaced, thus opening the "same" file by name does not guarantee that it will be opened or it will open the same file as far as I understand how things work in linux – Sergey Apr 04 '13 at 11:13
  • 2
    The ability to duplicate an arbitrary file descriptor from another process feels like a small security issue. Not surprising that it is possible in Windows. (Please note the dripping sarcasm on the word "small") – William Pursell Apr 04 '13 at 11:45

2 Answers2

6

As +vonbrand pointed out you can just use /proc/<pid>/fd/<fd>. But you can not just "write there" and it will not give any firworks.

It is a special symbolic link to the file that is opened in process with pid <pid> as file descriptor <fd>.

Just use it to open the exact same file in your process.

You do not have to worry about the original file beeing deleted or replaced because using this link will always give you the original file the process opened. Just try the following small piece of bash code:

#!/bin/bash
echo "test" >/tmp/file
ls -li /tmp/file
exec 3<> /tmp/file
rm /tmp/file
ls -lLi /proc/$$/fd/3
cat /proc/$$/fd/3

This creates a file /tmp/file containing the string test. Opens the file as file descriptor 3, removes it and after removing it can still cat its content by using /proc/self/fd/3. In linux a file is not finally deleted as long as any process still uses it.

So instead of getting and using the file descriptor of a process just open the file the file descriptor "points" to.

Of course you need the rights/permissions/privileges to do so. Which you have if you own both processes or if you are the root user.

EDIT: If not in bash you can also use /proc/self/... instead of /proc/$$/... to get info about the current process.

mariux
  • 2,807
  • 12
  • 21
  • This looks like exactly what I need. Will try it out. – Sergey Apr 04 '13 at 18:13
  • 1
    Just a note: while opening another fd works with, say, files, it creates problems with some magic device files where it is important to clone the fd as opposed to opening the device referenced by the original fd. – TheDiveO Mar 07 '19 at 15:06
1

If you have the proper permissions, file descriptor 5 of the process with PID 43512 is at /proc/43512/fd/5. I haven't ever messed around much with those (except to take a peek), so writing there might work fine or give spectacular fireworks.

vonbrand
  • 11,412
  • 8
  • 32
  • 52