90 lines
1.4 KiB
Go
90 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"strconv"
|
|
)
|
|
|
|
func copy(src, dst string) error {
|
|
fi, err := os.Stat(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
inmode := fi.Mode()
|
|
|
|
in, err := os.Open(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer in.Close()
|
|
|
|
out, err := os.Create(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer out.Close()
|
|
|
|
copied, err := io.Copy(out, in)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if copied < fi.Size() {
|
|
return errors.New("copy not completed")
|
|
}
|
|
if err := out.Sync(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := out.Chmod(inmode); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
args := os.Args
|
|
// args[1] : 나를 시작한 pid. pid가 종료될 때 까지 기다림
|
|
// args[2] : target 폴더
|
|
// args[3:] : 다시 시작할 때 넘겨줄 arguments(프로세스 이름 포함)
|
|
fmt.Println(args)
|
|
|
|
pid, err := strconv.Atoi(args[1])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
proc, err := os.FindProcess(pid)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
proc.Wait()
|
|
|
|
selfext, _ := os.Executable()
|
|
|
|
entries, _ := os.ReadDir(args[2])
|
|
for _, ent := range entries {
|
|
if ent.Name() == selfext {
|
|
continue
|
|
}
|
|
|
|
if ent.IsDir() {
|
|
if err := os.MkdirAll(ent.Name(), os.ModePerm); err != nil {
|
|
panic(err)
|
|
}
|
|
} else {
|
|
if err := copy(path.Join(args[2], ent.Name()), ent.Name()); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
os.RemoveAll(args[2])
|
|
cmd := exec.Command(args[3], args[4:]...)
|
|
cmd.Start()
|
|
}
|