Created
November 17, 2010 13:57
-
-
Save nathankerr/703399 to your computer and use it in GitHub Desktop.
Directory monitoring and program execution in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.8 | |
*.6 | |
monitor |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include $(GOROOT)/src/Make.inc | |
TARG=monitor | |
GOFILES=\ | |
monitor.go\ | |
include $(GOROOT)/src/Make.cmd |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"exec" | |
"log" | |
"os" | |
"syscall" | |
"strings" | |
"time" | |
) | |
func main() { | |
var verbose *bool = new(bool) | |
*verbose = true | |
if len(os.Args) < 3 { | |
os.Stdout.Write([]uint8("Usage: ./monitor [-v] <dir> <cmd> <args>\n")) | |
os.Exit(1) | |
} | |
dir := os.Args[1] | |
cmd := os.Args[2] | |
args := os.Args[3:] | |
if *verbose { | |
log.Println("Verbose output enabled") | |
log.Println("dir:", dir) | |
log.Println("cmd:", cmd) | |
log.Println("args:", args) | |
} | |
fd, errno := syscall.InotifyInit() | |
if errno != 0 { | |
panic("inotify init") | |
} | |
if *verbose { | |
log.Println("inotify fd", fd) | |
} | |
for { | |
wd := watch(fd, dir) | |
if *verbose { | |
log.Println("Watch", wd, dir, "on inotify fd", fd) | |
} | |
detectEvent(fd) | |
if *verbose { | |
log.Println("Change detected") | |
} | |
stopWatching(fd, wd) | |
if *verbose { | |
log.Println("Stopped watching", wd) | |
} | |
log.Println("Running", cmd, "in", dir) | |
run(dir, cmd, args) | |
if *verbose { | |
log.Println("Run completed") | |
} | |
} | |
} | |
func watch(fd int, dir string) int { | |
wd, errno := syscall.InotifyAddWatch(fd, dir, syscall.IN_ATTRIB) | |
if errno != 0 { | |
panic("add watch") | |
} | |
return wd | |
} | |
func stopWatching(fd, wd int) { | |
syscall.InotifyRmWatch(fd, uint32(wd)) | |
detectEvent(fd) | |
} | |
func detectEvent(fd int) { | |
raw := make([]byte, 80) | |
_, errno := syscall.Read(fd, raw) | |
if errno != 0 { | |
panic("read inotify") | |
} | |
} | |
func run(dir, cmd string, args []string) { | |
time.Sleep(50) // Avoid running before the modified file has been fully modified. | |
c := exec.Command(cmd, strings.Join(args, " ")) | |
err := c.Run() | |
if err != nil { | |
//panic(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment