Goのos.RenameはLinuxではちゃんとrename(2)を使っているのか

それはまあ、そうだろうとは思うのだが、本当にそうか（すなわちアトミックにファイル操作するのか）を確認した。

```go:renamer.go
package main

import "os"

func main() {
	dest := os.Args[1]
	src := os.Args[2]

	if e := os.Rename(dest, src); e != nil {
		panic(e)
	}
}
```

こういうなんてことの無いプログラムをビルドし、手頃なLinux amd64のVMで `strace` を走らせる。

```shell-session
[vagrant@www tmp]$ strace ./renamer sample sample.1
execve("./renamer", ["./renamer", "sample", "sample.1"], [/* 22 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x4bcb30)       = 0
sched_getaffinity(0, 128, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) = 128
mmap(0xc000000000, 65536, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000
munmap(0xc000000000, 65536)             = 0
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff4f672d000
mmap(0xc208000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc208000000
mmap(0xc207ff0000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc207ff0000
mmap(0xc000000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff4f671d000
mmap(NULL, 1439992, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff4f65bd000
sigaltstack({ss_sp=0xc208002000, ss_flags=0, ss_size=32768}, NULL) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGHUP, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGHUP, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGQUIT, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGILL, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGTRAP, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGABRT, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGBUS, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGFPE, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGUSR1, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGSEGV, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
...
rt_sigaction(SIGRT_21, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_22, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_23, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_24, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_25, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_26, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_27, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_28, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_29, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_30, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_31, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigaction(SIGRT_32, {0x434000, ~[], SA_RESTORER|SA_STACK|SA_RESTART|SA_SIGINFO, 0x434070}, NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[], [], 8) = 0
clone(child_stack=0xc208030000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD) = 1222
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
futex(0x4b5960, FUTEX_WAKE, 1)          = 1
rt_sigprocmask(SIG_SETMASK, ~[], [], 8) = 0
clone(child_stack=0xc20802e000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD) = 1223
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
futex(0x4b5e18, FUTEX_WAIT, 0, NULL)    = 0
rename("sample", "sample.1")            = 0
futex(0x4b5960, FUTEX_WAKE, 1)          = 1
exit_group(0)                           = ?
+++ exited with 0 +++
```

`rename(2)` 呼んでました。こちらからは以上です。

## 追記

社のチャットで実際どう言うコードなのよ？という話をしたら大変勉強になりました...

- http://iiirc.org/snippets/514