Skip to content

Instantly share code, notes, and snippets.

@rjeczalik
Created December 7, 2015 13:57
Show Gist options
  • Save rjeczalik/eff8663929fc6191f2da to your computer and use it in GitHub Desktop.
Save rjeczalik/eff8663929fc6191f2da to your computer and use it in GitHub Desktop.
package main
import (
"errors"
"flag"
"fmt"
"log"
"log/syslog"
"os"
"os/exec"
"time"
)
// NOTE(rjeczalik): run with sudo
var kext = flag.String("kext", "DisableTurboBoost", "Kext module name to keep alive.")
var t = flag.Duration("t", 1*time.Minute, "Ticker interval.")
type InitError struct {
Err error
}
func (err *InitError) Error() string {
return fmt.Sprintf("init error: %v", err.Err)
}
func IsInit(err error) bool {
_, ok := err.(*InitError)
return ok
}
type Kext struct {
Module string
ErrorLog *log.Logger
ready bool
}
func (k *Kext) init() error {
if k.ready {
return nil
}
if k.Module == "" {
return &InitError{
Err: errors.New("module is empty"),
}
}
lookup := []string{
k.Module,
"/System/Library/Extensions/" + k.Module + ".kext",
}
module := ""
for _, path := range lookup {
k.logf("trying %q", path)
if _, err := os.Stat(path); err == nil {
module = path
break
}
}
if module == "" {
return &InitError{
Err: fmt.Errorf("unable to find kext for %q", k.Module),
}
}
k.Module = module
k.ready = true
return nil
}
func (k *Kext) Load() error {
return k.run("kextload")
}
func (k *Kext) Unload() error {
return k.run("kextunload")
}
func (k *Kext) run(cmd string) error {
if err := k.init(); err != nil {
k.logf("error init: %s", err)
return err
}
p, err := exec.Command(cmd, k.Module).CombinedOutput()
if err != nil {
k.logf("error running %s: %s (output %q)", cmd, err, p)
return err
}
return nil
}
func (k *Kext) logf(format string, args ...interface{}) {
if k.ErrorLog != nil {
k.ErrorLog.Printf(format, args...)
} else {
log.Printf(format, args...)
}
}
func main() {
flag.Parse()
logger, err := syslog.NewLogger(syslog.LOG_WARNING, log.LstdFlags)
if err != nil {
log.Fatalf("error obtaining syslog logger: %s", err)
}
k := &Kext{
Module: *kext,
ErrorLog: logger,
}
for range time.Tick(*t) {
logger.Printf("refreshing %q", k.Module)
if err := k.Unload(); IsInit(err) {
logger.Fatal(err)
}
if err := k.Load(); IsInit(err) {
logger.Fatal(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment