Kai Backman | 382a19c | 2009-08-18 19:20:33 -0700 | [diff] [blame] | 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 | |
| 5 | package syscall |
| 6 | |
Shenghou Ma | f848595 | 2012-10-08 00:13:28 +0800 | [diff] [blame] | 7 | import "unsafe" |
| 8 | |
Dave Cheney | 532bc5f | 2015-03-09 07:03:00 +1100 | [diff] [blame] | 9 | const _SYS_dup = SYS_DUP2 |
| 10 | |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 11 | func Getpagesize() int { return 4096 } |
Kai Backman | 116beb2 | 2009-10-06 16:39:38 -0700 | [diff] [blame] | 12 | |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 13 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } |
Kai Backman | 116beb2 | 2009-10-06 16:39:38 -0700 | [diff] [blame] | 14 | |
Kai Backman | 382a19c | 2009-08-18 19:20:33 -0700 | [diff] [blame] | 15 | func NsecToTimespec(nsec int64) (ts Timespec) { |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 16 | ts.Sec = int32(nsec / 1e9) |
| 17 | ts.Nsec = int32(nsec % 1e9) |
| 18 | return |
Kai Backman | 382a19c | 2009-08-18 19:20:33 -0700 | [diff] [blame] | 19 | } |
| 20 | |
Kai Backman | 382a19c | 2009-08-18 19:20:33 -0700 | [diff] [blame] | 21 | func NsecToTimeval(nsec int64) (tv Timeval) { |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 22 | nsec += 999 // round up to microsecond |
| 23 | tv.Sec = int32(nsec / 1e9) |
| 24 | tv.Usec = int32(nsec % 1e9 / 1e3) |
| 25 | return |
Kai Backman | 382a19c | 2009-08-18 19:20:33 -0700 | [diff] [blame] | 26 | } |
| 27 | |
Dave Cheney | 9b3ccc0 | 2015-02-25 10:20:13 +1100 | [diff] [blame] | 28 | func Pipe(p []int) (err error) { |
| 29 | if len(p) != 2 { |
| 30 | return EINVAL |
| 31 | } |
| 32 | var pp [2]_C_int |
| 33 | err = pipe2(&pp, 0) |
| 34 | p[0] = int(pp[0]) |
| 35 | p[1] = int(pp[1]) |
| 36 | return |
| 37 | } |
| 38 | |
| 39 | //sysnb pipe2(p *[2]_C_int, flags int) (err error) |
| 40 | |
| 41 | func Pipe2(p []int, flags int) (err error) { |
| 42 | if len(p) != 2 { |
| 43 | return EINVAL |
| 44 | } |
| 45 | var pp [2]_C_int |
| 46 | err = pipe2(&pp, flags) |
| 47 | p[0] = int(pp[0]) |
| 48 | p[1] = int(pp[1]) |
| 49 | return |
| 50 | } |
| 51 | |
Russ Cox | bf68f66 | 2014-05-16 12:15:32 -0400 | [diff] [blame] | 52 | // Underlying system call writes to newoffset via pointer. |
| 53 | // Implemented in assembly to avoid allocation. |
| 54 | func seek(fd int, offset int64, whence int) (newoffset int64, err Errno) |
Russ Cox | 1142b60 | 2010-10-20 10:39:46 -0400 | [diff] [blame] | 55 | |
Russ Cox | bf68f66 | 2014-05-16 12:15:32 -0400 | [diff] [blame] | 56 | func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { |
| 57 | newoffset, errno := seek(fd, offset, whence) |
| 58 | if errno != 0 { |
| 59 | return 0, errno |
| 60 | } |
| 61 | return newoffset, nil |
| 62 | } |
Russ Cox | 1142b60 | 2010-10-20 10:39:46 -0400 | [diff] [blame] | 63 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 64 | //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) |
Ian Lance Taylor | 31f58dc | 2013-01-28 08:54:15 -0800 | [diff] [blame] | 65 | //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) |
Brad Fitzpatrick | f00af3d | 2014-01-21 18:54:49 -0800 | [diff] [blame] | 66 | //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) |
| 67 | //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 68 | //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32 |
| 69 | //sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32 |
Brad Fitzpatrick | f00af3d | 2014-01-21 18:54:49 -0800 | [diff] [blame] | 70 | //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) |
| 71 | //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 72 | //sysnb socket(domain int, typ int, proto int) (fd int, err error) |
| 73 | //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) |
| 74 | //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) |
| 75 | //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) |
Brad Fitzpatrick | f00af3d | 2014-01-21 18:54:49 -0800 | [diff] [blame] | 76 | //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) |
Russ Cox | 3d5ddff | 2012-09-24 00:06:22 -0400 | [diff] [blame] | 77 | //sysnb socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 78 | //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) |
Mikio Hara | a7858a4 | 2014-03-29 09:28:40 +0900 | [diff] [blame] | 79 | //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) |
Kai Backman | 382a19c | 2009-08-18 19:20:33 -0700 | [diff] [blame] | 80 | |
Shenghou Ma | 911f802 | 2012-06-03 06:49:57 +0800 | [diff] [blame] | 81 | // 64-bit file system and 32-bit uid calls |
| 82 | // (16-bit uid calls are not always supported in newer kernels) |
Ian Lance Taylor | 28074d5 | 2015-03-26 08:02:16 -0700 | [diff] [blame] | 83 | //sys Dup2(oldfd int, newfd int) (err error) |
Shenghou Ma | 911f802 | 2012-06-03 06:49:57 +0800 | [diff] [blame] | 84 | //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 85 | //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 |
Shenghou Ma | 911f802 | 2012-06-03 06:49:57 +0800 | [diff] [blame] | 86 | //sysnb Getegid() (egid int) = SYS_GETEGID32 |
| 87 | //sysnb Geteuid() (euid int) = SYS_GETEUID32 |
| 88 | //sysnb Getgid() (gid int) = SYS_GETGID32 |
| 89 | //sysnb Getuid() (uid int) = SYS_GETUID32 |
Shenghou Ma | 3475362 | 2015-05-07 21:08:40 +0000 | [diff] [blame] | 90 | //sysnb InotifyInit() (fd int, err error) |
Shenghou Ma | 911f802 | 2012-06-03 06:49:57 +0800 | [diff] [blame] | 91 | //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 92 | //sys Listen(s int, n int) (err error) |
| 93 | //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 |
Dmitriy Vyukov | c242aa3 | 2012-10-29 23:15:06 +0400 | [diff] [blame] | 94 | //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 95 | //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT |
Shenghou Ma | 911f802 | 2012-06-03 06:49:57 +0800 | [diff] [blame] | 96 | //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 |
| 97 | //sys Setfsuid(uid int) (err error) = SYS_SETFSUID32 |
Shenghou Ma | 911f802 | 2012-06-03 06:49:57 +0800 | [diff] [blame] | 98 | //sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32 |
| 99 | //sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32 |
| 100 | //sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32 |
| 101 | //sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32 |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 102 | //sys Shutdown(fd int, how int) (err error) |
| 103 | //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) |
| 104 | //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 |
Kai Backman | 116beb2 | 2009-10-06 16:39:38 -0700 | [diff] [blame] | 105 | |
Ian Lance Taylor | 7d03d0e | 2010-09-21 06:49:56 -0700 | [diff] [blame] | 106 | // Vsyscalls on amd64. |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 107 | //sysnb Gettimeofday(tv *Timeval) (err error) |
| 108 | //sysnb Time(t *Time_t) (tt Time_t, err error) |
Ian Lance Taylor | 7d03d0e | 2010-09-21 06:49:56 -0700 | [diff] [blame] | 109 | |
Shenghou Ma | 6e21122 | 2012-03-06 03:12:11 +0800 | [diff] [blame] | 110 | //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 |
| 111 | //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 |
| 112 | //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 |
| 113 | //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 |
| 114 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 115 | //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) |
Russ Cox | 48ae1f2 | 2011-04-06 17:52:02 -0400 | [diff] [blame] | 116 | |
Shenghou Ma | f848595 | 2012-10-08 00:13:28 +0800 | [diff] [blame] | 117 | func Fstatfs(fd int, buf *Statfs_t) (err error) { |
| 118 | _, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) |
| 119 | if e != 0 { |
| 120 | err = e |
| 121 | } |
| 122 | return |
| 123 | } |
| 124 | |
| 125 | func Statfs(path string, buf *Statfs_t) (err error) { |
| 126 | pathp, err := BytePtrFromString(path) |
| 127 | if err != nil { |
| 128 | return err |
| 129 | } |
| 130 | _, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) |
Russ Cox | cf622d7 | 2014-09-08 16:59:59 -0400 | [diff] [blame] | 131 | use(unsafe.Pointer(pathp)) |
Shenghou Ma | f848595 | 2012-10-08 00:13:28 +0800 | [diff] [blame] | 132 | if e != 0 { |
| 133 | err = e |
| 134 | } |
| 135 | return |
| 136 | } |
| 137 | |
Russ Cox | c017a82 | 2011-11-13 22:44:52 -0500 | [diff] [blame] | 138 | func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { |
Russ Cox | 48ae1f2 | 2011-04-06 17:52:02 -0400 | [diff] [blame] | 139 | page := uintptr(offset / 4096) |
| 140 | if offset != int64(page)*4096 { |
| 141 | return 0, EINVAL |
| 142 | } |
| 143 | return mmap2(addr, length, prot, flags, fd, page) |
| 144 | } |
| 145 | |
Han-Wen Nienhuys | 8b7d39e | 2012-07-02 22:57:32 -0700 | [diff] [blame] | 146 | type rlimit32 struct { |
| 147 | Cur uint32 |
| 148 | Max uint32 |
| 149 | } |
| 150 | |
| 151 | //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT |
| 152 | |
| 153 | const rlimInf32 = ^uint32(0) |
| 154 | const rlimInf64 = ^uint64(0) |
| 155 | |
| 156 | func Getrlimit(resource int, rlim *Rlimit) (err error) { |
Peter Mundy | 5852760 | 2013-07-25 09:56:06 -0400 | [diff] [blame] | 157 | err = prlimit(0, resource, nil, rlim) |
Han-Wen Nienhuys | 8b7d39e | 2012-07-02 22:57:32 -0700 | [diff] [blame] | 158 | if err != ENOSYS { |
| 159 | return err |
| 160 | } |
| 161 | |
| 162 | rl := rlimit32{} |
| 163 | err = getrlimit(resource, &rl) |
| 164 | if err != nil { |
| 165 | return |
| 166 | } |
| 167 | |
| 168 | if rl.Cur == rlimInf32 { |
| 169 | rlim.Cur = rlimInf64 |
| 170 | } else { |
| 171 | rlim.Cur = uint64(rl.Cur) |
| 172 | } |
| 173 | |
| 174 | if rl.Max == rlimInf32 { |
| 175 | rlim.Max = rlimInf64 |
| 176 | } else { |
| 177 | rlim.Max = uint64(rl.Max) |
| 178 | } |
| 179 | return |
| 180 | } |
| 181 | |
| 182 | //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT |
| 183 | |
| 184 | func Setrlimit(resource int, rlim *Rlimit) (err error) { |
Peter Mundy | 5852760 | 2013-07-25 09:56:06 -0400 | [diff] [blame] | 185 | err = prlimit(0, resource, rlim, nil) |
Han-Wen Nienhuys | 8b7d39e | 2012-07-02 22:57:32 -0700 | [diff] [blame] | 186 | if err != ENOSYS { |
| 187 | return err |
| 188 | } |
| 189 | |
| 190 | rl := rlimit32{} |
| 191 | if rlim.Cur == rlimInf64 { |
| 192 | rl.Cur = rlimInf32 |
| 193 | } else if rlim.Cur < uint64(rlimInf32) { |
| 194 | rl.Cur = uint32(rlim.Cur) |
| 195 | } else { |
| 196 | return EINVAL |
| 197 | } |
| 198 | if rlim.Max == rlimInf64 { |
| 199 | rl.Max = rlimInf32 |
| 200 | } else if rlim.Max < uint64(rlimInf32) { |
| 201 | rl.Max = uint32(rlim.Max) |
| 202 | } else { |
| 203 | return EINVAL |
| 204 | } |
| 205 | |
| 206 | return setrlimit(resource, &rl) |
| 207 | } |
| 208 | |
Shenghou Ma | 7c412e9 | 2012-10-25 13:41:04 +0800 | [diff] [blame] | 209 | func (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) } |
Kai Backman | 116beb2 | 2009-10-06 16:39:38 -0700 | [diff] [blame] | 210 | |
Shenghou Ma | 7c412e9 | 2012-10-25 13:41:04 +0800 | [diff] [blame] | 211 | func (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) } |
Russ Cox | 66f7463 | 2010-12-08 14:31:46 -0500 | [diff] [blame] | 212 | |
| 213 | func (iov *Iovec) SetLen(length int) { |
| 214 | iov.Len = uint32(length) |
| 215 | } |
| 216 | |
| 217 | func (msghdr *Msghdr) SetControllen(length int) { |
| 218 | msghdr.Controllen = uint32(length) |
| 219 | } |
| 220 | |
| 221 | func (cmsg *Cmsghdr) SetLen(length int) { |
| 222 | cmsg.Len = uint32(length) |
| 223 | } |