syscall_linux_test.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build linux
  5. package unix_test
  6. import (
  7. "io/ioutil"
  8. "os"
  9. "runtime"
  10. "testing"
  11. "time"
  12. "golang.org/x/sys/unix"
  13. )
  14. func TestFchmodat(t *testing.T) {
  15. defer chtmpdir(t)()
  16. touch(t, "file1")
  17. os.Symlink("file1", "symlink1")
  18. err := unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, 0)
  19. if err != nil {
  20. t.Fatalf("Fchmodat: unexpected error: %v", err)
  21. }
  22. fi, err := os.Stat("file1")
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. if fi.Mode() != 0444 {
  27. t.Errorf("Fchmodat: failed to change mode: expected %v, got %v", 0444, fi.Mode())
  28. }
  29. err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, unix.AT_SYMLINK_NOFOLLOW)
  30. if err != unix.EOPNOTSUPP {
  31. t.Fatalf("Fchmodat: unexpected error: %v, expected EOPNOTSUPP", err)
  32. }
  33. }
  34. func TestIoctlGetInt(t *testing.T) {
  35. f, err := os.Open("/dev/random")
  36. if err != nil {
  37. t.Fatalf("failed to open device: %v", err)
  38. }
  39. defer f.Close()
  40. v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT)
  41. if err != nil {
  42. t.Fatalf("failed to perform ioctl: %v", err)
  43. }
  44. t.Logf("%d bits of entropy available", v)
  45. }
  46. func TestPpoll(t *testing.T) {
  47. f, cleanup := mktmpfifo(t)
  48. defer cleanup()
  49. const timeout = 100 * time.Millisecond
  50. ok := make(chan bool, 1)
  51. go func() {
  52. select {
  53. case <-time.After(10 * timeout):
  54. t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
  55. case <-ok:
  56. }
  57. }()
  58. fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
  59. timeoutTs := unix.NsecToTimespec(int64(timeout))
  60. n, err := unix.Ppoll(fds, &timeoutTs, nil)
  61. ok <- true
  62. if err != nil {
  63. t.Errorf("Ppoll: unexpected error: %v", err)
  64. return
  65. }
  66. if n != 0 {
  67. t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
  68. return
  69. }
  70. }
  71. func TestTime(t *testing.T) {
  72. var ut unix.Time_t
  73. ut2, err := unix.Time(&ut)
  74. if err != nil {
  75. t.Fatalf("Time: %v", err)
  76. }
  77. if ut != ut2 {
  78. t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut)
  79. }
  80. var now time.Time
  81. for i := 0; i < 10; i++ {
  82. ut, err = unix.Time(nil)
  83. if err != nil {
  84. t.Fatalf("Time: %v", err)
  85. }
  86. now = time.Now()
  87. if int64(ut) == now.Unix() {
  88. return
  89. }
  90. }
  91. t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix())
  92. }
  93. func TestUtime(t *testing.T) {
  94. defer chtmpdir(t)()
  95. touch(t, "file1")
  96. buf := &unix.Utimbuf{
  97. Modtime: 12345,
  98. }
  99. err := unix.Utime("file1", buf)
  100. if err != nil {
  101. t.Fatalf("Utime: %v", err)
  102. }
  103. fi, err := os.Stat("file1")
  104. if err != nil {
  105. t.Fatal(err)
  106. }
  107. if fi.ModTime().Unix() != 12345 {
  108. t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix())
  109. }
  110. }
  111. func TestUtimesNanoAt(t *testing.T) {
  112. defer chtmpdir(t)()
  113. symlink := "symlink1"
  114. os.Remove(symlink)
  115. err := os.Symlink("nonexisting", symlink)
  116. if err != nil {
  117. t.Fatal(err)
  118. }
  119. ts := []unix.Timespec{
  120. {Sec: 1111, Nsec: 2222},
  121. {Sec: 3333, Nsec: 4444},
  122. }
  123. err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
  124. if err != nil {
  125. t.Fatalf("UtimesNanoAt: %v", err)
  126. }
  127. var st unix.Stat_t
  128. err = unix.Lstat(symlink, &st)
  129. if err != nil {
  130. t.Fatalf("Lstat: %v", err)
  131. }
  132. if st.Atim != ts[0] {
  133. t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
  134. }
  135. if st.Mtim != ts[1] {
  136. t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
  137. }
  138. }
  139. func TestGetrlimit(t *testing.T) {
  140. var rlim unix.Rlimit
  141. err := unix.Getrlimit(unix.RLIMIT_AS, &rlim)
  142. if err != nil {
  143. t.Fatalf("Getrlimit: %v", err)
  144. }
  145. }
  146. func TestSelect(t *testing.T) {
  147. _, err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
  148. if err != nil {
  149. t.Fatalf("Select: %v", err)
  150. }
  151. dur := 150 * time.Millisecond
  152. tv := unix.NsecToTimeval(int64(dur))
  153. start := time.Now()
  154. _, err = unix.Select(0, nil, nil, nil, &tv)
  155. took := time.Since(start)
  156. if err != nil {
  157. t.Fatalf("Select: %v", err)
  158. }
  159. if took < dur {
  160. t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
  161. }
  162. }
  163. func TestPselect(t *testing.T) {
  164. _, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 0, Nsec: 0}, nil)
  165. if err != nil {
  166. t.Fatalf("Pselect: %v", err)
  167. }
  168. dur := 2500 * time.Microsecond
  169. ts := unix.NsecToTimespec(int64(dur))
  170. start := time.Now()
  171. _, err = unix.Pselect(0, nil, nil, nil, &ts, nil)
  172. took := time.Since(start)
  173. if err != nil {
  174. t.Fatalf("Pselect: %v", err)
  175. }
  176. if took < dur {
  177. t.Errorf("Pselect: timeout should have been at least %v, got %v", dur, took)
  178. }
  179. }
  180. func TestFstatat(t *testing.T) {
  181. defer chtmpdir(t)()
  182. touch(t, "file1")
  183. var st1 unix.Stat_t
  184. err := unix.Stat("file1", &st1)
  185. if err != nil {
  186. t.Fatalf("Stat: %v", err)
  187. }
  188. var st2 unix.Stat_t
  189. err = unix.Fstatat(unix.AT_FDCWD, "file1", &st2, 0)
  190. if err != nil {
  191. t.Fatalf("Fstatat: %v", err)
  192. }
  193. if st1 != st2 {
  194. t.Errorf("Fstatat: returned stat does not match Stat")
  195. }
  196. os.Symlink("file1", "symlink1")
  197. err = unix.Lstat("symlink1", &st1)
  198. if err != nil {
  199. t.Fatalf("Lstat: %v", err)
  200. }
  201. err = unix.Fstatat(unix.AT_FDCWD, "symlink1", &st2, unix.AT_SYMLINK_NOFOLLOW)
  202. if err != nil {
  203. t.Fatalf("Fstatat: %v", err)
  204. }
  205. if st1 != st2 {
  206. t.Errorf("Fstatat: returned stat does not match Lstat")
  207. }
  208. }
  209. func TestSchedSetaffinity(t *testing.T) {
  210. runtime.LockOSThread()
  211. defer runtime.UnlockOSThread()
  212. var oldMask unix.CPUSet
  213. err := unix.SchedGetaffinity(0, &oldMask)
  214. if err != nil {
  215. t.Fatalf("SchedGetaffinity: %v", err)
  216. }
  217. var newMask unix.CPUSet
  218. newMask.Zero()
  219. if newMask.Count() != 0 {
  220. t.Errorf("CpuZero: didn't zero CPU set: %v", newMask)
  221. }
  222. cpu := 1
  223. newMask.Set(cpu)
  224. if newMask.Count() != 1 || !newMask.IsSet(cpu) {
  225. t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
  226. }
  227. cpu = 5
  228. newMask.Set(cpu)
  229. if newMask.Count() != 2 || !newMask.IsSet(cpu) {
  230. t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
  231. }
  232. newMask.Clear(cpu)
  233. if newMask.Count() != 1 || newMask.IsSet(cpu) {
  234. t.Errorf("CpuClr: didn't clear CPU %d in set: %v", cpu, newMask)
  235. }
  236. err = unix.SchedSetaffinity(0, &newMask)
  237. if err != nil {
  238. t.Fatalf("SchedSetaffinity: %v", err)
  239. }
  240. var gotMask unix.CPUSet
  241. err = unix.SchedGetaffinity(0, &gotMask)
  242. if err != nil {
  243. t.Fatalf("SchedGetaffinity: %v", err)
  244. }
  245. if gotMask != newMask {
  246. t.Errorf("SchedSetaffinity: returned affinity mask does not match set affinity mask")
  247. }
  248. // Restore old mask so it doesn't affect successive tests
  249. err = unix.SchedSetaffinity(0, &oldMask)
  250. if err != nil {
  251. t.Fatalf("SchedSetaffinity: %v", err)
  252. }
  253. }
  254. // utilities taken from os/os_test.go
  255. func touch(t *testing.T, name string) {
  256. f, err := os.Create(name)
  257. if err != nil {
  258. t.Fatal(err)
  259. }
  260. if err := f.Close(); err != nil {
  261. t.Fatal(err)
  262. }
  263. }
  264. // chtmpdir changes the working directory to a new temporary directory and
  265. // provides a cleanup function. Used when PWD is read-only.
  266. func chtmpdir(t *testing.T) func() {
  267. oldwd, err := os.Getwd()
  268. if err != nil {
  269. t.Fatalf("chtmpdir: %v", err)
  270. }
  271. d, err := ioutil.TempDir("", "test")
  272. if err != nil {
  273. t.Fatalf("chtmpdir: %v", err)
  274. }
  275. if err := os.Chdir(d); err != nil {
  276. t.Fatalf("chtmpdir: %v", err)
  277. }
  278. return func() {
  279. if err := os.Chdir(oldwd); err != nil {
  280. t.Fatalf("chtmpdir: %v", err)
  281. }
  282. os.RemoveAll(d)
  283. }
  284. }