2011-05-31 Gabriel Charette <gchare@google.com>
[official-gcc.git] / libgo / syscalls / sysfile_posix.go
bloba16ba4aba607f2341fbe97c52e4cf0342150cc19
1 // sysfile_posix.go -- POSIX File handling.
3 // Copyright 2010 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Support for basic Unix file operations. This file simply
8 // translates from Go data types to Unix data types, and handles
9 // errno. FIXME: This could probably be done mechanically.
11 package syscall
13 import "unsafe"
15 func libc_open(name *byte, mode int, perm Mode_t) int __asm__ ("open");
16 func libc_close(fd int) int __asm__ ("close");
17 func libc_read(fd int, buf *byte, count Size_t) Ssize_t __asm__ ("read");
18 func libc_write(fd int, buf *byte, count Size_t) Ssize_t __asm__ ("write");
19 func libc_fsync(fd int) int __asm__ ("fsync")
20 func libc_pipe(filedes *int) int __asm__("pipe");
21 func libc_unlink(name *byte) int __asm__ ("unlink");
22 func libc_rmdir(name *byte) int __asm__ ("rmdir");
23 func libc_fcntl(fd int, cmd int, arg int) int __asm__ ("fcntl");
24 func libc_mkdir(name *byte, perm Mode_t) int __asm__ ("mkdir");
25 func libc_dup(int) int __asm__ ("dup")
26 func libc_gettimeofday(tv *Timeval, tz *byte) int __asm__ ("gettimeofday");
27 func libc_select(int, *byte, *byte, *byte, *Timeval) int __asm__ ("select");
28 func libc_chdir(name *byte) int __asm__ ("chdir");
29 func libc_fchdir(int) int __asm__ ("fchdir");
30 func libc_getcwd(*byte, Size_t) *byte __asm__ ("getcwd");
31 func libc_link(oldpath *byte, newpath *byte) int __asm__ ("link");
32 func libc_symlink(oldpath *byte, newpath *byte) int __asm__ ("symlink");
33 func libc_readlink(*byte, *byte, Size_t) Ssize_t __asm__ ("readlink");
34 func libc_rename(oldpath *byte, newpath *byte) int __asm__ ("rename");
35 func libc_chmod(path *byte, mode Mode_t) int __asm__ ("chmod");
36 func libc_fchmod(fd int, mode Mode_t) int __asm__ ("fchmod");
37 func libc_chown(path *byte, owner Uid_t, group Gid_t) int __asm__ ("chown");
38 func libc_fchown(fd int, owner Uid_t, group Gid_t) int __asm__ ("fchown");
39 func libc_lchown(path *byte, owner Uid_t, group Gid_t) int __asm__ ("lchown");
40 func libc_utimes(filename *byte, times *[2]Timeval) int __asm__ ("utimes");
41 func libc_getuid() Uid_t __asm__ ("getuid");
42 func libc_geteuid() Uid_t __asm__ ("geteuid");
43 func libc_getgid() Gid_t __asm__ ("getgid");
44 func libc_getegid() Gid_t __asm__ ("getegid");
45 func libc_getgroups(size int, list *Gid_t) int __asm__ ("getgroups");
46 func libc_getpagesize() int __asm__ ("getpagesize");
47 func libc_exit(status int) __asm__ ("exit")
48 func libc_getpid() Pid_t __asm__ ("getpid")
49 func libc_getppid() Pid_t __asm__ ("getppid")
50 func libc_kill(Pid_t, int) int __asm__ ("kill")
52 func Open(name string, mode int, perm uint32) (fd int, errno int) {
53 fd = libc_open(StringBytePtr(name), mode, Mode_t(perm));
54 if fd < 0 { errno = GetErrno() }
55 return;
58 func Creat(name string, perm uint32) (fd int, errno int) {
59 fd = libc_open(StringBytePtr(name), O_CREAT | O_WRONLY | O_TRUNC, Mode_t(perm));
60 if fd < 0 { errno = GetErrno() }
61 return;
64 func Close(fd int) (errno int) {
65 r := libc_close(fd);
66 if r < 0 { errno = GetErrno() }
67 return;
70 func Read(fd int, p []byte) (n int, errno int) {
71 var _p0 *byte;
72 if len(p) > 0 { _p0 = &p[0]; }
73 r := libc_read(fd, _p0, Size_t(len(p)));
74 if r == -1 { errno = GetErrno() }
75 n = int(r);
76 return;
79 func Write(fd int, p []byte) (n int, errno int) {
80 var _p0 *byte;
81 if len(p) > 0 { _p0 = &p[0]; }
82 r := libc_write(fd, _p0, Size_t(len(p)));
83 if r == -1 { errno = GetErrno() }
84 n = int(r);
85 return;
88 func Fsync(fd int) (errno int) {
89 if libc_fsync(fd) < 0 {
90 errno = GetErrno()
92 return
95 func Pread(fd int, p []byte, offset int64) (n int, errno int) {
96 var _p0 *byte;
97 if len(p) > 0 { _p0 = &p[0]; }
98 r := libc_pread(fd, _p0, Size_t(len(p)), Offset_t(offset));
99 if r == -1 { errno = GetErrno() }
100 n = int(r);
101 return;
104 func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
105 var _p0 *byte;
106 if len(p) > 0 { _p0 = &p[0]; }
107 r := libc_pwrite(fd, _p0, Size_t(len(p)), Offset_t(offset));
108 if r == -1 { errno = GetErrno() }
109 n = int(r);
110 return;
113 func Seek(fd int, offset int64, whence int) (off int64, errno int) {
114 r := libc_lseek(fd, Offset_t(offset), whence);
115 if r == -1 { errno = GetErrno() }
116 off = int64(r);
117 return;
120 func Pipe(p []int) (errno int) {
121 if len(p) != 2 {
122 return EINVAL;
124 var pp [2]int;
125 r := libc_pipe(&pp[0]);
126 if r < 0 {
127 errno = GetErrno();
129 p[0] = pp[0];
130 p[1] = pp[1];
131 return;
134 func Stat(name string, buf *Stat_t) (errno int) {
135 r := libc_stat(StringBytePtr(name), buf);
136 if r < 0 { errno = GetErrno() }
137 return;
140 func Lstat(name string, buf *Stat_t) (errno int) {
141 r := libc_lstat(StringBytePtr(name), buf);
142 if r < 0 { errno = GetErrno() }
143 return;
146 func Fstat(fd int, buf *Stat_t) (errno int) {
147 r := libc_fstat(fd, buf);
148 if r < 0 { errno = GetErrno() }
149 return;
152 func Unlink(name string) (errno int) {
153 r := libc_unlink(StringBytePtr(name));
154 if r < 0 { errno = GetErrno() }
155 return;
158 func Rmdir(name string) (errno int) {
159 r := libc_rmdir(StringBytePtr(name));
160 if r < 0 { errno = GetErrno() }
161 return;
164 func Mkdir(path string, mode uint32) (errno int) {
165 r := libc_mkdir(StringBytePtr(path), Mode_t(mode));
166 if r < 0 { errno = GetErrno() }
167 return;
170 func Dup(oldfd int) (fd int, errno int) {
171 fd = libc_dup(oldfd)
172 if fd < 0 {
173 errno = GetErrno()
175 return
178 func Gettimeofday(tv *Timeval) (errno int) {
179 r := libc_gettimeofday(tv, nil);
180 if r < 0 { errno = GetErrno() }
181 return;
184 const nfdbits = unsafe.Sizeof(fds_bits_type) * 8
186 type FdSet_t struct {
187 Fds_bits [(FD_SETSIZE + nfdbits - 1) / nfdbits]fds_bits_type
190 func FDSet(fd int, set *FdSet_t) {
191 set.Fds_bits[fd / nfdbits] |= (1 << (uint)(fd % nfdbits))
194 func FDClr(fd int, set *FdSet_t) {
195 set.Fds_bits[fd / nfdbits] &^= (1 << (uint)(fd % nfdbits))
198 func FDIsSet(fd int, set *FdSet_t) bool {
199 if set.Fds_bits[fd / nfdbits] & (1 << (uint)(fd % nfdbits)) != 0 {
200 return true
201 } else {
202 return false
206 func FDZero(set *FdSet_t) {
207 for i := range set.Fds_bits {
208 set.Fds_bits[i] = 0
212 func Select(nfds int, r *FdSet_t, w *FdSet_t, e *FdSet_t, timeout *Timeval) (n int, errno int) {
213 n = libc_select(nfds, (*byte)(unsafe.Pointer(r)),
214 (*byte)(unsafe.Pointer(w)),
215 (*byte)(unsafe.Pointer(e)), timeout);
216 if n < 0 { errno = GetErrno() }
217 return;
220 func Chdir(path string) (errno int) {
221 r := libc_chdir(StringBytePtr(path));
222 if r < 0 { errno = GetErrno() }
223 return;
226 func Fchdir(fd int) (errno int) {
227 r := libc_fchdir(int(fd));
228 if r < 0 { errno = GetErrno() }
229 return;
232 const ImplementsGetwd = true
234 func Getwd() (ret string, errno int) {
235 for len := Size_t(4096); ; len *= 2 {
236 b := make([]byte, len);
237 p := libc_getcwd(&b[0], len);
238 if p != nil {
239 i := 0;
240 for b[i] != 0 {
241 i++;
243 return string(b[0:i]), 0;
245 e := GetErrno();
246 if e != ERANGE {
247 return "", e;
252 func Link(oldpath, newpath string) (errno int) {
253 r := libc_link(StringBytePtr(oldpath), StringBytePtr(newpath));
254 if r < 0 { errno = GetErrno() }
255 return;
258 func Symlink(oldpath, newpath string) (errno int) {
259 r := libc_symlink(StringBytePtr(oldpath), StringBytePtr(newpath));
260 if r < 0 { errno = GetErrno() }
261 return;
264 func Readlink(path string, buf []byte) (n int, errno int) {
265 var _p0 *byte;
266 if len(buf) > 0 { _p0 = &buf[0]; }
267 r := libc_readlink(StringBytePtr(path), _p0, Size_t(len(buf)));
268 if r < 0 { errno = GetErrno() }
269 n = int(r);
270 return;
273 func Rename(oldpath, newpath string) (errno int) {
274 r := libc_rename(StringBytePtr(oldpath), StringBytePtr(newpath));
275 if r < 0 { errno = GetErrno() }
276 return
279 func Chmod(path string, mode uint32) (errno int) {
280 r := libc_chmod(StringBytePtr(path), Mode_t(mode));
281 if r < 0 { errno = GetErrno() }
282 return;
285 func Fchmod(fd int, mode uint32) (errno int) {
286 r := libc_fchmod(fd, Mode_t(mode));
287 if r < 0 { errno = GetErrno() }
288 return;
291 func Chown(path string, uid int, gid int) (errno int) {
292 r := libc_chown(StringBytePtr(path), Uid_t(uid), Gid_t(gid));
293 if r < 0 { errno = GetErrno() }
294 return;
297 func Lchown(path string, uid int, gid int) (errno int) {
298 r := libc_lchown(StringBytePtr(path), Uid_t(uid), Gid_t(gid));
299 if r < 0 { errno = GetErrno() }
300 return;
303 func Fchown(fd int, uid int, gid int) (errno int) {
304 r := libc_fchown(fd, Uid_t(uid), Gid_t(gid));
305 if r < 0 { errno = GetErrno() }
306 return;
309 func Truncate(path string, length int64) (errno int) {
310 r := libc_truncate(StringBytePtr(path), Offset_t(length));
311 if r < 0 { errno = GetErrno() }
312 return;
315 func Ftruncate(fd int, length int64) (errno int) {
316 r := libc_ftruncate(fd, Offset_t(length));
317 if r < 0 { errno = GetErrno() }
318 return;
321 func Utimes(path string, tv []Timeval) (errno int) {
322 if len(tv) != 2 {
323 return EINVAL;
325 r := libc_utimes(StringBytePtr(path),
326 (*[2]Timeval)(unsafe.Pointer(&tv[0])));
327 if r < 0 {
328 errno = GetErrno();
330 return;
333 // Getuid returns the numeric user id of the caller.
334 func Getuid() int {
335 return int(libc_getuid());
338 // Geteuid returns the numeric effective user id of the caller.
339 func Geteuid() int {
340 return int(libc_geteuid());
343 // Getgid returns the numeric group id of the caller.
344 func Getgid() int {
345 return int(libc_getgid());
348 // Getegid returns the numeric effective group id of the caller.
349 func Getegid() int {
350 return int(libc_getegid());
353 // Getgroups returns a list of the numeric ids of groups that the caller belongs to.
354 func Getgroups() (gids []int, errno int) {
355 n := libc_getgroups(0, nil);
356 if n < 0 {
357 return nil, GetErrno();
359 if n == 0 {
360 return nil, 0;
363 // Sanity check group count. Max is 1<<16 on Linux.
364 if n < 0 || n > 1<<20 {
365 return nil, EINVAL;
368 a := make([]Gid_t, n);
369 n = libc_getgroups(n, &a[0]);
370 if n < 0 {
371 return nil, GetErrno();
373 gids = make([]int, n);
374 for i, v := range a[0:n] {
375 gids[i] = int(v);
377 return;
380 func Getpagesize() int {
381 return libc_getpagesize();
384 func TimespecToNsec(ts Timespec) int64 {
385 return int64(ts.Sec)*1e9 + int64(ts.Nsec);
388 func NsecToTimespec(nsec int64) (ts Timespec) {
389 ts.Sec = Timespec_sec_t(nsec / 1e9);
390 ts.Nsec = Timespec_nsec_t(nsec % 1e9);
391 return;
394 func TimevalToNsec(tv Timeval) int64 {
395 return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3;
398 func NsecToTimeval(nsec int64) (tv Timeval) {
399 nsec += 999; // round up to microsecond
400 tv.Sec = Timeval_sec_t(nsec/1e9);
401 tv.Usec = Timeval_usec_t(nsec%1e9 / 1e3);
402 return;
405 func Exit(code int) {
406 libc_exit(code);
409 func fcntl(fd, cmd, arg int) (val int, errno int) {
410 val = libc_fcntl(int(fd), int(cmd), int(arg));
411 if val == -1 { errno = GetErrno() }
412 return;
415 func Getpid() (pid int) {
416 return int(libc_getpid());
419 func Getppid() (ppid int) {
420 return int(libc_getppid());
423 func Kill(pid int, sig int) (errno int) {
424 r := libc_kill(Pid_t(pid), sig)
425 if r < 0 {
426 errno = GetErrno()
428 return