How was it decided what utility should work with proc - by programmers of that utility?
No, by the developers of procfs
, the virtual filesystem that exports kernel info in the form of a filesystem, allowing normal POSIX system calls to operate on it.
ls
and ln
just make the same system calls they always do: In Unix everything is a file; that's the whole point, and why you can use ls -l
on /proc/PID
instead of needing a special tool like lsof
or ps
.
You can run anything you want on a /proc/PID/fd/*
file, e.g. if a program has its config file open, you can read that file with less
, edit it with emacs
or vim
, or create a compressed copy of it with gzip < /proc/.../3 > foo.gz
You might think this works just by following the symlink. But that's not actually true. The lstat
on that file reports it as a symlink, and readlink shows you a link target. But that link target is just text made up by the kernel: it can be something like /foo/bar (deleted)
for an FD that's still open on a file after it's been unlinked. But open()
on that /proc
path will still open the actual file. (Like most system calls, open
follows symlinks internally. For regular symlinks on regular filesystems, the link target does get treated like a normal pathname.)
There's no way to link that inode back into the filesystem (mostly for security reasons; it's possible using linkat(2)
on an FD opened with O_TMPFILE
which never had a pathname in the first place. https://stackoverflow.com/questions/4171713/relinking-an-anonymous-unlinked-but-open-file)
For your case, the right question to ask is "how it was decided which system-calls should do what on things under /proc/PID?"
AFAIK, no system calls on /proc
files can modify the process environment. i.e. the kernel information is exported read-only.
You'll have to use other hacks, like described in comments, to make system calls like dup2
inside the context of the process. e.g. using the ptrace
API. e.g. by using GDB or other debuggers which use ptrace
to do things inside the target process.
ptrace(2)
(you can easily try that with gdb). You can also "steal" its open fds via unix domain sockets +SCM_RIGHTS
. You can also create your own virtual fileystem in userland withfuse(4)
. Now you have all the needed pieces to demo something better than linux'sproc(5)
and explore ways to make it less broken. Good luck! – Sep 27 '19 at 19:57ln
to redirect them, when you can do it trivially withfdup2()
syscalls? In this case,exec 1>/tmp/somefile
will make1
be a symlink to/tmp/somefile
. There's already a well-supported mechanism that works on all POSIX-compliant systems; why would we want to add another one that's going to be incompatible with every other OS? – Charles Duffy Sep 28 '19 at 15:45dup2(newfd, 1)
orexec >foo
to redirect the output of another process. – Sep 28 '19 at 20:07dup2(open("/dev/null", 0), 1)
will a) make stdout unwritable, any subsequentwrite(2)
to it will fail withEBADF
, not succeed as when it's redirected via>/dev/null
in the shell and b) leak a file descriptor. – Sep 28 '19 at 21:14printf()
actually prints anything ;-) – Sep 28 '19 at 23:39daemon(3)
& co; they never close the standard fds, but redirect them to/from /dev/null. – Sep 28 '19 at 23:55dup2()
does just that (that's how shells implement redirections, etc). – Sep 28 '19 at 23:59