Patchwork libgo patch committed: Fill out syscall package for GNU/Linux

login
register
mail settings
Submitter Ian Taylor
Date Feb. 29, 2012, 8:02 p.m.
Message ID <mcr62epo1b9.fsf@dhcp-172-18-216-180.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/143814/
State New
Headers show

Comments

Ian Taylor - Feb. 29, 2012, 8:02 p.m.
This patch to libgo fills out the syscall package for GNU/Linux to match
all the functions in the syscall package in the master Go library.
There is a test case for this patch at
http://code.google.com/p/go/issues/detail?id=3071 .  Bootstrapped and
ran Go testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch

diff -r 79998be2e6dd libgo/Makefile.am
--- a/libgo/Makefile.am	Tue Feb 28 12:55:43 2012 -0800
+++ b/libgo/Makefile.am	Wed Feb 29 11:53:30 2012 -0800
@@ -1489,6 +1489,13 @@ 
 syscall_netlink_file =
 endif
 
+# GNU/Linux specific socket filters.
+if LIBGO_IS_LINUX
+syscall_lsf_file = go/syscall/lsf_linux.go
+else
+syscall_lsf_file =
+endif
+
 go_base_syscall_files = \
 	go/syscall/env_unix.go \
 	go/syscall/syscall_errno.go \
@@ -1509,6 +1516,7 @@ 
 	$(syscall_socket_file) \
 	$(syscall_uname_file) \
 	$(syscall_netlink_file) \
+	$(syscall_lsf_file) \
 	$(GO_LIBCALL_OS_FILE) \
 	$(GO_LIBCALL_OS_ARCH_FILE) \
 	$(GO_SYSCALL_OS_FILE) \
diff -r 79998be2e6dd libgo/configure.ac
--- a/libgo/configure.ac	Tue Feb 28 12:55:43 2012 -0800
+++ b/libgo/configure.ac	Wed Feb 29 11:53:30 2012 -0800
@@ -453,7 +453,7 @@ 
   ;;
 esac
 
-AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h)
+AC_CHECK_HEADERS(sys/mman.h syscall.h sys/epoll.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h ustat.h utime.h linux/reboot.h)
 
 AC_CHECK_HEADERS([linux/filter.h linux/netlink.h linux/rtnetlink.h], [], [],
 [#ifdef HAVE_SYS_SOCKET_H
@@ -467,7 +467,7 @@ 
 AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
 AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
 
-AC_CHECK_FUNCS(epoll_create1 faccessat fallocate fchmodat fchownat futimesat inotify_add_watch inotify_init inotify_rm_watch mkdirat mknodat openat renameat splice tee unlinkat unshare)
+AC_CHECK_FUNCS(epoll_create1 faccessat fallocate fchmodat fchownat futimesat inotify_add_watch inotify_init inotify_init1 inotify_rm_watch mkdirat mknodat openat renameat sync_file_range splice tee unlinkat unshare)
 AC_TYPE_OFF_T
 AC_CHECK_TYPES([loff_t])
 
diff -r 79998be2e6dd libgo/go/syscall/libcall_linux.go
--- a/libgo/go/syscall/libcall_linux.go	Tue Feb 28 12:55:43 2012 -0800
+++ b/libgo/go/syscall/libcall_linux.go	Wed Feb 29 11:53:30 2012 -0800
@@ -160,20 +160,17 @@ 
 
 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
 
-// FIXME: mksysinfo needs to produce LINUX_REBOOT_MAGIC[12].
-
-// //sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
-// //reboot(magic1 uint, magic2 uint, cmd int, arg *byte) int
-// func Reboot(cmd int) (err error) {
-// 	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
-// }
+//sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
+//reboot(magic1 uint, magic2 uint, cmd int, arg *byte) int
+func Reboot(cmd int) (err error) {
+	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
+}
 
 //sys	Acct(path string) (err error)
 //acct(path *byte) int
 
-// FIXME: mksysinfo Timex
-// //sys	Adjtimex(buf *Timex) (state int, err error)
-// //adjtimex(buf *Timex) int
+//sys	Adjtimex(buf *Timex) (state int, err error)
+//adjtimex(buf *Timex) int
 
 //sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
 //faccessat(dirfd int, pathname *byte, mode int, flags int) int
@@ -198,10 +195,56 @@ 
 	return int(r1)
 }
 
-// FIXME: mksysinfo linux_dirent
-//    Or just abandon this function.
-// //sys	Getdents(fd int, buf []byte) (n int, err error)
-// //getdents64(fd int, buf *byte, count uint)
+func Getdents(fd int, buf []byte) (n int, err error) {
+	var p *byte
+	if len(buf) > 0 {
+		p = &buf[0]
+	} else {
+		p = (*byte)(unsafe.Pointer(&_zero))
+	}
+	entersyscall()
+	r1, _, errno := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(len(buf)))
+	n = int(r1)
+	if n < 0 {
+		err = errno
+	}
+	exitsyscall()
+	return
+}
+
+func clen(n []byte) int {
+	for i := 0; i < len(n); i++ {
+		if n[i] == 0 {
+			return i
+		}
+	}
+	return len(n)
+}
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+	return Getdents(fd, buf)
+}
+
+func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
+	origlen := len(buf)
+	count = 0
+	for max != 0 && len(buf) > 0 {
+		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
+		buf = buf[dirent.Reclen:]
+		if dirent.Ino == 0 { // File absent in directory.
+			continue
+		}
+		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
+		var name = string(bytes[0:clen(bytes[:])])
+		if name == "." || name == ".." { // Useless names
+			continue
+		}
+		max--
+		count++
+		names = append(names, name)
+	}
+	return origlen - len(buf), count, names
+}
 
 //sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
 //inotify_add_watch(fd int, pathname *byte, mask uint32) int
@@ -209,9 +252,8 @@ 
 //sysnb	InotifyInit() (fd int, err error)
 //inotify_init() int
 
-// FIXME: Only in glibc 2.9 and later.
-// //sysnb	InotifyInit1(flags int) (fd int, err error)
-// //inotify_init1(flags int) int
+//sysnb	InotifyInit1(flags int) (fd int, err error)
+//inotify_init1(flags int) int
 
 //sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
 //inotify_rm_watch(fd int, wd uint32) int
@@ -284,20 +326,22 @@ 
 //sys	Statfs(path string, buf *Statfs_t) (err error)
 //statfs(path *byte, buf *Statfs_t) int
 
-// FIXME: Only in glibc 2.6 and later.
-// //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
-// //sync_file_range(fd int, off Offset_t, n Offset_t, flags uint) int
+//sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
+//sync_file_range(fd int, off Offset_t, n Offset_t, flags uint) int
 
-// FIXME: mksysinfo Sysinfo_t
-// //sysnb	Sysinfo(info *Sysinfo_t) (err error)
-// //sysinfo(info *Sysinfo_t) int
+//sysnb	Sysinfo(info *Sysinfo_t) (err error)
+//sysinfo(info *Sysinfo_t) int
 
 //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
 //tee(rfd int, wfd int, len Size_t, flags uint) Ssize_t
 
-// FIXME: Only available as a syscall.
-// //sysnb	Tgkill(tgid int, tid int, sig int) (err error)
-// //tgkill(tgid int, tid int, sig int) int
+func Tgkill(tgid, tid, sig int) error {
+	r1, _, errno := Syscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+	if r1 < 0 {
+		return errno
+	}
+	return nil
+}
 
 //sys	unlinkat(dirfd int, path string, flags int) (err error)
 //unlinkat(dirfd int, path *byte, flags int) int
@@ -312,6 +356,5 @@ 
 //sys	Unshare(flags int) (err error)
 //unshare(flags int) int
 
-// FIXME: mksysinfo Ustat_t
-// //sys	Ustat(dev int, ubuf *Ustat_t) (err error)
-// //ustat(dev _dev_t, ubuf *Ustat_t) int
+//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
+//ustat(dev _dev_t, ubuf *Ustat_t) int
diff -r 79998be2e6dd libgo/go/syscall/libcall_posix.go
--- a/libgo/go/syscall/libcall_posix.go	Tue Feb 28 12:55:43 2012 -0800
+++ b/libgo/go/syscall/libcall_posix.go	Wed Feb 29 11:53:30 2012 -0800
@@ -61,6 +61,18 @@ 
 	}
 }
 
+func Getcwd(buf []byte) (n int, err error) {
+	err = getcwd(&buf[0], Size_t(len(buf)))
+	if err == nil {
+		i := 0
+		for buf[i] != 0 {
+			i++
+		}
+		n = i + 1
+	}
+	return
+}
+
 //sysnb	getgroups(size int, list *Gid_t) (nn int, err error)
 //getgroups(size int, list *Gid_t) int
 
@@ -226,9 +238,8 @@ 
 //sysnb	Getppid() (ppid int)
 //getppid() Pid_t
 
-// FIXME: mksysinfo Rlimit
-// //sysnb	Getrlimit(resource int, rlim *Rlimit) (err error)
-// //getrlimit(resource int, rlim *Rlimit) int
+//sysnb	Getrlimit(resource int, rlim *Rlimit) (err error)
+//getrlimit(resource int, rlim *Rlimit) int
 
 //sysnb	Getrusage(who int, rusage *Rusage) (err error)
 //getrusage(who int, rusage *Rusage) int
@@ -296,9 +307,8 @@ 
 //sysnb	Setreuid(ruid int, euid int) (err error)
 //setreuid(ruid Uid_t, euid Uid_t) int
 
-// FIXME: mksysinfo Rlimit
-// //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-// //setrlimit(resource int, rlim *Rlimit) int
+//sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
+//setrlimit(resource int, rlim *Rlimit) int
 
 //sysnb	Setsid() (pid int, err error)
 //setsid() Pid_t
@@ -319,9 +329,8 @@ 
 //sys	Sync()
 //sync()
 
-// FIXME: mksysinfo Time_t
-// //sysnb	Time(t *Time_t) (tt Time_t, err error)
-// //time(t *Time_t) Time_t
+//sysnb	Time(t *Time_t) (tt Time_t, err error)
+//time(t *Time_t) Time_t
 
 //sysnb	Times(tms *Tms) (ticks uintptr, err error)
 //times(tms *Tms) _clock_t
@@ -332,9 +341,8 @@ 
 //sys	Unlink(path string) (err error)
 //unlink(path *byte) int
 
-// FIXME: mksysinfo Utimbuf
-// //sys	Utime(path string, buf *Utimbuf) (err error)
-// //utime(path *byte, buf *Utimbuf) int
+//sys	Utime(path string, buf *Utimbuf) (err error)
+//utime(path *byte, buf *Utimbuf) int
 
 //sys	Write(fd int, p []byte) (n int, err error)
 //write(fd int, buf *byte, count Size_t) Ssize_t
diff -r 79998be2e6dd libgo/go/syscall/lsf_linux.go
--- a/libgo/go/syscall/lsf_linux.go	Tue Feb 28 12:55:43 2012 -0800
+++ b/libgo/go/syscall/lsf_linux.go	Wed Feb 29 11:53:30 2012 -0800
@@ -69,10 +69,10 @@ 
 	var p SockFprog
 	p.Len = uint16(len(i))
 	p.Filter = (*SockFilter)(unsafe.Pointer(&i[0]))
-	return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, uintptr(unsafe.Pointer(&p)), unsafe.Sizeof(p))
+	return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, (*byte)(unsafe.Pointer(&p)), Socklen_t(unsafe.Sizeof(p)))
 }
 
 func DetachLsf(fd int) error {
 	var dummy int
-	return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, uintptr(unsafe.Pointer(&dummy)), unsafe.Sizeof(dummy))
+	return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, (*byte)(unsafe.Pointer(&dummy)), Socklen_t(unsafe.Sizeof(dummy)))
 }
diff -r 79998be2e6dd libgo/mksysinfo.sh
--- a/libgo/mksysinfo.sh	Tue Feb 28 12:55:43 2012 -0800
+++ b/libgo/mksysinfo.sh	Wed Feb 29 11:53:30 2012 -0800
@@ -78,6 +78,7 @@ 
 #if defined(HAVE_SYS_SELECT_H)
 #include <sys/select.h>
 #endif
+#include <time.h>
 #include <unistd.h>
 #include <netdb.h>
 #include <pwd.h>
@@ -102,6 +103,21 @@ 
 #if defined(HAVE_STATFS_H)
 #include <sys/statfs.h>
 #endif
+#if defined(HAVE_SYS_TIMEX_H)
+#include <sys/timex.h>
+#endif
+#if defined(HAVE_SYS_SYSINFO_H)
+#include <sys/sysinfo.h>
+#endif
+#if defined(HAVE_USTAT_H)
+#include <ustat.h>
+#endif
+#if defined(HAVE_UTIME_H)
+#include <utime.h>
+#endif
+#if defined(HAVE_LINUX_REBOOT_H)
+#include <linux/reboot.h>
+#endif
 
 /* Constants that may only be defined as expressions on some systems,
    expressions too complex for -fdump-go-spec to handle.  These are
@@ -339,6 +355,11 @@ 
   echo "type _upad128_t struct { _l [4]uint32; }" >> ${OUT}
 fi
 
+# The time_t type.
+if grep '^type _time_t ' gen-sysinfo.go > /dev/null 2>&1; then
+  echo 'type Time_t _time_t' >> ${OUT}
+fi
+
 # The time structures need special handling: we need to name the
 # types, so that we can cast integers to the right types when
 # assigning to the structures.
@@ -712,6 +733,10 @@ 
     sed -e 's/^\(const \)_\(IFLA[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
 grep '^const _IFF' gen-sysinfo.go | \
     sed -e 's/^\(const \)_\(IFF[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+grep '^const _IFNAMSIZ' gen-sysinfo.go | \
+    sed -e 's/^\(const \)_\(IFNAMSIZ[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+grep '^const _SIOC' gen-sysinfo.go |
+    sed -e 's/^\(const \)_\(SIOC[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
 
 # The size of the ifinfomsg struct.
 if grep 'type IfInfomsg ' ${OUT} > /dev/null 2>&1; then
@@ -806,4 +831,95 @@ 
 	 -e 's/f_spare/Spare/' \
     >> ${OUT}
 
+# The timex struct.
+grep '^type _timex ' gen-sysinfo.go | \
+    sed -e 's/_timex/Timex/' \
+      -e 's/modes/Modes/' \
+      -e 's/offset/Offset/' \
+      -e 's/freq/Freq/' \
+      -e 's/maxerror/Maxerror/' \
+      -e 's/esterror/Esterror/' \
+      -e 's/status/Status/' \
+      -e 's/constant/Constant/' \
+      -e 's/precision/Precision/' \
+      -e 's/tolerance/Tolerance/' \
+      -e 's/ time / Time /' \
+      -e 's/tick/Tick/' \
+      -e 's/ppsfreq/Ppsfreq/' \
+      -e 's/jitter/Jitter/' \
+      -e 's/shift/Shift/' \
+      -e 's/stabil/Stabil/' \
+      -e 's/jitcnt/Jitcnt/' \
+      -e 's/calcnt/Calcnt/' \
+      -e 's/errcnt/Errcnt/' \
+      -e 's/stbcnt/Stbcnt/' \
+      -e 's/tai/Tai/' \
+      -e 's/_timeval/Timeval/' \
+    >> ${OUT}
+
+# The rlimit struct.
+grep '^type _rlimit ' gen-sysinfo.go | \
+    sed -e 's/_rlimit/Rlimit/' \
+      -e 's/rlim_cur/Cur/' \
+      -e 's/rlim_max/Max/' \
+    >> ${OUT}
+
+# The RLIMIT constants.
+grep '^const _RLIMIT_' gen-sysinfo.go |
+    sed -e 's/^\(const \)_\(RLIMIT_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# The sysinfo struct.
+grep '^type _sysinfo ' gen-sysinfo.go | \
+    sed -e 's/_sysinfo/Sysinfo_t/' \
+      -e 's/uptime/Uptime/' \
+      -e 's/loads/Loads/' \
+      -e 's/totalram/Totalram/' \
+      -e 's/freeram/Freeram/' \
+      -e 's/sharedram/Sharedram/' \
+      -e 's/bufferram/Bufferram/' \
+      -e 's/totalswap/Totalswap/' \
+      -e 's/freeswap/Freeswap/' \
+      -e 's/procs/Procs/' \
+      -e 's/totalhigh/Totalhigh/' \
+      -e 's/freehigh/Freehigh/' \
+      -e 's/mem_unit/Unit/' \
+    >> ${OUT}
+
+# The ustat struct.
+grep '^type _ustat ' gen-sysinfo.go | \
+    sed -e 's/_ustat/Ustat_t/' \
+      -e 's/f_tfree/Tfree/' \
+      -e 's/f_tinode/Tinoe/' \
+      -e 's/f_fname/Fname/' \
+      -e 's/f_fpack/Fpack/' \
+    >> ${OUT}
+
+# The utimbuf struct.
+grep '^type _utimbuf ' gen-sysinfo.go | \
+    sed -e 's/_utimbuf/Utimbuf/' \
+      -e 's/actime/Actime/' \
+      -e 's/modtime/Modtime/' \
+    >> ${OUT}
+
+# The GNU/Linux LINUX_REBOOT flags.
+grep '^const _LINUX_REBOOT_' gen-sysinfo.go |
+    sed -e 's/^\(const \)_\(LINUX_REBOOT_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+
+# The GNU/Linux sock_filter struct.
+grep '^type _sock_filter ' gen-sysinfo.go | \
+    sed -e 's/_sock_filter/SockFilter/' \
+      -e 's/code/Code/' \
+      -e 's/jt/Jt/' \
+      -e 's/jf/Jf/' \
+      -e 's/k /K /' \
+    >> ${OUT}
+
+# The GNU/Linux sock_fprog struct.
+grep '^type _sock_fprog ' gen-sysinfo.go | \
+    sed -e 's/_sock_fprog/SockFprog/' \
+      -e 's/len/Len/' \
+      -e 's/filter/Filter/' \
+      -e 's/_sock_filter/SockFilter/' \
+    >> ${OUT}
+
 exit $?
diff -r 79998be2e6dd libgo/runtime/go-nosys.c
--- a/libgo/runtime/go-nosys.c	Tue Feb 28 12:55:43 2012 -0800
+++ b/libgo/runtime/go-nosys.c	Wed Feb 29 11:53:30 2012 -0800
@@ -116,6 +116,15 @@ 
 }
 #endif
 
+#ifndef HAVE_INOTIFY_INIT1
+int
+inotify_init1 (int flags __attribute__ ((unused)))
+{
+  errno = ENOSYS;
+  return -1;
+}
+#endif
+
 #ifndef HAVE_INOTIFY_RM_WATCH
 int
 inotify_rm_watch (int fd __attribute__ ((unused)),
@@ -187,6 +196,18 @@ 
 }
 #endif
 
+#ifndef HAVE_SYNC_FILE_RANGE
+int
+sync_file_range (int fd __attribute__ ((unused)),
+		 off64_t offset __attribute__ ((unused)),
+		 off64_t nbytes __attribute__ ((unused)),
+		 unsigned int flags __attribute__ ((unused)))
+{
+  errno = ENOSYS;
+  return -1;
+}
+#endif
+
 #ifndef HAVE_TEE
 int
 tee (int fd_in __attribute__ ((unused)),