This commit is contained in:
Brad Fitzpatrick 2014-08-18 17:16:18 -07:00
commit 50f03763be
3 changed files with 77 additions and 8 deletions

View File

@ -1,4 +1,4 @@
// +build windows appengine // +build appengine
/* /*
Copyright 2012 The Camlistore Authors. Copyright 2012 The Camlistore Authors.
@ -19,13 +19,21 @@ limitations under the License.
package osutil package osutil
import ( import (
"errors"
"log" "log"
"runtime"
) )
// restartProcess returns an error if things couldn't be // SelfPath returns the path of the executable for the currently running
// process.
func SelfPath() (string, error) {
return "", errors.New("SelfPath not implemented on App Engine.")
}
// RestartProcess returns an error if things couldn't be
// restarted. On success, this function never returns // restarted. On success, this function never returns
// because the process becomes the new process. // because the process becomes the new process.
func RestartProcess() error { func RestartProcess() error {
log.Print("RestartProcess not implemented on windows") log.Print("RestartProcess not implemented on this platform.")
return nil return nil
} }

View File

@ -21,6 +21,7 @@ package osutil
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"runtime" "runtime"
"syscall" "syscall"
@ -29,7 +30,13 @@ import (
// if non-nil, osSelfPath is used from selfPath. // if non-nil, osSelfPath is used from selfPath.
var osSelfPath func() (string, error) var osSelfPath func() (string, error)
func selfPath() (string, error) { // TODO(mpl): document the symlink behaviour in SelfPath for the BSDs when
// I know for sure.
// SelfPath returns the path of the executable for the currently running
// process. At least on linux, the returned path is a symlink to the actual
// executable.
func SelfPath() (string, error) {
if f := osSelfPath; f != nil { if f := osSelfPath; f != nil {
return f() return f()
} }
@ -45,16 +52,16 @@ func selfPath() (string, error) {
// See https://codereview.appspot.com/6736069/ // See https://codereview.appspot.com/6736069/
return os.Args[0], nil return os.Args[0], nil
} }
return "", errors.New("No restart because selfPath() not implemented for " + runtime.GOOS) return "", errors.New("SelfPath not implemented for " + runtime.GOOS)
} }
// restartProcess returns an error if things couldn't be // RestartProcess returns an error if things couldn't be
// restarted. On success, this function never returns // restarted. On success, this function never returns
// because the process becomes the new process. // because the process becomes the new process.
func RestartProcess() error { func RestartProcess() error {
path, err := selfPath() path, err := SelfPath()
if err != nil { if err != nil {
return err return fmt.Errorf("RestartProcess failed: %v", err)
} }
return syscall.Exec(path, os.Args, os.Environ()) return syscall.Exec(path, os.Args, os.Environ())
} }

View File

@ -0,0 +1,54 @@
// +build windows
/*
Copyright 2014 The Camlistore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package osutil
import (
"log"
"syscall"
"unicode/utf16"
"unsafe"
)
// SelfPath returns the path of the executable for the currently running
// process.
func SelfPath() (string, error) {
kernel32, err := syscall.LoadDLL("kernel32.dll")
if err != nil {
return "", err
}
sysproc, err := kernel32.FindProc("GetModuleFileNameW")
if err != nil {
return "", err
}
b := make([]uint16, syscall.MAX_PATH)
r, _, err := sysproc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)))
n := uint32(r)
if n == 0 {
return "", err
}
return string(utf16.Decode(b[0:n])), nil
}
// RestartProcess returns an error if things couldn't be
// restarted. On success, this function never returns
// because the process becomes the new process.
func RestartProcess() error {
log.Print("RestartProcess not implemented on this platform.")
return nil
}