OSDN Git Service

libgo: Only build iopl and ioperm on 386, amd64, alpha GNU/Linux.
[pf3gnuchains/gcc-fork.git] / libgo / go / syscall / libcall_linux.go
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 // GNU/Linux library calls.
6
7 package syscall
8
9 import "unsafe"
10
11 //sys   Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
12 //openat(dirfd int, path *byte, flags int, mode Mode_t) int
13
14 //sys   futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
15 //futimesat(dirfd int, path *byte, times *[2]Timeval) int
16 func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
17         if len(tv) != 2 {
18                 return EINVAL
19         }
20         return futimesat(dirfd, StringBytePtr(path), (*[2]Timeval)(unsafe.Pointer(&tv[0])))
21 }
22
23 func Futimes(fd int, tv []Timeval) (err error) {
24         // Believe it or not, this is the best we can do on GNU/Linux
25         // (and is what glibc does).
26         return Utimes("/proc/self/fd/"+itoa(fd), tv)
27 }
28
29 //sys   ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
30 //ptrace(request int, pid Pid_t, addr *byte, data *byte) _C_long
31
32 //sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
33 //ptrace(request int, pid Pid_t, addr *byte, data *byte) _C_long
34
35 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
36         // The peek requests are machine-size oriented, so we wrap it
37         // to retrieve arbitrary-length data.
38
39         // The ptrace syscall differs from glibc's ptrace.
40         // Peeks returns the word in *data, not as the return value.
41
42         var buf [sizeofPtr]byte
43
44         // Leading edge.  PEEKTEXT/PEEKDATA don't require aligned
45         // access (PEEKUSER warns that it might), but if we don't
46         // align our reads, we might straddle an unmapped page
47         // boundary and not get the bytes leading up to the page
48         // boundary.
49         n := 0
50         if addr%sizeofPtr != 0 {
51                 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
52                 if err != nil {
53                         return 0, err
54                 }
55                 n += copy(out, buf[addr%sizeofPtr:])
56                 out = out[n:]
57         }
58
59         // Remainder.
60         for len(out) > 0 {
61                 // We use an internal buffer to gaurantee alignment.
62                 // It's not documented if this is necessary, but we're paranoid.
63                 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
64                 if err != nil {
65                         return n, err
66                 }
67                 copied := copy(out, buf[0:])
68                 n += copied
69                 out = out[copied:]
70         }
71
72         return n, nil
73 }
74
75 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
76         return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
77 }
78
79 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
80         return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
81 }
82
83 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
84         // As for ptracePeek, we need to align our accesses to deal
85         // with the possibility of straddling an invalid page.
86
87         // Leading edge.
88         n := 0
89         if addr%sizeofPtr != 0 {
90                 var buf [sizeofPtr]byte
91                 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
92                 if err != nil {
93                         return 0, err
94                 }
95                 n += copy(buf[addr%sizeofPtr:], data)
96                 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
97                 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
98                 if err != nil {
99                         return 0, err
100                 }
101                 data = data[n:]
102         }
103
104         // Interior.
105         for len(data) > int(sizeofPtr) {
106                 word := *((*uintptr)(unsafe.Pointer(&data[0])))
107                 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
108                 if err != nil {
109                         return n, err
110                 }
111                 n += int(sizeofPtr)
112                 data = data[sizeofPtr:]
113         }
114
115         // Trailing edge.
116         if len(data) > 0 {
117                 var buf [sizeofPtr]byte
118                 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
119                 if err != nil {
120                         return n, err
121                 }
122                 copy(buf[0:], data)
123                 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
124                 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
125                 if err != nil {
126                         return n, err
127                 }
128                 n += len(data)
129         }
130
131         return n, nil
132 }
133
134 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
135         return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
136 }
137
138 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
139         return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
140 }
141
142 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
143         return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
144 }
145
146 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
147         return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
148 }
149
150 func PtraceSetOptions(pid int, options int) (err error) {
151         return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
152 }
153
154 func PtraceGetEventMsg(pid int) (msg uint, err error) {
155         var data _C_long
156         err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
157         msg = uint(data)
158         return
159 }
160
161 func PtraceCont(pid int, signal int) (err error) {
162         return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
163 }
164
165 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
166
167 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
168
169 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
170
171 // FIXME: mksysinfo needs to produce LINUX_REBOOT_MAGIC[12].
172
173 // //sys        reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
174 // //reboot(magic1 uint, magic2 uint, cmd int, arg *byte) int
175 // func Reboot(cmd int) (err error) {
176 //      return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
177 // }
178
179 //sys   Acct(path string) (err error)
180 //acct(path *byte) int
181
182 // FIXME: mksysinfo Timex
183 // //sys        Adjtimex(buf *Timex) (state int, err error)
184 // //adjtimex(buf *Timex) int
185
186 //sys   Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
187 //faccessat(dirfd int, pathname *byte, mode int, flags int) int
188
189 // FIXME: Only in glibc 2.10 and later.
190 // //sys        Fallocate(fd int, mode uint32, off int64, len int64) (err error)
191 // //fallocate(fd int, mode int, offset Offset_t, len Offset_t) int
192
193 //sys   Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
194 //fchmodat(dirfd int, pathname *byte, mode Mode_t, flags int) int
195
196 //sys   Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
197 //fchownat(dirfd int, path *byte, owner Uid_t, group Gid_t, flags int) int
198
199 //sys   Flock(fd int, how int) (err error)
200 //flock(fd int, how int) int
201
202 // FIXME: mksysinfo statfs
203 // //sys        Fstatfs(fd int, buf *Statfs_t) (err error)
204 // //fstatfs(fd int, buf *Statfs_t) int
205
206 // FIXME: Only available as a syscall.
207 // //sysnb      Gettid() (tid int)
208 // //gettid() Pid_t
209
210 // FIXME: mksysinfo linux_dirent
211 //    Or just abandon this function.
212 // //sys        Getdents(fd int, buf []byte) (n int, err error)
213 // //getdents64(fd int, buf *byte, count uint)
214
215 //sys   InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
216 //inotify_add_watch(fd int, pathname *byte, mask uint32) int
217
218 //sysnb InotifyInit() (fd int, err error)
219 //inotify_init() int
220
221 // FIXME: Only in glibc 2.9 and later.
222 // //sysnb      InotifyInit1(flags int) (fd int, err error)
223 // //inotify_init1(flags int) int
224
225 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
226 //inotify_rm_watch(fd int, wd uint32) int
227
228 //sys   Klogctl(typ int, buf []byte) (n int, err error)
229 //klogctl(typ int, bufp *byte, len int) int
230
231 //sys   Mkdirat(dirfd int, path string, mode uint32) (err error)
232 //mkdirat(dirfd int, path *byte, mode Mode_t) int
233
234 //sys   Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
235 //mknodat(dirfd int, path *byte, mode Mode_t, dev _dev_t) int
236
237 //sys   PivotRoot(newroot string, putold string) (err error)
238 //pivot_root(newroot *byte, putold *byte) int
239
240 //sys   Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
241 //renameat(olddirfd int, oldpath *byte, newdirfd int, newpath *byte) int
242
243 //sys   sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error)
244 //sendfile64(outfd int, infd int, offset *Offset_t, count Size_t) Ssize_t
245 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
246         var soff Offset_t
247         var psoff *Offset_t
248         if offset != nil {
249                 psoff = &soff
250         }
251         written, err = sendfile(outfd, infd, psoff, count)
252         if offset != nil {
253                 *offset = int64(soff)
254         }
255         return
256 }
257
258 //sys   Setfsgid(gid int) (err error)
259 //setfsgid(gid Gid_t) int
260
261 //sys   Setfsuid(uid int) (err error)
262 //setfsuid(uid Uid_t) int
263
264 //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
265 //setresgid(rgid Gid_t, egid Gid_t, sgid Gid_t) int
266
267 //sysnb Setresuid(ruid int, eguid int, suid int) (err error)
268 //setresuid(ruid Uid_t, euid Uid_t, suid Uid_t) int
269
270 //sys   splice(rfd int, roff *_loff_t, wfd int, woff *_loff_t, len int, flags int) (n int64, err error)
271 //splice(rfd int, roff *_loff_t, wfd int, woff *_loff_t, len Size_t, flags uint) Ssize_t
272 func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
273         var lroff _loff_t
274         var plroff *_loff_t
275         if roff != nil {
276                 plroff = &lroff
277         }
278         var lwoff _loff_t
279         var plwoff *_loff_t
280         if woff != nil {
281                 plwoff = &lwoff
282         }
283         n, err = splice(rfd, plroff, wfd, plwoff, len, flags)
284         if roff != nil {
285                 *roff = int64(lroff)
286         }
287         if woff != nil {
288                 *woff = int64(lwoff)
289         }
290         return
291 }
292
293 // FIXME: mksysinfo statfs
294 // //sys        Statfs(path string, buf *Statfs_t) (err error)
295 // //statfs(path *byte, buf *Statfs_t) int
296
297 // FIXME: Only in glibc 2.6 and later.
298 // //sys        SyncFileRange(fd int, off int64, n int64, flags int) (err error)
299 // //sync_file_range(fd int, off Offset_t, n Offset_t, flags uint) int
300
301 // FIXME: mksysinfo Sysinfo_t
302 // //sysnb      Sysinfo(info *Sysinfo_t) (err error)
303 // //sysinfo(info *Sysinfo_t) int
304
305 //sys   Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
306 //tee(rfd int, wfd int, len Size_t, flags uint) Ssize_t
307
308 // FIXME: Only available as a syscall.
309 // //sysnb      Tgkill(tgid int, tid int, sig int) (err error)
310 // //tgkill(tgid int, tid int, sig int) int
311
312 //sys   unlinkat(dirfd int, path string, flags int) (err error)
313 //unlinkat(dirfd int, path *byte, flags int) int
314
315 func Unlinkat(dirfd int, path string) (err error) {
316         return unlinkat(dirfd, path, 0)
317 }
318
319 //sys   Unmount(target string, flags int) (err error) = SYS_UMOUNT2
320 //umount2(target *byte, flags int) int
321
322 //sys   Unshare(flags int) (err error)
323 //unshare(flags int) int
324
325 // FIXME: mksysinfo Ustat_t
326 // //sys        Ustat(dev int, ubuf *Ustat_t) (err error)
327 // //ustat(dev _dev_t, ubuf *Ustat_t) int