syscall_solaris.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. // Copyright 2009 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. // Solaris system calls.
  5. // This file is compiled as ordinary Go code,
  6. // but it is also input to mksyscall,
  7. // which parses the //sys lines and generates system call stubs.
  8. // Note that sometimes we use a lowercase //sys name and wrap
  9. // it in our own nicer implementation, either here or in
  10. // syscall_solaris.go or syscall_unix.go.
  11. package unix
  12. import "unsafe"
  13. type SockaddrDatalink struct {
  14. Family uint16
  15. Index uint16
  16. Type uint8
  17. Nlen uint8
  18. Alen uint8
  19. Slen uint8
  20. Data [244]int8
  21. raw RawSockaddrDatalink
  22. }
  23. func clen(n []byte) int {
  24. for i := 0; i < len(n); i++ {
  25. if n[i] == 0 {
  26. return i
  27. }
  28. }
  29. return len(n)
  30. }
  31. // ParseDirent parses up to max directory entries in buf,
  32. // appending the names to names. It returns the number
  33. // bytes consumed from buf, the number of entries added
  34. // to names, and the new names slice.
  35. func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
  36. origlen := len(buf)
  37. for max != 0 && len(buf) > 0 {
  38. dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
  39. if dirent.Reclen == 0 {
  40. buf = nil
  41. break
  42. }
  43. buf = buf[dirent.Reclen:]
  44. if dirent.Ino == 0 { // File absent in directory.
  45. continue
  46. }
  47. bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
  48. var name = string(bytes[0:clen(bytes[:])])
  49. if name == "." || name == ".." { // Useless names
  50. continue
  51. }
  52. max--
  53. count++
  54. names = append(names, name)
  55. }
  56. return origlen - len(buf), count, names
  57. }
  58. func pipe() (r uintptr, w uintptr, err uintptr)
  59. func Pipe(p []int) (err error) {
  60. if len(p) != 2 {
  61. return EINVAL
  62. }
  63. r0, w0, e1 := pipe()
  64. if e1 != 0 {
  65. err = Errno(e1)
  66. }
  67. p[0], p[1] = int(r0), int(w0)
  68. return
  69. }
  70. func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
  71. if sa.Port < 0 || sa.Port > 0xFFFF {
  72. return nil, 0, EINVAL
  73. }
  74. sa.raw.Family = AF_INET
  75. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  76. p[0] = byte(sa.Port >> 8)
  77. p[1] = byte(sa.Port)
  78. for i := 0; i < len(sa.Addr); i++ {
  79. sa.raw.Addr[i] = sa.Addr[i]
  80. }
  81. return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
  82. }
  83. func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
  84. if sa.Port < 0 || sa.Port > 0xFFFF {
  85. return nil, 0, EINVAL
  86. }
  87. sa.raw.Family = AF_INET6
  88. p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
  89. p[0] = byte(sa.Port >> 8)
  90. p[1] = byte(sa.Port)
  91. sa.raw.Scope_id = sa.ZoneId
  92. for i := 0; i < len(sa.Addr); i++ {
  93. sa.raw.Addr[i] = sa.Addr[i]
  94. }
  95. return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
  96. }
  97. func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
  98. name := sa.Name
  99. n := len(name)
  100. if n >= len(sa.raw.Path) {
  101. return nil, 0, EINVAL
  102. }
  103. sa.raw.Family = AF_UNIX
  104. for i := 0; i < n; i++ {
  105. sa.raw.Path[i] = int8(name[i])
  106. }
  107. // length is family (uint16), name, NUL.
  108. sl := _Socklen(2)
  109. if n > 0 {
  110. sl += _Socklen(n) + 1
  111. }
  112. if sa.raw.Path[0] == '@' {
  113. sa.raw.Path[0] = 0
  114. // Don't count trailing NUL for abstract address.
  115. sl--
  116. }
  117. return unsafe.Pointer(&sa.raw), sl, nil
  118. }
  119. func Getsockname(fd int) (sa Sockaddr, err error) {
  120. var rsa RawSockaddrAny
  121. var len _Socklen = SizeofSockaddrAny
  122. if err = getsockname(fd, &rsa, &len); err != nil {
  123. return
  124. }
  125. return anyToSockaddr(&rsa)
  126. }
  127. // The const provides a compile-time constant so clients
  128. // can adjust to whether there is a working Getwd and avoid
  129. // even linking this function into the binary. See ../os/getwd.go.
  130. const ImplementsGetwd = false
  131. func Getwd() (string, error) { return "", ENOTSUP }
  132. /*
  133. * Wrapped
  134. */
  135. //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
  136. //sysnb setgroups(ngid int, gid *_Gid_t) (err error)
  137. func Getgroups() (gids []int, err error) {
  138. n, err := getgroups(0, nil)
  139. if err != nil {
  140. return nil, err
  141. }
  142. if n == 0 {
  143. return nil, nil
  144. }
  145. // Sanity check group count. Max is 16 on BSD.
  146. if n < 0 || n > 1000 {
  147. return nil, EINVAL
  148. }
  149. a := make([]_Gid_t, n)
  150. n, err = getgroups(n, &a[0])
  151. if err != nil {
  152. return nil, err
  153. }
  154. gids = make([]int, n)
  155. for i, v := range a[0:n] {
  156. gids[i] = int(v)
  157. }
  158. return
  159. }
  160. func Setgroups(gids []int) (err error) {
  161. if len(gids) == 0 {
  162. return setgroups(0, nil)
  163. }
  164. a := make([]_Gid_t, len(gids))
  165. for i, v := range gids {
  166. a[i] = _Gid_t(v)
  167. }
  168. return setgroups(len(a), &a[0])
  169. }
  170. func ReadDirent(fd int, buf []byte) (n int, err error) {
  171. // Final argument is (basep *uintptr) and the syscall doesn't take nil.
  172. // TODO(rsc): Can we use a single global basep for all calls?
  173. return Getdents(fd, buf, new(uintptr))
  174. }
  175. // Wait status is 7 bits at bottom, either 0 (exited),
  176. // 0x7F (stopped), or a signal number that caused an exit.
  177. // The 0x80 bit is whether there was a core dump.
  178. // An extra number (exit code, signal causing a stop)
  179. // is in the high bits.
  180. type WaitStatus uint32
  181. const (
  182. mask = 0x7F
  183. core = 0x80
  184. shift = 8
  185. exited = 0
  186. stopped = 0x7F
  187. )
  188. func (w WaitStatus) Exited() bool { return w&mask == exited }
  189. func (w WaitStatus) ExitStatus() int {
  190. if w&mask != exited {
  191. return -1
  192. }
  193. return int(w >> shift)
  194. }
  195. func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
  196. func (w WaitStatus) Signal() Signal {
  197. sig := Signal(w & mask)
  198. if sig == stopped || sig == 0 {
  199. return -1
  200. }
  201. return sig
  202. }
  203. func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
  204. func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
  205. func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
  206. func (w WaitStatus) StopSignal() Signal {
  207. if !w.Stopped() {
  208. return -1
  209. }
  210. return Signal(w>>shift) & 0xFF
  211. }
  212. func (w WaitStatus) TrapCause() int { return -1 }
  213. func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
  214. func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
  215. r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
  216. if e1 != 0 {
  217. err = Errno(e1)
  218. }
  219. return int(r0), err
  220. }
  221. func gethostname() (name string, err uintptr)
  222. func Gethostname() (name string, err error) {
  223. name, e1 := gethostname()
  224. if e1 != 0 {
  225. err = Errno(e1)
  226. }
  227. return name, err
  228. }
  229. func UtimesNano(path string, ts []Timespec) (err error) {
  230. if len(ts) != 2 {
  231. return EINVAL
  232. }
  233. var tv [2]Timeval
  234. for i := 0; i < 2; i++ {
  235. tv[i].Sec = ts[i].Sec
  236. tv[i].Usec = ts[i].Nsec / 1000
  237. }
  238. return Utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
  239. }
  240. //sys fcntl(fd int, cmd int, arg int) (val int, err error)
  241. // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
  242. func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
  243. _, _, e1 := sysvicall6(procfcntl.Addr(), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
  244. if e1 != 0 {
  245. return e1
  246. }
  247. return nil
  248. }
  249. func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
  250. switch rsa.Addr.Family {
  251. case AF_UNIX:
  252. pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
  253. sa := new(SockaddrUnix)
  254. // Assume path ends at NUL.
  255. // This is not technically the Solaris semantics for
  256. // abstract Unix domain sockets -- they are supposed
  257. // to be uninterpreted fixed-size binary blobs -- but
  258. // everyone uses this convention.
  259. n := 0
  260. for n < len(pp.Path) && pp.Path[n] != 0 {
  261. n++
  262. }
  263. bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
  264. sa.Name = string(bytes)
  265. return sa, nil
  266. case AF_INET:
  267. pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
  268. sa := new(SockaddrInet4)
  269. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  270. sa.Port = int(p[0])<<8 + int(p[1])
  271. for i := 0; i < len(sa.Addr); i++ {
  272. sa.Addr[i] = pp.Addr[i]
  273. }
  274. return sa, nil
  275. case AF_INET6:
  276. pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
  277. sa := new(SockaddrInet6)
  278. p := (*[2]byte)(unsafe.Pointer(&pp.Port))
  279. sa.Port = int(p[0])<<8 + int(p[1])
  280. sa.ZoneId = pp.Scope_id
  281. for i := 0; i < len(sa.Addr); i++ {
  282. sa.Addr[i] = pp.Addr[i]
  283. }
  284. return sa, nil
  285. }
  286. return nil, EAFNOSUPPORT
  287. }
  288. //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libsocket.accept
  289. func Accept(fd int) (nfd int, sa Sockaddr, err error) {
  290. var rsa RawSockaddrAny
  291. var len _Socklen = SizeofSockaddrAny
  292. nfd, err = accept(fd, &rsa, &len)
  293. if err != nil {
  294. return
  295. }
  296. sa, err = anyToSockaddr(&rsa)
  297. if err != nil {
  298. Close(nfd)
  299. nfd = 0
  300. }
  301. return
  302. }
  303. func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
  304. var msg Msghdr
  305. var rsa RawSockaddrAny
  306. msg.Name = (*byte)(unsafe.Pointer(&rsa))
  307. msg.Namelen = uint32(SizeofSockaddrAny)
  308. var iov Iovec
  309. if len(p) > 0 {
  310. iov.Base = (*int8)(unsafe.Pointer(&p[0]))
  311. iov.SetLen(len(p))
  312. }
  313. var dummy int8
  314. if len(oob) > 0 {
  315. // receive at least one normal byte
  316. if len(p) == 0 {
  317. iov.Base = &dummy
  318. iov.SetLen(1)
  319. }
  320. msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
  321. }
  322. msg.Iov = &iov
  323. msg.Iovlen = 1
  324. if n, err = recvmsg(fd, &msg, flags); err != nil {
  325. return
  326. }
  327. oobn = int(msg.Accrightslen)
  328. // source address is only specified if the socket is unconnected
  329. if rsa.Addr.Family != AF_UNSPEC {
  330. from, err = anyToSockaddr(&rsa)
  331. }
  332. return
  333. }
  334. func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
  335. _, err = SendmsgN(fd, p, oob, to, flags)
  336. return
  337. }
  338. //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.sendmsg
  339. func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
  340. var ptr unsafe.Pointer
  341. var salen _Socklen
  342. if to != nil {
  343. ptr, salen, err = to.sockaddr()
  344. if err != nil {
  345. return 0, err
  346. }
  347. }
  348. var msg Msghdr
  349. msg.Name = (*byte)(unsafe.Pointer(ptr))
  350. msg.Namelen = uint32(salen)
  351. var iov Iovec
  352. if len(p) > 0 {
  353. iov.Base = (*int8)(unsafe.Pointer(&p[0]))
  354. iov.SetLen(len(p))
  355. }
  356. var dummy int8
  357. if len(oob) > 0 {
  358. // send at least one normal byte
  359. if len(p) == 0 {
  360. iov.Base = &dummy
  361. iov.SetLen(1)
  362. }
  363. msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
  364. }
  365. msg.Iov = &iov
  366. msg.Iovlen = 1
  367. if n, err = sendmsg(fd, &msg, flags); err != nil {
  368. return 0, err
  369. }
  370. if len(oob) > 0 && len(p) == 0 {
  371. n = 0
  372. }
  373. return n, nil
  374. }
  375. /*
  376. * Exposed directly
  377. */
  378. //sys Access(path string, mode uint32) (err error)
  379. //sys Adjtime(delta *Timeval, olddelta *Timeval) (err error)
  380. //sys Chdir(path string) (err error)
  381. //sys Chmod(path string, mode uint32) (err error)
  382. //sys Chown(path string, uid int, gid int) (err error)
  383. //sys Chroot(path string) (err error)
  384. //sys Close(fd int) (err error)
  385. //sys Dup(fd int) (nfd int, err error)
  386. //sys Exit(code int)
  387. //sys Fchdir(fd int) (err error)
  388. //sys Fchmod(fd int, mode uint32) (err error)
  389. //sys Fchown(fd int, uid int, gid int) (err error)
  390. //sys Fpathconf(fd int, name int) (val int, err error)
  391. //sys Fstat(fd int, stat *Stat_t) (err error)
  392. //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
  393. //sysnb Getgid() (gid int)
  394. //sysnb Getpid() (pid int)
  395. //sys Geteuid() (euid int)
  396. //sys Getegid() (egid int)
  397. //sys Getppid() (ppid int)
  398. //sys Getpriority(which int, who int) (n int, err error)
  399. //sysnb Getrlimit(which int, lim *Rlimit) (err error)
  400. //sysnb Gettimeofday(tv *Timeval) (err error)
  401. //sysnb Getuid() (uid int)
  402. //sys Kill(pid int, signum Signal) (err error)
  403. //sys Lchown(path string, uid int, gid int) (err error)
  404. //sys Link(path string, link string) (err error)
  405. //sys Listen(s int, backlog int) (err error) = libsocket.listen
  406. //sys Lstat(path string, stat *Stat_t) (err error)
  407. //sys Mkdir(path string, mode uint32) (err error)
  408. //sys Mknod(path string, mode uint32, dev int) (err error)
  409. //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
  410. //sys Open(path string, mode int, perm uint32) (fd int, err error)
  411. //sys Pathconf(path string, name int) (val int, err error)
  412. //sys Pread(fd int, p []byte, offset int64) (n int, err error)
  413. //sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
  414. //sys read(fd int, p []byte) (n int, err error)
  415. //sys Readlink(path string, buf []byte) (n int, err error)
  416. //sys Rename(from string, to string) (err error)
  417. //sys Rmdir(path string) (err error)
  418. //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek
  419. //sysnb Setegid(egid int) (err error)
  420. //sysnb Seteuid(euid int) (err error)
  421. //sysnb Setgid(gid int) (err error)
  422. //sysnb Setpgid(pid int, pgid int) (err error)
  423. //sys Setpriority(which int, who int, prio int) (err error)
  424. //sysnb Setregid(rgid int, egid int) (err error)
  425. //sysnb Setreuid(ruid int, euid int) (err error)
  426. //sysnb Setrlimit(which int, lim *Rlimit) (err error)
  427. //sysnb Setsid() (pid int, err error)
  428. //sysnb Setuid(uid int) (err error)
  429. //sys Shutdown(s int, how int) (err error) = libsocket.shutdown
  430. //sys Stat(path string, stat *Stat_t) (err error)
  431. //sys Symlink(path string, link string) (err error)
  432. //sys Sync() (err error)
  433. //sys Truncate(path string, length int64) (err error)
  434. //sys Fsync(fd int) (err error)
  435. //sys Ftruncate(fd int, length int64) (err error)
  436. //sys Umask(newmask int) (oldmask int)
  437. //sys Unlink(path string) (err error)
  438. //sys Utimes(path string, times *[2]Timeval) (err error)
  439. //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind
  440. //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.connect
  441. //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
  442. //sys munmap(addr uintptr, length uintptr) (err error)
  443. //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.sendto
  444. //sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.socket
  445. //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.socketpair
  446. //sys write(fd int, p []byte) (n int, err error)
  447. //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.getsockopt
  448. //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
  449. //sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname
  450. //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt
  451. //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom
  452. //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.recvmsg
  453. func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
  454. r0, _, e1 := sysvicall6(procread.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
  455. n = int(r0)
  456. if e1 != 0 {
  457. err = e1
  458. }
  459. return
  460. }
  461. func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
  462. r0, _, e1 := sysvicall6(procwrite.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
  463. n = int(r0)
  464. if e1 != 0 {
  465. err = e1
  466. }
  467. return
  468. }