| 75 | } |
| 76 | |
| 77 | func openFile(name string, withSudo bool) (wrappedFile, error) { |
| 78 | var err error |
| 79 | var writeCloser io.WriteCloser |
| 80 | var screenb bool |
| 81 | var cmd *exec.Cmd |
| 82 | var sigChan chan os.Signal |
| 83 | |
| 84 | if withSudo { |
| 85 | conv := "notrunc" |
| 86 | // TODO: both platforms do not support dd with conv=fsync yet |
| 87 | if !(runtime.GOOS == "illumos" || runtime.GOOS == "netbsd") { |
| 88 | conv += ",fsync" |
| 89 | } |
| 90 | |
| 91 | cmd = exec.Command(config.GlobalSettings["sucmd"].(string), "dd", "bs=4k", "conv="+conv, "of="+name) |
| 92 | writeCloser, err = cmd.StdinPipe() |
| 93 | if err != nil { |
| 94 | return wrappedFile{}, err |
| 95 | } |
| 96 | |
| 97 | sigChan = make(chan os.Signal, 1) |
| 98 | signal.Reset(os.Interrupt) |
| 99 | signal.Notify(sigChan, os.Interrupt) |
| 100 | |
| 101 | screenb = screen.TempFini() |
| 102 | // need to start the process now, otherwise when we flush the file |
| 103 | // contents to its stdin it might hang because the kernel's pipe size |
| 104 | // is too small to handle the full file contents all at once |
| 105 | err = cmd.Start() |
| 106 | if err != nil { |
| 107 | screen.TempStart(screenb) |
| 108 | |
| 109 | signal.Notify(util.Sigterm, os.Interrupt) |
| 110 | signal.Stop(sigChan) |
| 111 | |
| 112 | return wrappedFile{}, err |
| 113 | } |
| 114 | } else { |
| 115 | writeCloser, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE, util.FileMode) |
| 116 | if err != nil { |
| 117 | return wrappedFile{}, err |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | return wrappedFile{name, writeCloser, withSudo, screenb, cmd, sigChan}, nil |
| 122 | } |
| 123 | |
| 124 | func (wf wrappedFile) Truncate() error { |
| 125 | if wf.withSudo { |