Source file
src/syscall/fs_wasip1.go
1
2
3
4
5
6
7 package syscall
8
9 import (
10 "internal/stringslite"
11 "runtime"
12 "unsafe"
13 )
14
15 func init() {
16
17
18
19
20
21
22
23
24 SetNonblock(0, true)
25 SetNonblock(1, true)
26 SetNonblock(2, true)
27 }
28
29 type uintptr32 = uint32
30 type size = uint32
31 type fdflags = uint32
32 type filesize = uint64
33 type filetype = uint8
34 type lookupflags = uint32
35 type oflags = uint32
36 type rights = uint64
37 type timestamp = uint64
38 type dircookie = uint64
39 type filedelta = int64
40 type fstflags = uint32
41
42 type iovec struct {
43 buf uintptr32
44 bufLen size
45 }
46
47 const (
48 LOOKUP_SYMLINK_FOLLOW = 0x00000001
49 )
50
51 const (
52 OFLAG_CREATE = 0x0001
53 OFLAG_DIRECTORY = 0x0002
54 OFLAG_EXCL = 0x0004
55 OFLAG_TRUNC = 0x0008
56 )
57
58 const (
59 FDFLAG_APPEND = 0x0001
60 FDFLAG_DSYNC = 0x0002
61 FDFLAG_NONBLOCK = 0x0004
62 FDFLAG_RSYNC = 0x0008
63 FDFLAG_SYNC = 0x0010
64 )
65
66 const (
67 RIGHT_FD_DATASYNC = 1 << iota
68 RIGHT_FD_READ
69 RIGHT_FD_SEEK
70 RIGHT_FDSTAT_SET_FLAGS
71 RIGHT_FD_SYNC
72 RIGHT_FD_TELL
73 RIGHT_FD_WRITE
74 RIGHT_FD_ADVISE
75 RIGHT_FD_ALLOCATE
76 RIGHT_PATH_CREATE_DIRECTORY
77 RIGHT_PATH_CREATE_FILE
78 RIGHT_PATH_LINK_SOURCE
79 RIGHT_PATH_LINK_TARGET
80 RIGHT_PATH_OPEN
81 RIGHT_FD_READDIR
82 RIGHT_PATH_READLINK
83 RIGHT_PATH_RENAME_SOURCE
84 RIGHT_PATH_RENAME_TARGET
85 RIGHT_PATH_FILESTAT_GET
86 RIGHT_PATH_FILESTAT_SET_SIZE
87 RIGHT_PATH_FILESTAT_SET_TIMES
88 RIGHT_FD_FILESTAT_GET
89 RIGHT_FD_FILESTAT_SET_SIZE
90 RIGHT_FD_FILESTAT_SET_TIMES
91 RIGHT_PATH_SYMLINK
92 RIGHT_PATH_REMOVE_DIRECTORY
93 RIGHT_PATH_UNLINK_FILE
94 RIGHT_POLL_FD_READWRITE
95 RIGHT_SOCK_SHUTDOWN
96 RIGHT_SOCK_ACCEPT
97 )
98
99 const (
100 WHENCE_SET = 0
101 WHENCE_CUR = 1
102 WHENCE_END = 2
103 )
104
105 const (
106 FILESTAT_SET_ATIM = 0x0001
107 FILESTAT_SET_ATIM_NOW = 0x0002
108 FILESTAT_SET_MTIM = 0x0004
109 FILESTAT_SET_MTIM_NOW = 0x0008
110 )
111
112 const (
113
114
115 fullRights = rights(^uint32(0))
116 readRights = rights(RIGHT_FD_READ | RIGHT_FD_READDIR)
117 writeRights = rights(RIGHT_FD_DATASYNC | RIGHT_FD_WRITE | RIGHT_FD_ALLOCATE | RIGHT_PATH_FILESTAT_SET_SIZE)
118
119
120
121
122
123 fileRights rights = RIGHT_FD_DATASYNC |
124 RIGHT_FD_READ |
125 RIGHT_FD_SEEK |
126 RIGHT_FDSTAT_SET_FLAGS |
127 RIGHT_FD_SYNC |
128 RIGHT_FD_TELL |
129 RIGHT_FD_WRITE |
130 RIGHT_FD_ADVISE |
131 RIGHT_FD_ALLOCATE |
132 RIGHT_PATH_CREATE_DIRECTORY |
133 RIGHT_PATH_CREATE_FILE |
134 RIGHT_PATH_LINK_SOURCE |
135 RIGHT_PATH_LINK_TARGET |
136 RIGHT_PATH_OPEN |
137 RIGHT_FD_READDIR |
138 RIGHT_PATH_READLINK |
139 RIGHT_PATH_RENAME_SOURCE |
140 RIGHT_PATH_RENAME_TARGET |
141 RIGHT_PATH_FILESTAT_GET |
142 RIGHT_PATH_FILESTAT_SET_SIZE |
143 RIGHT_PATH_FILESTAT_SET_TIMES |
144 RIGHT_FD_FILESTAT_GET |
145 RIGHT_FD_FILESTAT_SET_SIZE |
146 RIGHT_FD_FILESTAT_SET_TIMES |
147 RIGHT_PATH_SYMLINK |
148 RIGHT_PATH_REMOVE_DIRECTORY |
149 RIGHT_PATH_UNLINK_FILE |
150 RIGHT_POLL_FD_READWRITE
151
152
153
154
155 dirRights rights = RIGHT_FD_SEEK |
156 RIGHT_FDSTAT_SET_FLAGS |
157 RIGHT_FD_SYNC |
158 RIGHT_PATH_CREATE_DIRECTORY |
159 RIGHT_PATH_CREATE_FILE |
160 RIGHT_PATH_LINK_SOURCE |
161 RIGHT_PATH_LINK_TARGET |
162 RIGHT_PATH_OPEN |
163 RIGHT_FD_READDIR |
164 RIGHT_PATH_READLINK |
165 RIGHT_PATH_RENAME_SOURCE |
166 RIGHT_PATH_RENAME_TARGET |
167 RIGHT_PATH_FILESTAT_GET |
168 RIGHT_PATH_FILESTAT_SET_SIZE |
169 RIGHT_PATH_FILESTAT_SET_TIMES |
170 RIGHT_FD_FILESTAT_GET |
171 RIGHT_FD_FILESTAT_SET_TIMES |
172 RIGHT_PATH_SYMLINK |
173 RIGHT_PATH_REMOVE_DIRECTORY |
174 RIGHT_PATH_UNLINK_FILE
175 )
176
177
178
179
180
181 func fd_close(fd int32) Errno
182
183
184
185
186
187 func fd_filestat_set_size(fd int32, set_size filesize) Errno
188
189
190
191
192
193 func fd_pread(fd int32, iovs unsafe.Pointer, iovsLen size, offset filesize, nread unsafe.Pointer) Errno
194
195
196
197 func fd_pwrite(fd int32, iovs unsafe.Pointer, iovsLen size, offset filesize, nwritten unsafe.Pointer) Errno
198
199
200
201 func fd_read(fd int32, iovs unsafe.Pointer, iovsLen size, nread unsafe.Pointer) Errno
202
203
204
205 func fd_readdir(fd int32, buf unsafe.Pointer, bufLen size, cookie dircookie, nwritten unsafe.Pointer) Errno
206
207
208
209 func fd_seek(fd int32, offset filedelta, whence uint32, newoffset unsafe.Pointer) Errno
210
211
212
213
214
215 func fd_fdstat_set_rights(fd int32, rightsBase rights, rightsInheriting rights) Errno
216
217
218
219 func fd_filestat_get(fd int32, buf unsafe.Pointer) Errno
220
221
222
223 func fd_write(fd int32, iovs unsafe.Pointer, iovsLen size, nwritten unsafe.Pointer) Errno
224
225
226
227 func fd_sync(fd int32) Errno
228
229
230
231 func path_create_directory(fd int32, path unsafe.Pointer, pathLen size) Errno
232
233
234
235 func path_filestat_get(fd int32, flags lookupflags, path unsafe.Pointer, pathLen size, buf unsafe.Pointer) Errno
236
237
238
239 func path_filestat_set_times(fd int32, flags lookupflags, path unsafe.Pointer, pathLen size, atim timestamp, mtim timestamp, fstflags fstflags) Errno
240
241
242
243 func path_link(oldFd int32, oldFlags lookupflags, oldPath unsafe.Pointer, oldPathLen size, newFd int32, newPath unsafe.Pointer, newPathLen size) Errno
244
245
246
247 func path_readlink(fd int32, path unsafe.Pointer, pathLen size, buf unsafe.Pointer, bufLen size, nwritten unsafe.Pointer) Errno
248
249
250
251 func path_remove_directory(fd int32, path unsafe.Pointer, pathLen size) Errno
252
253
254
255 func path_rename(oldFd int32, oldPath unsafe.Pointer, oldPathLen size, newFd int32, newPath unsafe.Pointer, newPathLen size) Errno
256
257
258
259 func path_symlink(oldPath unsafe.Pointer, oldPathLen size, fd int32, newPath unsafe.Pointer, newPathLen size) Errno
260
261
262
263 func path_unlink_file(fd int32, path unsafe.Pointer, pathLen size) Errno
264
265
266
267 func path_open(rootFD int32, dirflags lookupflags, path unsafe.Pointer, pathLen size, oflags oflags, fsRightsBase rights, fsRightsInheriting rights, fsFlags fdflags, fd unsafe.Pointer) Errno
268
269
270
271 func random_get(buf unsafe.Pointer, bufLen size) Errno
272
273
274
275
276 type fdstat struct {
277 filetype filetype
278 fdflags uint16
279 rightsBase rights
280 rightsInheriting rights
281 }
282
283
284
285 func fd_fdstat_get(fd int32, buf unsafe.Pointer) Errno
286
287
288
289 func fd_fdstat_set_flags(fd int32, flags fdflags) Errno
290
291 func fd_fdstat_get_flags(fd int) (uint32, error) {
292 var stat fdstat
293 errno := fd_fdstat_get(int32(fd), unsafe.Pointer(&stat))
294 return uint32(stat.fdflags), errnoErr(errno)
295 }
296
297 func fd_fdstat_get_type(fd int) (uint8, error) {
298 var stat fdstat
299 errno := fd_fdstat_get(int32(fd), unsafe.Pointer(&stat))
300 return stat.filetype, errnoErr(errno)
301 }
302
303 type preopentype = uint8
304
305 const (
306 preopentypeDir preopentype = iota
307 )
308
309 type prestatDir struct {
310 prNameLen size
311 }
312
313 type prestat struct {
314 typ preopentype
315 dir prestatDir
316 }
317
318
319
320 func fd_prestat_get(fd int32, prestat unsafe.Pointer) Errno
321
322
323
324 func fd_prestat_dir_name(fd int32, path unsafe.Pointer, pathLen size) Errno
325
326 type opendir struct {
327 fd int32
328 name string
329 }
330
331
332
333
334 var preopens []opendir
335
336
337
338
339
340
341
342 var cwd string
343
344 func init() {
345 dirNameBuf := make([]byte, 256)
346
347
348 for preopenFd := int32(3); ; preopenFd++ {
349 var prestat prestat
350
351 errno := fd_prestat_get(preopenFd, unsafe.Pointer(&prestat))
352 if errno == EBADF {
353 break
354 }
355 if errno == ENOTDIR || prestat.typ != preopentypeDir {
356 continue
357 }
358 if errno != 0 {
359 panic("fd_prestat: " + errno.Error())
360 }
361 if int(prestat.dir.prNameLen) > len(dirNameBuf) {
362 dirNameBuf = make([]byte, prestat.dir.prNameLen)
363 }
364
365 errno = fd_prestat_dir_name(preopenFd, unsafe.Pointer(&dirNameBuf[0]), prestat.dir.prNameLen)
366 if errno != 0 {
367 panic("fd_prestat_dir_name: " + errno.Error())
368 }
369
370 preopens = append(preopens, opendir{
371 fd: preopenFd,
372 name: string(dirNameBuf[:prestat.dir.prNameLen]),
373 })
374 }
375
376 if cwd, _ = Getenv("PWD"); cwd != "" {
377 cwd = joinPath("/", cwd)
378 } else if len(preopens) > 0 {
379 cwd = preopens[0].name
380 }
381 }
382
383
384 func now() (sec int64, nsec int32)
385
386
387 func appendCleanPath(buf []byte, path string, lookupParent bool) ([]byte, bool) {
388 i := 0
389 for i < len(path) {
390 for i < len(path) && path[i] == '/' {
391 i++
392 }
393
394 j := i
395 for j < len(path) && path[j] != '/' {
396 j++
397 }
398
399 s := path[i:j]
400 i = j
401
402 switch s {
403 case "":
404 continue
405 case ".":
406 continue
407 case "..":
408 if !lookupParent {
409 k := len(buf)
410 for k > 0 && buf[k-1] != '/' {
411 k--
412 }
413 for k > 1 && buf[k-1] == '/' {
414 k--
415 }
416 buf = buf[:k]
417 if k == 0 {
418 lookupParent = true
419 } else {
420 s = ""
421 continue
422 }
423 }
424 default:
425 lookupParent = false
426 }
427
428 if len(buf) > 0 && buf[len(buf)-1] != '/' {
429 buf = append(buf, '/')
430 }
431 buf = append(buf, s...)
432 }
433 return buf, lookupParent
434 }
435
436
437
438
439
440
441
442
443
444
445
446
447
448 func joinPath(dir, file string) string {
449 buf := make([]byte, 0, len(dir)+len(file)+1)
450 if isAbs(dir) {
451 buf = append(buf, '/')
452 }
453 buf, lookupParent := appendCleanPath(buf, dir, false)
454 buf, _ = appendCleanPath(buf, file, lookupParent)
455
456
457
458
459 if len(buf) == 0 {
460 buf = append(buf, '.')
461 }
462
463
464
465 if buf[len(buf)-1] != '/' && isDir(file) {
466 buf = append(buf, '/')
467 }
468 return unsafe.String(&buf[0], len(buf))
469 }
470
471 func isAbs(path string) bool {
472 return stringslite.HasPrefix(path, "/")
473 }
474
475 func isDir(path string) bool {
476 return stringslite.HasSuffix(path, "/")
477 }
478
479
480
481
482
483
484
485 func preparePath(path string) (int32, unsafe.Pointer, size) {
486 var dirFd = int32(-1)
487 var dirName string
488
489 dir := "/"
490 if !isAbs(path) {
491 dir = cwd
492 }
493 path = joinPath(dir, path)
494
495 for _, p := range preopens {
496 if len(p.name) > len(dirName) && stringslite.HasPrefix(path, p.name) {
497 dirFd, dirName = p.fd, p.name
498 }
499 }
500
501 path = path[len(dirName):]
502 for isAbs(path) {
503 path = path[1:]
504 }
505 if len(path) == 0 {
506 path = "."
507 }
508
509 return dirFd, stringPointer(path), size(len(path))
510 }
511
512 func Open(path string, openmode int, perm uint32) (int, error) {
513 if path == "" {
514 return -1, EINVAL
515 }
516 dirFd, pathPtr, pathLen := preparePath(path)
517
518 var oflags oflags
519 if (openmode & O_CREATE) != 0 {
520 oflags |= OFLAG_CREATE
521 }
522 if (openmode & O_TRUNC) != 0 {
523 oflags |= OFLAG_TRUNC
524 }
525 if (openmode & O_EXCL) != 0 {
526 oflags |= OFLAG_EXCL
527 }
528
529 var rights rights
530 switch openmode & (O_RDONLY | O_WRONLY | O_RDWR) {
531 case O_RDONLY:
532 rights = fileRights & ^writeRights
533 case O_WRONLY:
534 rights = fileRights & ^readRights
535 case O_RDWR:
536 rights = fileRights
537 }
538
539 var fdflags fdflags
540 if (openmode & O_APPEND) != 0 {
541 fdflags |= FDFLAG_APPEND
542 }
543 if (openmode & O_SYNC) != 0 {
544 fdflags |= FDFLAG_SYNC
545 }
546
547 var fd int32
548 errno := path_open(
549 dirFd,
550 LOOKUP_SYMLINK_FOLLOW,
551 pathPtr,
552 pathLen,
553 oflags,
554 rights,
555 fileRights,
556 fdflags,
557 unsafe.Pointer(&fd),
558 )
559 if errno == EISDIR && oflags == 0 && fdflags == 0 && ((rights & writeRights) == 0) {
560
561
562
563
564
565
566
567
568
569 errno = path_open(
570 dirFd,
571 LOOKUP_SYMLINK_FOLLOW,
572 pathPtr,
573 pathLen,
574 oflags|OFLAG_DIRECTORY,
575 rights&dirRights,
576 fileRights,
577 fdflags,
578 unsafe.Pointer(&fd),
579 )
580 }
581 return int(fd), errnoErr(errno)
582 }
583
584 func Close(fd int) error {
585 errno := fd_close(int32(fd))
586 return errnoErr(errno)
587 }
588
589 func CloseOnExec(fd int) {
590
591 }
592
593 func Mkdir(path string, perm uint32) error {
594 if path == "" {
595 return EINVAL
596 }
597 dirFd, pathPtr, pathLen := preparePath(path)
598 errno := path_create_directory(dirFd, pathPtr, pathLen)
599 return errnoErr(errno)
600 }
601
602 func ReadDir(fd int, buf []byte, cookie dircookie) (int, error) {
603 var nwritten size
604 errno := fd_readdir(int32(fd), unsafe.Pointer(&buf[0]), size(len(buf)), cookie, unsafe.Pointer(&nwritten))
605 return int(nwritten), errnoErr(errno)
606 }
607
608 type Stat_t struct {
609 Dev uint64
610 Ino uint64
611 Filetype uint8
612 Nlink uint64
613 Size uint64
614 Atime uint64
615 Mtime uint64
616 Ctime uint64
617
618 Mode int
619
620
621 Uid uint32
622 Gid uint32
623 }
624
625 func Stat(path string, st *Stat_t) error {
626 if path == "" {
627 return EINVAL
628 }
629 dirFd, pathPtr, pathLen := preparePath(path)
630 errno := path_filestat_get(dirFd, LOOKUP_SYMLINK_FOLLOW, pathPtr, pathLen, unsafe.Pointer(st))
631 setDefaultMode(st)
632 return errnoErr(errno)
633 }
634
635 func Lstat(path string, st *Stat_t) error {
636 if path == "" {
637 return EINVAL
638 }
639 dirFd, pathPtr, pathLen := preparePath(path)
640 errno := path_filestat_get(dirFd, 0, pathPtr, pathLen, unsafe.Pointer(st))
641 setDefaultMode(st)
642 return errnoErr(errno)
643 }
644
645 func Fstat(fd int, st *Stat_t) error {
646 errno := fd_filestat_get(int32(fd), unsafe.Pointer(st))
647 setDefaultMode(st)
648 return errnoErr(errno)
649 }
650
651 func setDefaultMode(st *Stat_t) {
652
653
654
655 if st.Filetype == FILETYPE_DIRECTORY {
656 st.Mode = 0700
657 } else {
658 st.Mode = 0600
659 }
660 }
661
662 func Unlink(path string) error {
663 if path == "" {
664 return EINVAL
665 }
666 dirFd, pathPtr, pathLen := preparePath(path)
667 errno := path_unlink_file(dirFd, pathPtr, pathLen)
668 return errnoErr(errno)
669 }
670
671 func Rmdir(path string) error {
672 if path == "" {
673 return EINVAL
674 }
675 dirFd, pathPtr, pathLen := preparePath(path)
676 errno := path_remove_directory(dirFd, pathPtr, pathLen)
677 return errnoErr(errno)
678 }
679
680 func Chmod(path string, mode uint32) error {
681 var stat Stat_t
682 return Stat(path, &stat)
683 }
684
685 func Fchmod(fd int, mode uint32) error {
686 var stat Stat_t
687 return Fstat(fd, &stat)
688 }
689
690 func Chown(path string, uid, gid int) error {
691 return ENOSYS
692 }
693
694 func Fchown(fd int, uid, gid int) error {
695 return ENOSYS
696 }
697
698 func Lchown(path string, uid, gid int) error {
699 return ENOSYS
700 }
701
702 func UtimesNano(path string, ts []Timespec) error {
703
704 const UTIME_OMIT = -0x2
705 if path == "" {
706 return EINVAL
707 }
708 dirFd, pathPtr, pathLen := preparePath(path)
709 atime := TimespecToNsec(ts[0])
710 mtime := TimespecToNsec(ts[1])
711 if ts[0].Nsec == UTIME_OMIT || ts[1].Nsec == UTIME_OMIT {
712 var st Stat_t
713 if err := Stat(path, &st); err != nil {
714 return err
715 }
716 if ts[0].Nsec == UTIME_OMIT {
717 atime = int64(st.Atime)
718 }
719 if ts[1].Nsec == UTIME_OMIT {
720 mtime = int64(st.Mtime)
721 }
722 }
723 errno := path_filestat_set_times(
724 dirFd,
725 LOOKUP_SYMLINK_FOLLOW,
726 pathPtr,
727 pathLen,
728 timestamp(atime),
729 timestamp(mtime),
730 FILESTAT_SET_ATIM|FILESTAT_SET_MTIM,
731 )
732 return errnoErr(errno)
733 }
734
735 func Rename(from, to string) error {
736 if from == "" || to == "" {
737 return EINVAL
738 }
739 oldDirFd, oldPathPtr, oldPathLen := preparePath(from)
740 newDirFd, newPathPtr, newPathLen := preparePath(to)
741 errno := path_rename(
742 oldDirFd,
743 oldPathPtr,
744 oldPathLen,
745 newDirFd,
746 newPathPtr,
747 newPathLen,
748 )
749 return errnoErr(errno)
750 }
751
752 func Truncate(path string, length int64) error {
753 if path == "" {
754 return EINVAL
755 }
756 fd, err := Open(path, O_WRONLY, 0)
757 if err != nil {
758 return err
759 }
760 defer Close(fd)
761 return Ftruncate(fd, length)
762 }
763
764 func Ftruncate(fd int, length int64) error {
765 errno := fd_filestat_set_size(int32(fd), filesize(length))
766 return errnoErr(errno)
767 }
768
769 const ImplementsGetwd = true
770
771 func Getwd() (string, error) {
772 return cwd, nil
773 }
774
775 func Chdir(path string) error {
776 if path == "" {
777 return EINVAL
778 }
779
780 dir := "/"
781 if !isAbs(path) {
782 dir = cwd
783 }
784 path = joinPath(dir, path)
785
786 var stat Stat_t
787 dirFd, pathPtr, pathLen := preparePath(path)
788 errno := path_filestat_get(dirFd, LOOKUP_SYMLINK_FOLLOW, pathPtr, pathLen, unsafe.Pointer(&stat))
789 if errno != 0 {
790 return errnoErr(errno)
791 }
792 if stat.Filetype != FILETYPE_DIRECTORY {
793 return ENOTDIR
794 }
795 cwd = path
796 return nil
797 }
798
799 func Readlink(path string, buf []byte) (n int, err error) {
800 if path == "" {
801 return 0, EINVAL
802 }
803 if len(buf) == 0 {
804 return 0, nil
805 }
806 dirFd, pathPtr, pathLen := preparePath(path)
807 var nwritten size
808 errno := path_readlink(
809 dirFd,
810 pathPtr,
811 pathLen,
812 unsafe.Pointer(&buf[0]),
813 size(len(buf)),
814 unsafe.Pointer(&nwritten),
815 )
816
817
818
819
820
821 return int(nwritten), errnoErr(errno)
822 }
823
824 func Link(path, link string) error {
825 if path == "" || link == "" {
826 return EINVAL
827 }
828 oldDirFd, oldPathPtr, oldPathLen := preparePath(path)
829 newDirFd, newPathPtr, newPathLen := preparePath(link)
830 errno := path_link(
831 oldDirFd,
832 0,
833 oldPathPtr,
834 oldPathLen,
835 newDirFd,
836 newPathPtr,
837 newPathLen,
838 )
839 return errnoErr(errno)
840 }
841
842 func Symlink(path, link string) error {
843 if path == "" || link == "" {
844 return EINVAL
845 }
846 dirFd, pathPtr, pathlen := preparePath(link)
847 errno := path_symlink(
848 stringPointer(path),
849 size(len(path)),
850 dirFd,
851 pathPtr,
852 pathlen,
853 )
854 return errnoErr(errno)
855 }
856
857 func Fsync(fd int) error {
858 errno := fd_sync(int32(fd))
859 return errnoErr(errno)
860 }
861
862 func bytesPointer(b []byte) unsafe.Pointer {
863 return unsafe.Pointer(unsafe.SliceData(b))
864 }
865
866 func stringPointer(s string) unsafe.Pointer {
867 return unsafe.Pointer(unsafe.StringData(s))
868 }
869
870 func makeIOVec(b []byte) unsafe.Pointer {
871 return unsafe.Pointer(&iovec{
872 buf: uintptr32(uintptr(bytesPointer(b))),
873 bufLen: size(len(b)),
874 })
875 }
876
877 func Read(fd int, b []byte) (int, error) {
878 var nread size
879 errno := fd_read(int32(fd), makeIOVec(b), 1, unsafe.Pointer(&nread))
880 runtime.KeepAlive(b)
881 return int(nread), errnoErr(errno)
882 }
883
884 func Write(fd int, b []byte) (int, error) {
885 var nwritten size
886 errno := fd_write(int32(fd), makeIOVec(b), 1, unsafe.Pointer(&nwritten))
887 runtime.KeepAlive(b)
888 return int(nwritten), errnoErr(errno)
889 }
890
891 func Pread(fd int, b []byte, offset int64) (int, error) {
892 var nread size
893 errno := fd_pread(int32(fd), makeIOVec(b), 1, filesize(offset), unsafe.Pointer(&nread))
894 runtime.KeepAlive(b)
895 return int(nread), errnoErr(errno)
896 }
897
898 func Pwrite(fd int, b []byte, offset int64) (int, error) {
899 var nwritten size
900 errno := fd_pwrite(int32(fd), makeIOVec(b), 1, filesize(offset), unsafe.Pointer(&nwritten))
901 runtime.KeepAlive(b)
902 return int(nwritten), errnoErr(errno)
903 }
904
905 func Seek(fd int, offset int64, whence int) (int64, error) {
906 var newoffset filesize
907 errno := fd_seek(int32(fd), filedelta(offset), uint32(whence), unsafe.Pointer(&newoffset))
908 return int64(newoffset), errnoErr(errno)
909 }
910
911 func Dup(fd int) (int, error) {
912 return 0, ENOSYS
913 }
914
915 func Dup2(fd, newfd int) error {
916 return ENOSYS
917 }
918
919 func Pipe(fd []int) error {
920 return ENOSYS
921 }
922
923 func RandomGet(b []byte) error {
924 errno := random_get(bytesPointer(b), size(len(b)))
925 return errnoErr(errno)
926 }
927
View as plain text