...

Source file src/syscall/syscall_linux_386.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	// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
     6	// so that go vet can check that they are correct.
     7	
     8	package syscall
     9	
    10	import "unsafe"
    11	
    12	const (
    13		_SYS_dup       = SYS_DUP2
    14		_SYS_setgroups = SYS_SETGROUPS32
    15	)
    16	
    17	func setTimespec(sec, nsec int64) Timespec {
    18		return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
    19	}
    20	
    21	func setTimeval(sec, usec int64) Timeval {
    22		return Timeval{Sec: int32(sec), Usec: int32(usec)}
    23	}
    24	
    25	//sysnb	pipe(p *[2]_C_int) (err error)
    26	
    27	func Pipe(p []int) (err error) {
    28		if len(p) != 2 {
    29			return EINVAL
    30		}
    31		var pp [2]_C_int
    32		err = pipe(&pp)
    33		p[0] = int(pp[0])
    34		p[1] = int(pp[1])
    35		return
    36	}
    37	
    38	//sysnb pipe2(p *[2]_C_int, flags int) (err error)
    39	
    40	func Pipe2(p []int, flags int) (err error) {
    41		if len(p) != 2 {
    42			return EINVAL
    43		}
    44		var pp [2]_C_int
    45		err = pipe2(&pp, flags)
    46		p[0] = int(pp[0])
    47		p[1] = int(pp[1])
    48		return
    49	}
    50	
    51	// 64-bit file system and 32-bit uid calls
    52	// (386 default is 32-bit file system and 16-bit uid).
    53	//sys	Dup2(oldfd int, newfd int) (err error)
    54	//sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
    55	//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
    56	//sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
    57	//sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
    58	//sysnb	Getegid() (egid int) = SYS_GETEGID32
    59	//sysnb	Geteuid() (euid int) = SYS_GETEUID32
    60	//sysnb	Getgid() (gid int) = SYS_GETGID32
    61	//sysnb	Getuid() (uid int) = SYS_GETUID32
    62	//sysnb	InotifyInit() (fd int, err error)
    63	//sys	Ioperm(from int, num int, on int) (err error)
    64	//sys	Iopl(level int) (err error)
    65	//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
    66	//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
    67	//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
    68	//sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
    69	//sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
    70	//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
    71	//sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
    72	//sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
    73	//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
    74	//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
    75	//sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
    76	//sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
    77	//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
    78	//sysnb	setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
    79	//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
    80	
    81	//sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
    82	//sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
    83	
    84	func Stat(path string, stat *Stat_t) (err error) {
    85		return fstatat(_AT_FDCWD, path, stat, 0)
    86	}
    87	
    88	func Lchown(path string, uid int, gid int) (err error) {
    89		return Fchownat(_AT_FDCWD, path, uid, gid, _AT_SYMLINK_NOFOLLOW)
    90	}
    91	
    92	func Lstat(path string, stat *Stat_t) (err error) {
    93		return fstatat(_AT_FDCWD, path, stat, _AT_SYMLINK_NOFOLLOW)
    94	}
    95	
    96	func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
    97		page := uintptr(offset / 4096)
    98		if offset != int64(page)*4096 {
    99			return 0, EINVAL
   100		}
   101		return mmap2(addr, length, prot, flags, fd, page)
   102	}
   103	
   104	type rlimit32 struct {
   105		Cur uint32
   106		Max uint32
   107	}
   108	
   109	//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
   110	
   111	const rlimInf32 = ^uint32(0)
   112	const rlimInf64 = ^uint64(0)
   113	
   114	func Getrlimit(resource int, rlim *Rlimit) (err error) {
   115		err = prlimit(0, resource, nil, rlim)
   116		if err != ENOSYS {
   117			return err
   118		}
   119	
   120		rl := rlimit32{}
   121		err = getrlimit(resource, &rl)
   122		if err != nil {
   123			return
   124		}
   125	
   126		if rl.Cur == rlimInf32 {
   127			rlim.Cur = rlimInf64
   128		} else {
   129			rlim.Cur = uint64(rl.Cur)
   130		}
   131	
   132		if rl.Max == rlimInf32 {
   133			rlim.Max = rlimInf64
   134		} else {
   135			rlim.Max = uint64(rl.Max)
   136		}
   137		return
   138	}
   139	
   140	//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
   141	
   142	func Setrlimit(resource int, rlim *Rlimit) (err error) {
   143		err = prlimit(0, resource, rlim, nil)
   144		if err != ENOSYS {
   145			return err
   146		}
   147	
   148		rl := rlimit32{}
   149		if rlim.Cur == rlimInf64 {
   150			rl.Cur = rlimInf32
   151		} else if rlim.Cur < uint64(rlimInf32) {
   152			rl.Cur = uint32(rlim.Cur)
   153		} else {
   154			return EINVAL
   155		}
   156		if rlim.Max == rlimInf64 {
   157			rl.Max = rlimInf32
   158		} else if rlim.Max < uint64(rlimInf32) {
   159			rl.Max = uint32(rlim.Max)
   160		} else {
   161			return EINVAL
   162		}
   163	
   164		return setrlimit(resource, &rl)
   165	}
   166	
   167	// Underlying system call writes to newoffset via pointer.
   168	// Implemented in assembly to avoid allocation.
   169	func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
   170	
   171	func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
   172		newoffset, errno := seek(fd, offset, whence)
   173		if errno != 0 {
   174			return 0, errno
   175		}
   176		return newoffset, nil
   177	}
   178	
   179	// Vsyscalls on amd64.
   180	//sysnb	Gettimeofday(tv *Timeval) (err error)
   181	//sysnb	Time(t *Time_t) (tt Time_t, err error)
   182	
   183	// On x86 Linux, all the socket calls go through an extra indirection,
   184	// I think because the 5-register system call interface can't handle
   185	// the 6-argument calls like sendto and recvfrom. Instead the
   186	// arguments to the underlying system call are the number below
   187	// and a pointer to an array of uintptr. We hide the pointer in the
   188	// socketcall assembly to avoid allocation on every system call.
   189	
   190	const (
   191		// see linux/net.h
   192		_SOCKET      = 1
   193		_BIND        = 2
   194		_CONNECT     = 3
   195		_LISTEN      = 4
   196		_ACCEPT      = 5
   197		_GETSOCKNAME = 6
   198		_GETPEERNAME = 7
   199		_SOCKETPAIR  = 8
   200		_SEND        = 9
   201		_RECV        = 10
   202		_SENDTO      = 11
   203		_RECVFROM    = 12
   204		_SHUTDOWN    = 13
   205		_SETSOCKOPT  = 14
   206		_GETSOCKOPT  = 15
   207		_SENDMSG     = 16
   208		_RECVMSG     = 17
   209		_ACCEPT4     = 18
   210		_RECVMMSG    = 19
   211		_SENDMMSG    = 20
   212	)
   213	
   214	func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   215	func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
   216	
   217	func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
   218		fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   219		if e != 0 {
   220			err = e
   221		}
   222		return
   223	}
   224	
   225	func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
   226		fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
   227		if e != 0 {
   228			err = e
   229		}
   230		return
   231	}
   232	
   233	func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   234		_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   235		if e != 0 {
   236			err = e
   237		}
   238		return
   239	}
   240	
   241	func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
   242		_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
   243		if e != 0 {
   244			err = e
   245		}
   246		return
   247	}
   248	
   249	func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
   250		_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
   251		if e != 0 {
   252			err = e
   253		}
   254		return
   255	}
   256	
   257	func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   258		_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   259		if e != 0 {
   260			err = e
   261		}
   262		return
   263	}
   264	
   265	func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
   266		_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
   267		if e != 0 {
   268			err = e
   269		}
   270		return
   271	}
   272	
   273	func socket(domain int, typ int, proto int) (fd int, err error) {
   274		fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
   275		if e != 0 {
   276			err = e
   277		}
   278		return
   279	}
   280	
   281	func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
   282		_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
   283		if e != 0 {
   284			err = e
   285		}
   286		return
   287	}
   288	
   289	func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
   290		_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
   291		if e != 0 {
   292			err = e
   293		}
   294		return
   295	}
   296	
   297	func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
   298		var base uintptr
   299		if len(p) > 0 {
   300			base = uintptr(unsafe.Pointer(&p[0]))
   301		}
   302		n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
   303		if e != 0 {
   304			err = e
   305		}
   306		return
   307	}
   308	
   309	func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
   310		var base uintptr
   311		if len(p) > 0 {
   312			base = uintptr(unsafe.Pointer(&p[0]))
   313		}
   314		_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
   315		if e != 0 {
   316			err = e
   317		}
   318		return
   319	}
   320	
   321	func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   322		n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
   323		if e != 0 {
   324			err = e
   325		}
   326		return
   327	}
   328	
   329	func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
   330		n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
   331		if e != 0 {
   332			err = e
   333		}
   334		return
   335	}
   336	
   337	func Listen(s int, n int) (err error) {
   338		_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
   339		if e != 0 {
   340			err = e
   341		}
   342		return
   343	}
   344	
   345	func Shutdown(s, how int) (err error) {
   346		_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
   347		if e != 0 {
   348			err = e
   349		}
   350		return
   351	}
   352	
   353	func Fstatfs(fd int, buf *Statfs_t) (err error) {
   354		_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   355		if e != 0 {
   356			err = e
   357		}
   358		return
   359	}
   360	
   361	func Statfs(path string, buf *Statfs_t) (err error) {
   362		pathp, err := BytePtrFromString(path)
   363		if err != nil {
   364			return err
   365		}
   366		_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
   367		if e != 0 {
   368			err = e
   369		}
   370		return
   371	}
   372	
   373	func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
   374	
   375	func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
   376	
   377	func (iov *Iovec) SetLen(length int) {
   378		iov.Len = uint32(length)
   379	}
   380	
   381	func (msghdr *Msghdr) SetControllen(length int) {
   382		msghdr.Controllen = uint32(length)
   383	}
   384	
   385	func (cmsg *Cmsghdr) SetLen(length int) {
   386		cmsg.Len = uint32(length)
   387	}
   388	
   389	func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno) {
   390		panic("not implemented")
   391	}
   392	

View as plain text