aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/start.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/app/start.go')
-rw-r--r--internal/app/start.go68
1 files changed, 59 insertions, 9 deletions
diff --git a/internal/app/start.go b/internal/app/start.go
index 02fad973..ed34b7c2 100644
--- a/internal/app/start.go
+++ b/internal/app/start.go
@@ -2,11 +2,16 @@ package app
import (
"errors"
+ "fmt"
"os"
"os/exec"
+ "path"
+ "path/filepath"
"strconv"
"time"
+ "git.ophivana.moe/cat/fortify/helper"
+ "git.ophivana.moe/cat/fortify/internal/shim"
"git.ophivana.moe/cat/fortify/internal/state"
"git.ophivana.moe/cat/fortify/internal/verbose"
)
@@ -14,6 +19,8 @@ import (
type (
// ProcessError encapsulates errors returned by starting *exec.Cmd
ProcessError BaseError
+ // ShimError encapsulates errors returned by shim.ServeConfig.
+ ShimError BaseError
)
// Start starts the fortified child
@@ -21,12 +28,30 @@ func (a *app) Start() error {
a.lock.Lock()
defer a.lock.Unlock()
+ // resolve exec paths
+ e := [2]string{helper.BubblewrapName}
+ if len(a.seal.command) > 0 {
+ e[1] = a.seal.command[0]
+ }
+ for i, n := range e {
+ if len(n) == 0 {
+ continue
+ }
+ if filepath.Base(n) == n {
+ if s, err := exec.LookPath(n); err == nil {
+ e[i] = s
+ } else {
+ return (*ProcessError)(wrapError(err, fmt.Sprintf("cannot find %q in PATH: %v", n, err)))
+ }
+ }
+ }
+
if err := a.seal.sys.commit(); err != nil {
return err
}
// select command builder
- var commandBuilder func() (args []string)
+ var commandBuilder func(shimEnv string) (args []string)
switch a.seal.launchOption {
case LaunchMethodSudo:
commandBuilder = a.commandBuilderSudo
@@ -37,15 +62,30 @@ func (a *app) Start() error {
}
// configure child process
- a.cmd = exec.Command(a.seal.toolPath, commandBuilder()...)
+ confSockPath := path.Join(a.seal.share, "shim")
+ a.cmd = exec.Command(a.seal.toolPath, commandBuilder(shim.EnvShim+"="+confSockPath)...)
a.cmd.Env = []string{}
a.cmd.Stdin = os.Stdin
a.cmd.Stdout = os.Stdout
a.cmd.Stderr = os.Stderr
a.cmd.Dir = a.seal.RunDirPath
- // start child process
- verbose.Println("starting main process:", a.cmd)
+ if wls, err := shim.ServeConfig(confSockPath, &shim.Payload{
+ Argv: a.seal.command,
+ Env: a.seal.env,
+ Exec: e,
+ Bwrap: a.seal.bwrap,
+ WL: a.seal.wlDone != nil,
+
+ Verbose: verbose.Get(),
+ }, a.seal.wl, a.seal.wlDone); err != nil {
+ return (*ShimError)(wrapError(err, "cannot listen on shim socket:", err))
+ } else {
+ a.wayland = wls
+ }
+
+ // start shim
+ verbose.Println("starting shim as target user:", a.cmd)
if err := a.cmd.Start(); err != nil {
return (*ProcessError)(wrapError(err, "cannot start process:", err))
}
@@ -62,11 +102,11 @@ func (a *app) Start() error {
}
// register process state
- var e = new(StateStoreError)
- e.Inner, e.DoErr = a.seal.store.Do(func(b state.Backend) {
- e.InnerErr = b.Save(&sd)
+ var err = new(StateStoreError)
+ err.Inner, err.DoErr = a.seal.store.Do(func(b state.Backend) {
+ err.InnerErr = b.Save(&sd)
})
- return e.equiv("cannot save process state:", e)
+ return err.equiv("cannot save process state:", e)
}
// StateStoreError is returned for a failed state save
@@ -146,6 +186,14 @@ func (a *app) Wait() (int, error) {
verbose.Println("process", strconv.Itoa(a.cmd.Process.Pid), "exited with exit code", r)
+ // close wayland connection
+ if a.wayland != nil {
+ close(a.seal.wlDone)
+ if err := a.wayland.Close(); err != nil {
+ fmt.Println("fortify: cannot close wayland connection:", err)
+ }
+ }
+
// update store and revert app setup transaction
e := new(StateStoreError)
e.Inner, e.DoErr = a.seal.store.Do(func(b state.Backend) {
@@ -187,7 +235,9 @@ func (a *app) Wait() (int, error) {
ct = append(ct, i)
}
}
- verbose.Println("will revert operations tagged", ct, "as no remaining launchers hold these enablements")
+ if len(ct) > 0 {
+ verbose.Println("will revert operations tagged", ct, "as no remaining launchers hold these enablements")
+ }
}
if err := a.seal.sys.revert(tags); err != nil {