syscall_linux_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. "testing"
  10. "time"
  11. "golang.org/x/sys/unix"
  12. )
  13. func TestFchmodat(t *testing.T) {
  14. defer chtmpdir(t)()
  15. touch(t, "file1")
  16. os.Symlink("file1", "symlink1")
  17. err := unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, 0)
  18. if err != nil {
  19. t.Fatalf("Fchmodat: unexpected error: %v", err)
  20. }
  21. fi, err := os.Stat("file1")
  22. if err != nil {
  23. t.Fatal(err)
  24. }
  25. if fi.Mode() != 0444 {
  26. t.Errorf("Fchmodat: failed to change mode: expected %v, got %v", 0444, fi.Mode())
  27. }
  28. err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, unix.AT_SYMLINK_NOFOLLOW)
  29. if err != unix.EOPNOTSUPP {
  30. t.Fatalf("Fchmodat: unexpected error: %v, expected EOPNOTSUPP", err)
  31. }
  32. }
  33. func TestIoctlGetInt(t *testing.T) {
  34. f, err := os.Open("/dev/random")
  35. if err != nil {
  36. t.Fatalf("failed to open device: %v", err)
  37. }
  38. defer f.Close()
  39. v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT)
  40. if err != nil {
  41. t.Fatalf("failed to perform ioctl: %v", err)
  42. }
  43. t.Logf("%d bits of entropy available", v)
  44. }
  45. func TestPpoll(t *testing.T) {
  46. f, cleanup := mktmpfifo(t)
  47. defer cleanup()
  48. const timeout = 100 * time.Millisecond
  49. ok := make(chan bool, 1)
  50. go func() {
  51. select {
  52. case <-time.After(10 * timeout):
  53. t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
  54. case <-ok:
  55. }
  56. }()
  57. fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
  58. timeoutTs := unix.NsecToTimespec(int64(timeout))
  59. n, err := unix.Ppoll(fds, &timeoutTs, nil)
  60. ok <- true
  61. if err != nil {
  62. t.Errorf("Ppoll: unexpected error: %v", err)
  63. return
  64. }
  65. if n != 0 {
  66. t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
  67. return
  68. }
  69. }
  70. func TestTime(t *testing.T) {
  71. var ut unix.Time_t
  72. ut2, err := unix.Time(&ut)
  73. if err != nil {
  74. t.Fatalf("Time: %v", err)
  75. }
  76. if ut != ut2 {
  77. t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut)
  78. }
  79. var now time.Time
  80. for i := 0; i < 10; i++ {
  81. ut, err = unix.Time(nil)
  82. if err != nil {
  83. t.Fatalf("Time: %v", err)
  84. }
  85. now = time.Now()
  86. if int64(ut) == now.Unix() {
  87. return
  88. }
  89. }
  90. t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix())
  91. }
  92. func TestUtime(t *testing.T) {
  93. defer chtmpdir(t)()
  94. touch(t, "file1")
  95. buf := &unix.Utimbuf{
  96. Modtime: 12345,
  97. }
  98. err := unix.Utime("file1", buf)
  99. if err != nil {
  100. t.Fatalf("Utime: %v", err)
  101. }
  102. fi, err := os.Stat("file1")
  103. if err != nil {
  104. t.Fatal(err)
  105. }
  106. if fi.ModTime().Unix() != 12345 {
  107. t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix())
  108. }
  109. }
  110. func TestUtimesNanoAt(t *testing.T) {
  111. defer chtmpdir(t)()
  112. symlink := "symlink1"
  113. os.Remove(symlink)
  114. err := os.Symlink("nonexisting", symlink)
  115. if err != nil {
  116. t.Fatal(err)
  117. }
  118. ts := []unix.Timespec{
  119. {Sec: 1111, Nsec: 2222},
  120. {Sec: 3333, Nsec: 4444},
  121. }
  122. err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
  123. if err != nil {
  124. t.Fatalf("UtimesNanoAt: %v", err)
  125. }
  126. var st unix.Stat_t
  127. err = unix.Lstat(symlink, &st)
  128. if err != nil {
  129. t.Fatalf("Lstat: %v", err)
  130. }
  131. if st.Atim != ts[0] {
  132. t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
  133. }
  134. if st.Mtim != ts[1] {
  135. t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
  136. }
  137. }
  138. func TestGetrlimit(t *testing.T) {
  139. var rlim unix.Rlimit
  140. err := unix.Getrlimit(unix.RLIMIT_AS, &rlim)
  141. if err != nil {
  142. t.Fatalf("Getrlimit: %v", err)
  143. }
  144. }
  145. func TestSelect(t *testing.T) {
  146. _, err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
  147. if err != nil {
  148. t.Fatalf("Select: %v", err)
  149. }
  150. }
  151. func TestFstatat(t *testing.T) {
  152. defer chtmpdir(t)()
  153. touch(t, "file1")
  154. var st1 unix.Stat_t
  155. err := unix.Stat("file1", &st1)
  156. if err != nil {
  157. t.Fatalf("Stat: %v", err)
  158. }
  159. var st2 unix.Stat_t
  160. err = unix.Fstatat(unix.AT_FDCWD, "file1", &st2, 0)
  161. if err != nil {
  162. t.Fatalf("Fstatat: %v", err)
  163. }
  164. if st1 != st2 {
  165. t.Errorf("Fstatat: returned stat does not match Stat")
  166. }
  167. os.Symlink("file1", "symlink1")
  168. err = unix.Lstat("symlink1", &st1)
  169. if err != nil {
  170. t.Fatalf("Lstat: %v", err)
  171. }
  172. err = unix.Fstatat(unix.AT_FDCWD, "symlink1", &st2, unix.AT_SYMLINK_NOFOLLOW)
  173. if err != nil {
  174. t.Fatalf("Fstatat: %v", err)
  175. }
  176. if st1 != st2 {
  177. t.Errorf("Fstatat: returned stat does not match Lstat")
  178. }
  179. }
  180. // utilities taken from os/os_test.go
  181. func touch(t *testing.T, name string) {
  182. f, err := os.Create(name)
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. if err := f.Close(); err != nil {
  187. t.Fatal(err)
  188. }
  189. }
  190. // chtmpdir changes the working directory to a new temporary directory and
  191. // provides a cleanup function. Used when PWD is read-only.
  192. func chtmpdir(t *testing.T) func() {
  193. oldwd, err := os.Getwd()
  194. if err != nil {
  195. t.Fatalf("chtmpdir: %v", err)
  196. }
  197. d, err := ioutil.TempDir("", "test")
  198. if err != nil {
  199. t.Fatalf("chtmpdir: %v", err)
  200. }
  201. if err := os.Chdir(d); err != nil {
  202. t.Fatalf("chtmpdir: %v", err)
  203. }
  204. return func() {
  205. if err := os.Chdir(oldwd); err != nil {
  206. t.Fatalf("chtmpdir: %v", err)
  207. }
  208. os.RemoveAll(d)
  209. }
  210. }