我编写了一个守护进程,在开发过程中将其调试信息发送到stderr(在完全“守护进程”之前)。现在代码更加成熟,因此stderr已经被/dev/null
调用重定向到freopen(2)
。出于调试的目的,我真的希望能够连接到服务器守护程序,发送命令并让它神奇地开始通过套接字发送stderr
流。
是否有办法(在分叉的过程中)对父进程的dup(2)
执行“stderr
”操作到子套接字文件描述符?只接受Linux解决方案。
有大量代码打印到stderr
,用于验证目的 - 我宁愿不接触。
如果dup2
可以做我要问的事情,那就可以了:Redirect STDOUT and STDERR to socket in C?
答案 0 :(得分:2)
父进程分叉后,子进程无法强制更改父进程中任何内容的状态。可以想象,与父进行通信并请求它更改其写入标准错误输出的位置,但是子进程不能强制父进行。此外,如果父母在分叉之后将套接字关闭到客户端(通常是这样),那么它就无法与客户端轻松通信。
有一些方法可以在进程之间迁移(套接字)文件描述符,但我确信这也是一个合作进程。如果你想沿着那条路走下去,那么这个page会描述要做什么,并链接到客户端和服务器端程序来完成工作。 (您需要一个AF_UNIX套接字连接并使用子守护程序中的sendmsg()
和父守护程序中的recvmsg()
。通过该设置,子守护程序可以安排将客户端的套接字连接传递给父守护程序,然后父守护进程将dup2()
接收到的文件描述符设置为2(标准错误),然后关闭接收到的原始描述符。此后,标准错误输出将转发给客户端。
这需要注意设置,以及(如前所述)子进程和父守护进程之间的协作。我自己并没有直接这样做,所以我不确定这个过程中的陷阱。我知道它实际上可以广泛使用,至少在类Unix系统上。
答案 1 :(得分:1)
dup2
有什么问题?
在父级中,父级socket
和connect
并传递argv中的数字。将管道写入侧的文件描述符传递给argv中的子项。然后是close(2)
和dup2(numberFromArgv, 2)
?
或者,只需将错误服务器的端口号传递给子级(或将其硬连接),然后让其调用socket
,connect
和dup2
。
来想一想,我敢打赌,这里的主要问题是'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)
进行写作。