-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go
92 lines (75 loc) · 1.76 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// SPDX-License-Identifier: BSD-2-Clause
// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
package main
import (
"io"
"log"
"os"
"syscall"
"golang.org/x/sys/unix"
)
func main() {
if len(os.Args) != 2 {
log.Fatalf("Usage: %s <socket-path>", os.Args[0])
}
socketPath := os.Args[1]
conn, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0)
if err != nil {
log.Fatalf("socket: %v", err)
}
addr := &unix.SockaddrUnix{Name: socketPath}
if err := unix.Connect(conn, addr); err != nil {
log.Fatalf("connect: %v", err)
}
message, err := io.ReadAll(os.Stdin)
if err != nil {
log.Fatalf("ReadAll: %v", err)
}
_, err = unix.Write(conn, message)
if err != nil {
log.Fatalf("write: %v", err)
}
if err := unix.Shutdown(conn, unix.SHUT_WR); err != nil {
log.Fatalf("shutdown: %v", err)
}
oob := make([]byte, 1024)
buf := make([]byte, 1)
n, oobn, _, _, err := unix.Recvmsg(conn, buf, oob, 0)
if err != nil || n == 0 {
log.Fatalf("recvmsg: %v", err)
}
scms, err := unix.ParseSocketControlMessage(oob[:oobn])
if err != nil {
log.Fatalf("ParseSocketControlMessage: %v", err)
}
var memfd int = -1
for _, scm := range scms {
fds, err := unix.ParseUnixRights(&scm)
if err != nil {
log.Fatalf("ParseUnixRights: %v", err)
}
if len(fds) > 0 {
memfd = fds[0]
break
}
}
if memfd < 0 {
log.Fatal("invalid memfd")
}
var stat unix.Stat_t
if err := unix.Fstat(memfd, &stat); err != nil {
log.Fatalf("fstat: %v", err)
}
size := int(stat.Size)
data, err := unix.Mmap(memfd, 0, size, syscall.PROT_READ, syscall.MAP_SHARED)
if err != nil {
log.Fatalf("mmap: %v", err)
}
_, err = os.Stdout.Write(data)
if err != nil {
log.Fatalf("write: %v", err)
}
unix.Munmap(data)
unix.Close(memfd)
unix.Close(conn)
}