github.com/xyproto/orbiton/v2@v2.65.12-0.20240516144430-e10a419274ec/signals.go (about) 1 package main 2 3 import ( 4 "os" 5 "os/signal" 6 "path/filepath" 7 "syscall" 8 "time" 9 10 "github.com/xyproto/vt100" 11 ) 12 13 // SetUpSignalHandlers sets up a signal handler for when ctrl-c is pressed (SIGTERM), 14 // and also for when SIGUSR1 or SIGWINCH is received. 15 func (e *Editor) SetUpSignalHandlers(c *vt100.Canvas, tty *vt100.TTY, status *StatusBar) { 16 17 // For the drawing and the statusbar 18 resizeMut.Lock() 19 mut.Lock() 20 21 sigChan := make(chan os.Signal, 1) 22 23 // Send a SIGWINCH signal to the parent process if "OG" is set, 24 // to signal that "o is ready" to resize. The "og" GUI will then 25 // send SIGWINCH back, which will trigger FullResetRedraw in the case below. 26 if inVTEGUI { 27 // Clear any previous terminate or USR handlers 28 signal.Reset(syscall.SIGTERM, syscall.SIGUSR1, syscall.SIGWINCH) 29 // Set up notifications 30 signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGUSR1, syscall.SIGWINCH) 31 // Send a SIGWINCH signal to the "og" GUI, which is catched there 32 syscall.Kill(os.Getppid(), syscall.SIGWINCH) 33 } else { 34 // Start these in the background, since the "og" GUI isn't waiting 35 defer func() { 36 // Clear any previous terminate or USR handlers 37 signal.Reset(syscall.SIGTERM, syscall.SIGUSR1, syscall.SIGWINCH) 38 // Set up notifications 39 signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGUSR1, syscall.SIGWINCH) 40 }() 41 } 42 43 // For the drawing and the statusbar 44 resizeMut.Unlock() 45 mut.Unlock() 46 47 go func() { 48 for { 49 // Block until the signal is received 50 sig := <-sigChan 51 52 switch sig { 53 case syscall.SIGTERM: 54 // Save the file 55 mut.Lock() 56 e.UserSave(c, tty, status) 57 mut.Unlock() 58 case syscall.SIGUSR1: 59 // Unlock the file 60 if absFilename, err := filepath.Abs(e.filename); err != nil { 61 // Just unlock the non-absolute filename 62 fileLock.Unlock(e.filename) 63 } else { 64 fileLock.Unlock(absFilename) 65 } 66 fileLock.Save() 67 case syscall.SIGWINCH: 68 // Full redraw, like if Esc was pressed 69 drawLines := true 70 e.FullResetRedraw(c, status, drawLines) 71 // Try twice 72 time.Sleep(300 * time.Millisecond) 73 e.FullResetRedraw(c, status, drawLines) 74 } 75 } 76 }() 77 }