我可以将父进程的stderr重定向到分叉进程上的套接字文件描述符吗?

时间:2012-01-05 02:02:20

标签: c linux sockets stdio

我编写了一个守护进程,在开发过程中将其调试信息发送到stderr(在完全“守护进程”之前)。现在代码更加成熟,因此stderr已经被/dev/null调用重定向到freopen(2)。出于调试的目的,我真的希望能够连接到服务器守护程序,发送命令并让它神奇地开始通过套接字发送stderr流。

是否有办法(在分叉的过程中)对父进程dup(2)执行“stderr”操作到子套接字文件描述符?只接受Linux解决方案。

有大量代码打印到stderr用于验证目的 - 我宁愿不接触。

如果dup2可以做我要问的事情,那就可以了:Redirect STDOUT and STDERR to socket in C?

3 个答案:

答案 0 :(得分:2)

父进程分叉后,子进程无法强制更改父进程中任何内容的状态。可以想象,与父进行通信并请求它更改其写入标准错误输出的位置,但是子进程不能强制父进行。此外,如果父母在分叉之后将套接字关闭到客户端(通常是这样),那么它就无法与客户端轻松通信。

有一些方法可以在进程之间迁移(套接字)文件描述符,但我确信这也是一个合作进程。如果你想沿着那条路走下去,那么这个page会描述要做什么,并链接到客户端和服务器端程序来完成工作。 (您需要一个AF_UNIX套接字连接并使用子守护程序中的sendmsg()和父守护程序中的recvmsg()。通过该设置,子守护程序可以安排将客户端的套接字连接传递给父守护程序,然后父守护进程将dup2()接收到的文件描述符设置为2(标准错误),然后关闭接收到的原始描述符。此后,标准错误输出将转发给客户端。

这需要注意设置,以及(如前所述)子进程和父守护进程之间的协作。我自己并没有直接这样做,所以我不确定这个过程中的陷阱。我知道它实际上可以广泛使用,至少在类Unix系统上。

答案 1 :(得分:1)

dup2有什么问题?

在父级中,父级socketconnect并传递argv中的数字。将管道写入侧的文件描述符传递给argv中的子项。然后是close(2)dup2(numberFromArgv, 2)

或者,只需将错误服务器的端口号传递给子级(或将其硬连接),然后让其调用socketconnectdup2

来想一想,我敢打赌,这里的主要问题是'f'部分。在调用freopen之后,描述符号可能不再是'2'。调用fileno获取号码,然后使用dup2将套接字移动到该号码。

答案 2 :(得分:1)

进程有fork(2)后,子进程和父进程不共享文件描述符表,因此一个进程中的操作不会影响另一个进程。特定于Linux的clone(2)系统调用允许进程使用CLONE_FILES共享文件描述符表,并且可以与CLONE_NS共享文件系统信息(文件系统根目录,当前工作目录,umask)。使用clone(2)可能会为您的目的重写太大 - 而且因为它不同寻常,使用它可能会很烦人。

另一种方法,一个bmargulies suggests,是创建父进程的“错误服务器”部分,告诉客户端到connect(2)的哪个端口读取错误信息。如果您坚持使用TCP,它将通过网络工作,但对所有人开放,没有一些身份验证和授权代码。如果您使用unix(7)套接字,则可以使用SCM_CREDENTIALS消息来检查连接过程的用户,组和pid。

您还可以在pipe(7)之前使用每个子项的pipe(2)系统调用创建新的fork(2),如果孩子<,则只是浪费文件描述符< em>不想要调试信息。

如果使用unix(7)套接字为子进程提供父进程通信,则可以使用SCM_RIGHTS消息将文件描述符从一个进程发送到另一个进程 - 您可以让父进程发送{ {1}}或pipe(7)给孩子阅读或让孩子向父母发送socket(7)pipe(7)进行写作。