【问题标题】:How to perform socket activation, passing a socket to a child proc as stdin/out, in golang?如何在golang中执行套接字激活,将套接字作为标准输入/输出传递给子进程?
【发布时间】:2021-11-09 20:48:08
【问题描述】:

我有一个通过 systemd 套接字激活运行的 C 程序。 Systemd 侦听端口,当 TCP 连接进入时,应用程序将启动,并将 stdin/stdout 完全像处理套接字(IE:setsockopt 等)。

我正在尝试使用 go 中的一个小型启动程序来模仿这种行为。它只会被告知要侦听的端口以及在建立连接时要运行的命令(没有其他高级 systemd 功能)。

我遇到的问题是我似乎无法将连接作为套接字传递到标准输入/输出。将 TCPConn 传递给 CmdStdinStdout 不起作用(C 程序在 setsockopts 上出错)。

            cmd := exec.Cmd{
                Path:   cmds,
                Args:   args,
                Stdin:  conn.,
                Stdout: conn,
                Stderr: os.Stderr,
            }
            err = cmd.Run()

我看到了一个 article,关于如何在 C 中使用 dup(2) 和 fork 做类似的事情,但是

  • 它正在分叉而不是执行另一个子进程
  • 我不完全理解套接字 fd 被复制而不是 client 接受的连接

有没有办法在 Golang 中做这样的事情?

附加信息

socket 文件大致如下

[Unit]
Description=soc activated program 

[Socket]
ListenStream=0.0.0.0:10101
Accept=yes

[Install]
WantedBy=sockets.target

对应的单元文件如下:

[Unit]
Description=My Program 

[Service]
Type=simple
ExecStart=/usr/bin/myprog -N
StandardInput=socket
StandardOutput=socket
StandardError=journal
TimeoutStopSec=5
KillMode=process

[Install]
WantedBy=multi-user.target

【问题讨论】:

    标签: linux go network-programming posix


    【解决方案1】:

    使用连接的file:

            f, err := conn.File()
            if err != nil { /* TODO handle error */}
            defer f.Close()
    
            cmd := exec.Cmd{
                Path:   cmds,
                Args:   args,
                Stdin:  f,
                Stdout: f,
                Stderr: os.Stderr,
            }
            err = cmd.Run()
    

    【讨论】:

      猜你喜欢
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 2017-03-18
      • 2013-03-02
      相关资源
      最近更新 更多