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