aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlawl <github@dumbinter.net>2020-07-17 16:31:07 +0200
committerlawl <github@dumbinter.net>2020-07-17 16:31:07 +0200
commit26a497783101e6f14a01c0c992164998bcf6f676 (patch)
treef935d2c6982df2356edfbdb8c25ca9968ad51aa5
parent120b3fe00b84e6cb53389837baf0d1eec0ac84e9 (diff)
downloadnoisetorch-26a497783101e6f14a01c0c992164998bcf6f676.tar.gz
noisetorch-26a497783101e6f14a01c0c992164998bcf6f676.zip
remove rttime-rlimit as root during loading
-rw-r--r--main.go15
-rw-r--r--module.go27
-rw-r--r--rlimit.go68
3 files changed, 109 insertions, 1 deletions
diff --git a/main.go b/main.go
index 55c4141..819d843 100644
--- a/main.go
+++ b/main.go
@@ -1,11 +1,13 @@
package main
import (
+ "flag"
"image"
"io"
"io/ioutil"
"log"
"os"
+ "syscall"
"github.com/aarzilli/nucular/font"
@@ -28,6 +30,19 @@ type input struct {
func main() {
+ var pulsepid int
+ flag.IntVar(&pulsepid, "removerlimit", -1, "for internal use only")
+ flag.Parse()
+ if pulsepid > 0 {
+ const MaxUint = ^uint64(0)
+ new := syscall.Rlimit{Cur: MaxUint, Max: MaxUint}
+ err := setRlimit(pulsepid, &new)
+ if err != nil {
+ os.Exit(1)
+ }
+ os.Exit(0)
+ }
+
f, err := os.OpenFile("/tmp/noisetorch.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
log.Fatalf("error opening file: %v\n", err)
diff --git a/module.go b/module.go
index 1208a71..eb3ae99 100644
--- a/module.go
+++ b/module.go
@@ -59,6 +59,29 @@ func supressorState(c *pulseaudio.Client) int {
}
func loadSupressor(c *pulseaudio.Client, inp input, ui *uistate) error {
+
+ log.Printf("Querying pulse rlimit\n")
+
+ pid, err := getPulsePid()
+ if err != nil {
+ return err
+ }
+
+ lim, err := getRlimit(pid)
+ if err != nil {
+ return err
+ }
+ log.Printf("Rlimit: %+v. Trying to remove.\n", lim)
+ removeRlimitAsRoot(pid)
+ defer setRlimit(pid, &lim) // lowering RLIMIT doesn't require root
+
+ newLim, err := getRlimit(pid)
+ if err != nil {
+ return err
+ }
+ log.Printf("Rlimit: %+v\n", newLim)
+
+ time.Sleep(time.Millisecond * 1000) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast
log.Printf("Loading supressor\n")
idx, err := c.LoadModule("module-null-sink", "sink_name=nui_mic_denoised_out")
if err != nil {
@@ -108,6 +131,7 @@ func unloadSupressor(c *pulseaudio.Client) error {
log.Printf("Found null-sink at id [%d], sending unload command\n", m.Index)
c.UnloadModule(m.Index)
}
+ time.Sleep(time.Millisecond * 500) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast
log.Printf("Searching for ladspa-sink\n")
m, found, err = findModule(c, "module-ladspa-sink", "sink_name=nui_mic_raw_in sink_master=nui_mic_denoised_out")
if err != nil {
@@ -117,6 +141,7 @@ func unloadSupressor(c *pulseaudio.Client) error {
log.Printf("Found ladspa-sink at id [%d], sending unload command\n", m.Index)
c.UnloadModule(m.Index)
}
+ time.Sleep(time.Millisecond * 500) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast
log.Printf("Searching for loopback\n")
m, found, err = findModule(c, "module-loopback", "sink=nui_mic_raw_in")
if err != nil {
@@ -126,7 +151,7 @@ func unloadSupressor(c *pulseaudio.Client) error {
log.Printf("Found loopback at id [%d], sending unload command\n", m.Index)
c.UnloadModule(m.Index)
}
-
+ time.Sleep(time.Millisecond * 500) // pulseaudio gets SIGKILL'd because of RLIMITS if we send these too fast
log.Printf("Searching for remap-source\n")
m, found, err = findModule(c, "module-remap-source", "master=nui_mic_denoised_out.monitor source_name=nui_mic_remap")
if err != nil {
diff --git a/rlimit.go b/rlimit.go
new file mode 100644
index 0000000..1355965
--- /dev/null
+++ b/rlimit.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+const rlimitRTTime = 15
+
+func getPulsePid() (int, error) {
+ runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
+ pulsepidfile := filepath.Join(runtimeDir, "pulse/pid")
+ pidbuf, err := ioutil.ReadFile(pulsepidfile)
+ if err != nil {
+ return 0, err
+ }
+ pid, err := strconv.Atoi(strings.TrimSpace(string(pidbuf)))
+ if err != nil {
+ return 0, err
+ }
+ return pid, nil
+}
+
+func getRlimit(pid int) (syscall.Rlimit, error) {
+ var res syscall.Rlimit
+ err := pRlimit(pid, rlimitRTTime, nil, &res)
+ return res, err
+}
+
+func setRlimit(pid int, new *syscall.Rlimit) error {
+ var junk syscall.Rlimit
+ err := pRlimit(pid, rlimitRTTime, new, &junk)
+ return err
+}
+
+func removeRlimitAsRoot(pid int) {
+ self, err := os.Executable()
+ if err != nil {
+ log.Printf("Couldn't find path to own binary, trying PATH\n")
+ self = "noisetorch" //try PATH and hope for the best
+ }
+
+ cmd := exec.Command("pkexec", self, "-removerlimit", strconv.Itoa(pid))
+ log.Printf("Calling: %s\n", cmd.String())
+ err = cmd.Run()
+ if err != nil {
+ log.Printf("Couldn't remove rlimit as root: %v\n", err)
+ }
+}
+
+func pRlimit(pid int, limit uintptr, new *syscall.Rlimit, old *syscall.Rlimit) error {
+ _, _, errno := syscall.RawSyscall6(syscall.SYS_PRLIMIT64,
+ uintptr(pid),
+ limit,
+ uintptr(unsafe.Pointer(new)),
+ uintptr(unsafe.Pointer(old)), 0, 0)
+ if errno != 0 {
+ return errno
+ }
+ return nil
+}