diff options
Diffstat (limited to 'internal/app/spx11.go')
| -rw-r--r-- | internal/app/spx11.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/app/spx11.go b/internal/app/spx11.go new file mode 100644 index 00000000..2e515cd4 --- /dev/null +++ b/internal/app/spx11.go @@ -0,0 +1,63 @@ +package app + +import ( + "errors" + "fmt" + "io/fs" + "strconv" + "strings" + + "hakurei.app/container" + "hakurei.app/hst" + "hakurei.app/system/acl" +) + +var absX11SocketDir = container.AbsFHSTmp.Append(".X11-unix") + +// spX11Op exports the X11 display server to the container. +type spX11Op struct { + // Value of $DISPLAY, stored during toSystem + Display string +} + +func (s *spX11Op) toSystem(state *outcomeStateSys, config *hst.Config) error { + if d, ok := state.k.lookupEnv("DISPLAY"); !ok { + return newWithMessage("DISPLAY is not set") + } else { + s.Display = d + } + + // the socket file at `/tmp/.X11-unix/X%d` is typically owned by the priv user + // and not accessible by the target user + var socketPath *container.Absolute + if len(s.Display) > 1 && s.Display[0] == ':' { // `:%d` + if n, err := strconv.Atoi(s.Display[1:]); err == nil && n >= 0 { + socketPath = absX11SocketDir.Append("X" + strconv.Itoa(n)) + } + } else if len(s.Display) > 5 && strings.HasPrefix(s.Display, "unix:") { // `unix:%s` + if a, err := container.NewAbs(s.Display[5:]); err == nil { + socketPath = a + } + } + if socketPath != nil { + if _, err := state.k.stat(socketPath.String()); err != nil { + if !errors.Is(err, fs.ErrNotExist) { + return &hst.AppError{Step: fmt.Sprintf("access X11 socket %q", socketPath), Err: err} + } + } else { + state.sys.UpdatePermType(hst.EX11, socketPath, acl.Read, acl.Write, acl.Execute) + if !config.Container.HostAbstract { + s.Display = "unix:" + socketPath.String() + } + } + } + + state.sys.ChangeHosts("#" + state.uid.String()) + return nil +} + +func (s *spX11Op) toContainer(state *outcomeStateParams) error { + state.env["DISPLAY"] = s.Display + state.params.Bind(absX11SocketDir, absX11SocketDir, 0) + return nil +} |
