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