119 } |
156 } |
120 return string(buf[:n]), nil |
157 return string(buf[:n]), nil |
121 } |
158 } |
122 |
159 |
123 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { |
160 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { |
124 var _p0 unsafe.Pointer |
161 var ( |
125 var bufsize uintptr |
162 _p0 unsafe.Pointer |
|
163 bufsize uintptr |
|
164 oldBuf []statfs_freebsd11_t |
|
165 needsConvert bool |
|
166 ) |
|
167 |
126 if len(buf) > 0 { |
168 if len(buf) > 0 { |
127 _p0 = unsafe.Pointer(&buf[0]) |
169 if supportsABI(_ino64First) { |
128 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) |
170 _p0 = unsafe.Pointer(&buf[0]) |
129 } |
171 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) |
130 r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) |
172 } else { |
|
173 n := len(buf) |
|
174 oldBuf = make([]statfs_freebsd11_t, n) |
|
175 _p0 = unsafe.Pointer(&oldBuf[0]) |
|
176 bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n) |
|
177 needsConvert = true |
|
178 } |
|
179 } |
|
180 var sysno uintptr = SYS_GETFSSTAT |
|
181 if supportsABI(_ino64First) { |
|
182 sysno = SYS_GETFSSTAT_FREEBSD12 |
|
183 } |
|
184 r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags)) |
131 n = int(r0) |
185 n = int(r0) |
132 if e1 != 0 { |
186 if e1 != 0 { |
133 err = e1 |
187 err = e1 |
134 } |
188 } |
|
189 if e1 == 0 && needsConvert { |
|
190 for i := range oldBuf { |
|
191 buf[i].convertFrom(&oldBuf[i]) |
|
192 } |
|
193 } |
135 return |
194 return |
136 } |
195 } |
137 |
196 |
138 func setattrlistTimes(path string, times []Timespec, flags int) error { |
197 func setattrlistTimes(path string, times []Timespec, flags int) error { |
139 // used on Darwin for UtimesNano |
198 // used on Darwin for UtimesNano |
140 return ENOSYS |
199 return ENOSYS |
141 } |
200 } |
142 |
201 |
143 //sys ioctl(fd int, req uint, arg uintptr) (err error) |
202 //sys ioctl(fd int, req uint, arg uintptr) (err error) |
144 |
203 |
145 // ioctl itself should not be exposed directly, but additional get/set |
204 //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL |
146 // functions for specific types are permissible. |
|
147 |
|
148 // IoctlSetInt performs an ioctl operation which sets an integer value |
|
149 // on fd, using the specified request number. |
|
150 func IoctlSetInt(fd int, req uint, value int) error { |
|
151 return ioctl(fd, req, uintptr(value)) |
|
152 } |
|
153 |
|
154 func ioctlSetWinsize(fd int, req uint, value *Winsize) error { |
|
155 return ioctl(fd, req, uintptr(unsafe.Pointer(value))) |
|
156 } |
|
157 |
|
158 func ioctlSetTermios(fd int, req uint, value *Termios) error { |
|
159 return ioctl(fd, req, uintptr(unsafe.Pointer(value))) |
|
160 } |
|
161 |
|
162 // IoctlGetInt performs an ioctl operation which gets an integer value |
|
163 // from fd, using the specified request number. |
|
164 func IoctlGetInt(fd int, req uint) (int, error) { |
|
165 var value int |
|
166 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
|
167 return value, err |
|
168 } |
|
169 |
|
170 func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { |
|
171 var value Winsize |
|
172 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
|
173 return &value, err |
|
174 } |
|
175 |
|
176 func IoctlGetTermios(fd int, req uint) (*Termios, error) { |
|
177 var value Termios |
|
178 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
|
179 return &value, err |
|
180 } |
|
181 |
205 |
182 func Uname(uname *Utsname) error { |
206 func Uname(uname *Utsname) error { |
183 mib := []_C_int{CTL_KERN, KERN_OSTYPE} |
207 mib := []_C_int{CTL_KERN, KERN_OSTYPE} |
184 n := unsafe.Sizeof(uname.Sysname) |
208 n := unsafe.Sizeof(uname.Sysname) |
185 if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { |
209 if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { |
221 if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { |
245 if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { |
222 return err |
246 return err |
223 } |
247 } |
224 |
248 |
225 return nil |
249 return nil |
|
250 } |
|
251 |
|
252 func Stat(path string, st *Stat_t) (err error) { |
|
253 var oldStat stat_freebsd11_t |
|
254 if supportsABI(_ino64First) { |
|
255 return fstatat_freebsd12(AT_FDCWD, path, st, 0) |
|
256 } |
|
257 err = stat(path, &oldStat) |
|
258 if err != nil { |
|
259 return err |
|
260 } |
|
261 |
|
262 st.convertFrom(&oldStat) |
|
263 return nil |
|
264 } |
|
265 |
|
266 func Lstat(path string, st *Stat_t) (err error) { |
|
267 var oldStat stat_freebsd11_t |
|
268 if supportsABI(_ino64First) { |
|
269 return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW) |
|
270 } |
|
271 err = lstat(path, &oldStat) |
|
272 if err != nil { |
|
273 return err |
|
274 } |
|
275 |
|
276 st.convertFrom(&oldStat) |
|
277 return nil |
|
278 } |
|
279 |
|
280 func Fstat(fd int, st *Stat_t) (err error) { |
|
281 var oldStat stat_freebsd11_t |
|
282 if supportsABI(_ino64First) { |
|
283 return fstat_freebsd12(fd, st) |
|
284 } |
|
285 err = fstat(fd, &oldStat) |
|
286 if err != nil { |
|
287 return err |
|
288 } |
|
289 |
|
290 st.convertFrom(&oldStat) |
|
291 return nil |
|
292 } |
|
293 |
|
294 func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) { |
|
295 var oldStat stat_freebsd11_t |
|
296 if supportsABI(_ino64First) { |
|
297 return fstatat_freebsd12(fd, path, st, flags) |
|
298 } |
|
299 err = fstatat(fd, path, &oldStat, flags) |
|
300 if err != nil { |
|
301 return err |
|
302 } |
|
303 |
|
304 st.convertFrom(&oldStat) |
|
305 return nil |
|
306 } |
|
307 |
|
308 func Statfs(path string, st *Statfs_t) (err error) { |
|
309 var oldStatfs statfs_freebsd11_t |
|
310 if supportsABI(_ino64First) { |
|
311 return statfs_freebsd12(path, st) |
|
312 } |
|
313 err = statfs(path, &oldStatfs) |
|
314 if err != nil { |
|
315 return err |
|
316 } |
|
317 |
|
318 st.convertFrom(&oldStatfs) |
|
319 return nil |
|
320 } |
|
321 |
|
322 func Fstatfs(fd int, st *Statfs_t) (err error) { |
|
323 var oldStatfs statfs_freebsd11_t |
|
324 if supportsABI(_ino64First) { |
|
325 return fstatfs_freebsd12(fd, st) |
|
326 } |
|
327 err = fstatfs(fd, &oldStatfs) |
|
328 if err != nil { |
|
329 return err |
|
330 } |
|
331 |
|
332 st.convertFrom(&oldStatfs) |
|
333 return nil |
|
334 } |
|
335 |
|
336 func Getdents(fd int, buf []byte) (n int, err error) { |
|
337 return Getdirentries(fd, buf, nil) |
|
338 } |
|
339 |
|
340 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { |
|
341 if supportsABI(_ino64First) { |
|
342 if basep == nil || unsafe.Sizeof(*basep) == 8 { |
|
343 return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep))) |
|
344 } |
|
345 // The freebsd12 syscall needs a 64-bit base. On 32-bit machines |
|
346 // we can't just use the basep passed in. See #32498. |
|
347 var base uint64 = uint64(*basep) |
|
348 n, err = getdirentries_freebsd12(fd, buf, &base) |
|
349 *basep = uintptr(base) |
|
350 if base>>32 != 0 { |
|
351 // We can't stuff the base back into a uintptr, so any |
|
352 // future calls would be suspect. Generate an error. |
|
353 // EIO is allowed by getdirentries. |
|
354 err = EIO |
|
355 } |
|
356 return |
|
357 } |
|
358 |
|
359 // The old syscall entries are smaller than the new. Use 1/4 of the original |
|
360 // buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c). |
|
361 oldBufLen := roundup(len(buf)/4, _dirblksiz) |
|
362 oldBuf := make([]byte, oldBufLen) |
|
363 n, err = getdirentries(fd, oldBuf, basep) |
|
364 if err == nil && n > 0 { |
|
365 n = convertFromDirents11(buf, oldBuf[:n]) |
|
366 } |
|
367 return |
|
368 } |
|
369 |
|
370 func Mknod(path string, mode uint32, dev uint64) (err error) { |
|
371 var oldDev int |
|
372 if supportsABI(_ino64First) { |
|
373 return mknodat_freebsd12(AT_FDCWD, path, mode, dev) |
|
374 } |
|
375 oldDev = int(dev) |
|
376 return mknod(path, mode, oldDev) |
|
377 } |
|
378 |
|
379 func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) { |
|
380 var oldDev int |
|
381 if supportsABI(_ino64First) { |
|
382 return mknodat_freebsd12(fd, path, mode, dev) |
|
383 } |
|
384 oldDev = int(dev) |
|
385 return mknodat(fd, path, mode, oldDev) |
|
386 } |
|
387 |
|
388 // round x to the nearest multiple of y, larger or equal to x. |
|
389 // |
|
390 // from /usr/include/sys/param.h Macros for counting and rounding. |
|
391 // #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) |
|
392 func roundup(x, y int) int { |
|
393 return ((x + y - 1) / y) * y |
|
394 } |
|
395 |
|
396 func (s *Stat_t) convertFrom(old *stat_freebsd11_t) { |
|
397 *s = Stat_t{ |
|
398 Dev: uint64(old.Dev), |
|
399 Ino: uint64(old.Ino), |
|
400 Nlink: uint64(old.Nlink), |
|
401 Mode: old.Mode, |
|
402 Uid: old.Uid, |
|
403 Gid: old.Gid, |
|
404 Rdev: uint64(old.Rdev), |
|
405 Atim: old.Atim, |
|
406 Mtim: old.Mtim, |
|
407 Ctim: old.Ctim, |
|
408 Btim: old.Btim, |
|
409 Size: old.Size, |
|
410 Blocks: old.Blocks, |
|
411 Blksize: old.Blksize, |
|
412 Flags: old.Flags, |
|
413 Gen: uint64(old.Gen), |
|
414 } |
|
415 } |
|
416 |
|
417 func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) { |
|
418 *s = Statfs_t{ |
|
419 Version: _statfsVersion, |
|
420 Type: old.Type, |
|
421 Flags: old.Flags, |
|
422 Bsize: old.Bsize, |
|
423 Iosize: old.Iosize, |
|
424 Blocks: old.Blocks, |
|
425 Bfree: old.Bfree, |
|
426 Bavail: old.Bavail, |
|
427 Files: old.Files, |
|
428 Ffree: old.Ffree, |
|
429 Syncwrites: old.Syncwrites, |
|
430 Asyncwrites: old.Asyncwrites, |
|
431 Syncreads: old.Syncreads, |
|
432 Asyncreads: old.Asyncreads, |
|
433 // Spare |
|
434 Namemax: old.Namemax, |
|
435 Owner: old.Owner, |
|
436 Fsid: old.Fsid, |
|
437 // Charspare |
|
438 // Fstypename |
|
439 // Mntfromname |
|
440 // Mntonname |
|
441 } |
|
442 |
|
443 sl := old.Fstypename[:] |
|
444 n := clen(*(*[]byte)(unsafe.Pointer(&sl))) |
|
445 copy(s.Fstypename[:], old.Fstypename[:n]) |
|
446 |
|
447 sl = old.Mntfromname[:] |
|
448 n = clen(*(*[]byte)(unsafe.Pointer(&sl))) |
|
449 copy(s.Mntfromname[:], old.Mntfromname[:n]) |
|
450 |
|
451 sl = old.Mntonname[:] |
|
452 n = clen(*(*[]byte)(unsafe.Pointer(&sl))) |
|
453 copy(s.Mntonname[:], old.Mntonname[:n]) |
|
454 } |
|
455 |
|
456 func convertFromDirents11(buf []byte, old []byte) int { |
|
457 const ( |
|
458 fixedSize = int(unsafe.Offsetof(Dirent{}.Name)) |
|
459 oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name)) |
|
460 ) |
|
461 |
|
462 dstPos := 0 |
|
463 srcPos := 0 |
|
464 for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) { |
|
465 var dstDirent Dirent |
|
466 var srcDirent dirent_freebsd11 |
|
467 |
|
468 // If multiple direntries are written, sometimes when we reach the final one, |
|
469 // we may have cap of old less than size of dirent_freebsd11. |
|
470 copy((*[unsafe.Sizeof(srcDirent)]byte)(unsafe.Pointer(&srcDirent))[:], old[srcPos:]) |
|
471 |
|
472 reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8) |
|
473 if dstPos+reclen > len(buf) { |
|
474 break |
|
475 } |
|
476 |
|
477 dstDirent.Fileno = uint64(srcDirent.Fileno) |
|
478 dstDirent.Off = 0 |
|
479 dstDirent.Reclen = uint16(reclen) |
|
480 dstDirent.Type = srcDirent.Type |
|
481 dstDirent.Pad0 = 0 |
|
482 dstDirent.Namlen = uint16(srcDirent.Namlen) |
|
483 dstDirent.Pad1 = 0 |
|
484 |
|
485 copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen]) |
|
486 copy(buf[dstPos:], (*[unsafe.Sizeof(dstDirent)]byte)(unsafe.Pointer(&dstDirent))[:]) |
|
487 padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen] |
|
488 for i := range padding { |
|
489 padding[i] = 0 |
|
490 } |
|
491 |
|
492 dstPos += int(dstDirent.Reclen) |
|
493 srcPos += int(srcDirent.Reclen) |
|
494 } |
|
495 |
|
496 return dstPos |
|
497 } |
|
498 |
|
499 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
|
500 if raceenabled { |
|
501 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
|
502 } |
|
503 return sendfile(outfd, infd, offset, count) |
|
504 } |
|
505 |
|
506 //sys ptrace(request int, pid int, addr uintptr, data int) (err error) |
|
507 |
|
508 func PtraceAttach(pid int) (err error) { |
|
509 return ptrace(PTRACE_ATTACH, pid, 0, 0) |
|
510 } |
|
511 |
|
512 func PtraceCont(pid int, signal int) (err error) { |
|
513 return ptrace(PTRACE_CONT, pid, 1, signal) |
|
514 } |
|
515 |
|
516 func PtraceDetach(pid int) (err error) { |
|
517 return ptrace(PTRACE_DETACH, pid, 1, 0) |
|
518 } |
|
519 |
|
520 func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) { |
|
521 return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0) |
|
522 } |
|
523 |
|
524 func PtraceGetFsBase(pid int, fsbase *int64) (err error) { |
|
525 return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0) |
|
526 } |
|
527 |
|
528 func PtraceGetRegs(pid int, regsout *Reg) (err error) { |
|
529 return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0) |
|
530 } |
|
531 |
|
532 func PtraceLwpEvents(pid int, enable int) (err error) { |
|
533 return ptrace(PTRACE_LWPEVENTS, pid, 0, enable) |
|
534 } |
|
535 |
|
536 func PtraceLwpInfo(pid int, info uintptr) (err error) { |
|
537 return ptrace(PTRACE_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{}))) |
|
538 } |
|
539 |
|
540 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { |
|
541 return PtraceIO(PIOD_READ_D, pid, addr, out, SizeofLong) |
|
542 } |
|
543 |
|
544 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { |
|
545 return PtraceIO(PIOD_READ_I, pid, addr, out, SizeofLong) |
|
546 } |
|
547 |
|
548 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { |
|
549 return PtraceIO(PIOD_WRITE_D, pid, addr, data, SizeofLong) |
|
550 } |
|
551 |
|
552 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { |
|
553 return PtraceIO(PIOD_WRITE_I, pid, addr, data, SizeofLong) |
|
554 } |
|
555 |
|
556 func PtraceSetRegs(pid int, regs *Reg) (err error) { |
|
557 return ptrace(PTRACE_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0) |
|
558 } |
|
559 |
|
560 func PtraceSingleStep(pid int) (err error) { |
|
561 return ptrace(PTRACE_SINGLESTEP, pid, 1, 0) |
226 } |
562 } |
227 |
563 |
228 /* |
564 /* |
229 * Exposed directly |
565 * Exposed directly |
230 */ |
566 */ |
262 //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) |
598 //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) |
263 //sys Fchown(fd int, uid int, gid int) (err error) |
599 //sys Fchown(fd int, uid int, gid int) (err error) |
264 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) |
600 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) |
265 //sys Flock(fd int, how int) (err error) |
601 //sys Flock(fd int, how int) (err error) |
266 //sys Fpathconf(fd int, name int) (val int, err error) |
602 //sys Fpathconf(fd int, name int) (val int, err error) |
267 //sys Fstat(fd int, stat *Stat_t) (err error) |
603 //sys fstat(fd int, stat *stat_freebsd11_t) (err error) |
268 //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) |
604 //sys fstat_freebsd12(fd int, stat *Stat_t) (err error) |
269 //sys Fstatfs(fd int, stat *Statfs_t) (err error) |
605 //sys fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) |
|
606 //sys fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) |
|
607 //sys fstatfs(fd int, stat *statfs_freebsd11_t) (err error) |
|
608 //sys fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) |
270 //sys Fsync(fd int) (err error) |
609 //sys Fsync(fd int) (err error) |
271 //sys Ftruncate(fd int, length int64) (err error) |
610 //sys Ftruncate(fd int, length int64) (err error) |
272 //sys Getdents(fd int, buf []byte) (n int, err error) |
611 //sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) |
273 //sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) |
612 //sys getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) |
274 //sys Getdtablesize() (size int) |
613 //sys Getdtablesize() (size int) |
275 //sysnb Getegid() (egid int) |
614 //sysnb Getegid() (egid int) |
276 //sysnb Geteuid() (uid int) |
615 //sysnb Geteuid() (uid int) |
277 //sysnb Getgid() (gid int) |
616 //sysnb Getgid() (gid int) |
278 //sysnb Getpgid(pid int) (pgid int, err error) |
617 //sysnb Getpgid(pid int) (pgid int, err error) |
290 //sys Kqueue() (fd int, err error) |
629 //sys Kqueue() (fd int, err error) |
291 //sys Lchown(path string, uid int, gid int) (err error) |
630 //sys Lchown(path string, uid int, gid int) (err error) |
292 //sys Link(path string, link string) (err error) |
631 //sys Link(path string, link string) (err error) |
293 //sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) |
632 //sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) |
294 //sys Listen(s int, backlog int) (err error) |
633 //sys Listen(s int, backlog int) (err error) |
295 //sys Lstat(path string, stat *Stat_t) (err error) |
634 //sys lstat(path string, stat *stat_freebsd11_t) (err error) |
296 //sys Mkdir(path string, mode uint32) (err error) |
635 //sys Mkdir(path string, mode uint32) (err error) |
297 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) |
636 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) |
298 //sys Mkfifo(path string, mode uint32) (err error) |
637 //sys Mkfifo(path string, mode uint32) (err error) |
299 //sys Mknod(path string, mode uint32, dev int) (err error) |
638 //sys mknod(path string, mode uint32, dev int) (err error) |
|
639 //sys mknodat(fd int, path string, mode uint32, dev int) (err error) |
|
640 //sys mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) |
300 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) |
641 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) |
301 //sys Open(path string, mode int, perm uint32) (fd int, err error) |
642 //sys Open(path string, mode int, perm uint32) (fd int, err error) |
302 //sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) |
643 //sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) |
303 //sys Pathconf(path string, name int) (val int, err error) |
644 //sys Pathconf(path string, name int) (val int, err error) |
304 //sys Pread(fd int, p []byte, offset int64) (n int, err error) |
645 //sys Pread(fd int, p []byte, offset int64) (n int, err error) |