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