Is it possible to redirect the parent stderr process to a socket file handle to a forked process?

I wrote to the daemon that during development its debugging information went to stderr (before it was completely "demonized"). Now the code is more mature, so stderr is redirected to /dev/null with a call to freopen(2) . For debugging purposes, I would really like to be able to connect to the server daemon, send a command and start magically starting the transfer of the stderr stream through the socket.

Is there a way (in a bifurcated process) to execute " dup(2) " as an operation on the stderr parent process in the file descriptor of the child socket? Linux-only solution acceptable.

There are large lines of code that print to stderr , which - for verification purposes - I would just not touch.

If dup2 can do what I ask, it will work: Redirect STDOUT and STDERR to a socket in C?

+2
source share
3 answers

As soon as the process has fork(2) ed, the child and parent processes do not share the file descriptor tables, so operations in one do not affect the others. The Linux system call clone(2) allows processes to share a file descriptor table using CLONE_FILES , and file system information (file system root, current working directory, umask) can be shared with CLONE_NS . Using clone(2) may be too big to re-record for your purposes - and because it's unusual, working with it can be annoying.

Another approach proposed by bmargulies is to create a part of the "error server" of the parent process, which tells clients for which the connect(2) port is to read the error information. If you adhere to TCP, it will work across networks, but will be open to everyone without any authentication or authorization code. If you use unix(7) sockets, you can use SCM_CREDENTIALS messages to verify the user, group, and pid of the connection process.

You can also create a new pipe(7) using the pipe(2) system call for each child before fork(2) and simply drop the filedescriptors if the child does not want to receive debugging information.

If you use a unix(7) socket to provide parent-child communication, you can use the SCM_RIGHTS message to send the filedescriptor file from one process to another - you can either pass the parent address a pipe(7) or socket(7) for reading or to send the parent element a pipe(7) or socket(7) for writing.

+1
source

Once the parent process forks, the child cannot forcibly change the status of anything in the parent process. It can be assumed that he contacts the parent and asks him to change where he writes his standard error output, but the child cannot force the parent to do this. In addition, if the parent interface closed the socket to the client after forking (which he usually used), then he cannot easily communicate with the client.

There are ways to transfer the file descriptor (socket) between processes, but I am confident that this is also a shared process. If you want to go down this route, this page will describe what to do and links to client and server programs to do the job. (You need to connect the AF_UNIX socket and use sendmsg() in the child recvmsg() and recvmsg() in the parent daemon. With this installation, the child daemon can organize the transfer of the client socket connection to the parent daemon, and the parent daemon then dup2() received the file descriptor 2 (standard error) and then close the original descriptor, after which standard error output will be sent to the client.

This requires caution when setting up and (as already mentioned) cooperation between the child process and the parent daemon process. I actually didn’t do this directly myself, so I’m not sure about the pitfalls in this process. I know that in fact it is pretty widely used, at least on Unix-like systems.

+2
source

What happened to dup2 ?

In the parent, socket and connect in the parent and pass the number to argv. Pass the file descriptor of the write side of the channel to the child in argv. Then close(2) and dup2(numberFromArgv, 2) ?

Or simply pass the port number of the error server to the child device (or reinstall it) and call it socket , connect and dup2 .

Think about it, I bet the main problem here is the "f". After calling freopen, the handle number is probably no longer "2". Call fileno to get the number, and then use dup2 to move the socket to that number.

+1
source

Source: https://habr.com/ru/post/1390563/


All Articles