Files
kvm/native_linux.go
luckfox-eng29 8fbd6bcf0d Add support for Luckfox PicoKVM
Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
2025-09-16 11:58:09 +08:00

154 lines
3.6 KiB
Go

//go:build linux
package kvm
import (
"fmt"
"os/exec"
"sync"
"syscall"
"github.com/rs/zerolog"
)
type nativeOutput struct {
mu *sync.Mutex
logger *zerolog.Event
}
func (w *nativeOutput) Write(p []byte) (n int, err error) {
w.mu.Lock()
defer w.mu.Unlock()
w.logger.Msg(string(p))
return len(p), nil
}
func startVideoBinary(binaryPath string) (*exec.Cmd, error) {
// Run the binary inthe background
cmd := exec.Command(binaryPath)
vidoeOutputLock := sync.Mutex{}
videoStdout := &nativeOutput{
mu: &vidoeOutputLock,
logger: videoLogger.Info().Str("pipe", "stdout"),
}
videoStderr := &nativeOutput{
mu: &vidoeOutputLock,
logger: videoLogger.Info().Str("pipe", "stderr"),
}
// Redirect stdout and stderr to the current process
cmd.Stdout = videoStdout
cmd.Stderr = videoStderr
// Set the process group ID so we can kill the process and its children when this process exits
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pdeathsig: syscall.SIGKILL,
}
// Start the command
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("failed to start binary: %w", err)
}
return cmd, nil
}
func startAudioBinary(binaryPath string) (*exec.Cmd, error) {
// Run the binary inthe background
cmd := exec.Command(binaryPath)
audioOutputLock := sync.Mutex{}
audioStdout := &nativeOutput{
mu: &audioOutputLock,
logger: audioLogger.Info().Str("pipe", "stdout"),
}
audioStderr := &nativeOutput{
mu: &audioOutputLock,
logger: audioLogger.Info().Str("pipe", "stderr"),
}
// Redirect stdout and stderr to the current process
cmd.Stdout = audioStdout
cmd.Stderr = audioStderr
// Set the process group ID so we can kill the process and its children when this process exits
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pdeathsig: syscall.SIGKILL,
}
// Start the command
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("failed to start binary: %w", err)
}
return cmd, nil
}
func startVpnBinary(binaryPath string) (*exec.Cmd, error) {
// Run the binary inthe background
cmd := exec.Command(binaryPath)
vpnOutputLock := sync.Mutex{}
vpnStdout := &nativeOutput{
mu: &vpnOutputLock,
logger: audioLogger.Info().Str("pipe", "stdout"),
}
vpnStderr := &nativeOutput{
mu: &vpnOutputLock,
logger: audioLogger.Info().Str("pipe", "stderr"),
}
// Redirect stdout and stderr to the current process
cmd.Stdout = vpnStdout
cmd.Stderr = vpnStderr
// Set the process group ID so we can kill the process and its children when this process exits
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pdeathsig: syscall.SIGKILL,
}
// Start the command
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("failed to start binary: %w", err)
}
return cmd, nil
}
func startDisplayBinary(binaryPath string) (*exec.Cmd, error) {
// Run the binary inthe background
cmd := exec.Command(binaryPath)
displayOutputLock := sync.Mutex{}
displayStdout := &nativeOutput{
mu: &displayOutputLock,
logger: displayLogger.Info().Str("pipe", "stdout"),
}
displayStderr := &nativeOutput{
mu: &displayOutputLock,
logger: displayLogger.Info().Str("pipe", "stderr"),
}
//// Redirect stdout and stderr to the current process
cmd.Stdout = displayStdout
cmd.Stderr = displayStderr
// Set the process group ID so we can kill the process and its children when this process exits
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pdeathsig: syscall.SIGKILL,
}
// Start the command
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("failed to start binary: %w", err)
}
return cmd, nil
}