diff options
| author | YDBot <[email protected]> | 2026-06-10 06:27:27 +0000 |
|---|---|---|
| committer | YDBot <[email protected]> | 2026-06-10 06:27:27 +0000 |
| commit | eb8c7d3ee0c13034ecf5d8d35c24cefc40f0bb3f (patch) | |
| tree | a1eba7fec49a258bb24bfa77808233496ac0047f /contrib/go/_std_1.25/src/syscall/fs_js.go | |
| parent | c4011885693f041c96b035f368aae8a1baac8885 (diff) | |
| parent | 72cfbf8958fa6fa5227e9ad6466abfc635fdeb15 (diff) | |
Diffstat (limited to 'contrib/go/_std_1.25/src/syscall/fs_js.go')
| -rw-r--r-- | contrib/go/_std_1.25/src/syscall/fs_js.go | 586 |
1 files changed, 0 insertions, 586 deletions
diff --git a/contrib/go/_std_1.25/src/syscall/fs_js.go b/contrib/go/_std_1.25/src/syscall/fs_js.go deleted file mode 100644 index 7ef3cdee14a..00000000000 --- a/contrib/go/_std_1.25/src/syscall/fs_js.go +++ /dev/null @@ -1,586 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build js && wasm - -package syscall - -import ( - "errors" - "sync" - "syscall/js" -) - -// Provided by package runtime. -func now() (sec int64, nsec int32) - -var jsProcess = js.Global().Get("process") -var jsPath = js.Global().Get("path") -var jsFS = js.Global().Get("fs") -var constants = jsFS.Get("constants") - -var uint8Array = js.Global().Get("Uint8Array") - -var ( - nodeWRONLY = constants.Get("O_WRONLY").Int() - nodeRDWR = constants.Get("O_RDWR").Int() - nodeCREATE = constants.Get("O_CREAT").Int() - nodeTRUNC = constants.Get("O_TRUNC").Int() - nodeAPPEND = constants.Get("O_APPEND").Int() - nodeEXCL = constants.Get("O_EXCL").Int() - - // NodeJS on Windows does not support O_DIRECTORY, so we default - // to -1 and assign it in init if available. - // See https://nodejs.org/docs/latest/api/fs.html#file-open-constants. - nodeDIRECTORY = -1 -) - -func init() { - oDir := constants.Get("O_DIRECTORY") - if !oDir.IsUndefined() { - nodeDIRECTORY = oDir.Int() - } -} - -type jsFile struct { - path string - entries []string - dirIdx int // entries[:dirIdx] have already been returned in ReadDirent - pos int64 - seeked bool -} - -var filesMu sync.Mutex -var files = map[int]*jsFile{ - 0: {}, - 1: {}, - 2: {}, -} - -func fdToFile(fd int) (*jsFile, error) { - filesMu.Lock() - f, ok := files[fd] - filesMu.Unlock() - if !ok { - return nil, EBADF - } - return f, nil -} - -func Open(path string, openmode int, perm uint32) (int, error) { - if err := checkPath(path); err != nil { - return 0, err - } - - flags := 0 - if openmode&O_WRONLY != 0 { - flags |= nodeWRONLY - } - if openmode&O_RDWR != 0 { - flags |= nodeRDWR - } - if openmode&O_CREATE != 0 { - flags |= nodeCREATE - } - if openmode&O_TRUNC != 0 { - flags |= nodeTRUNC - } - if openmode&O_APPEND != 0 { - flags |= nodeAPPEND - } - if openmode&O_EXCL != 0 { - flags |= nodeEXCL - } - if openmode&O_SYNC != 0 { - return 0, errors.New("syscall.Open: O_SYNC is not supported by js/wasm") - } - if openmode&O_DIRECTORY != 0 { - if nodeDIRECTORY != -1 { - flags |= nodeDIRECTORY - } else { - return 0, errors.New("syscall.Open: O_DIRECTORY is not supported on Windows") - } - } - - jsFD, err := fsCall("open", path, flags, perm) - if err != nil { - return 0, err - } - fd := jsFD.Int() - - var entries []string - if stat, err := fsCall("fstat", fd); err == nil && stat.Call("isDirectory").Bool() { - dir, err := fsCall("readdir", path) - if err != nil { - return 0, err - } - entries = make([]string, dir.Length()) - for i := range entries { - entries[i] = dir.Index(i).String() - } - } - - path = jsPath.Call("resolve", path).String() - - f := &jsFile{ - path: path, - entries: entries, - } - filesMu.Lock() - files[fd] = f - filesMu.Unlock() - return fd, nil -} - -func Close(fd int) error { - filesMu.Lock() - delete(files, fd) - filesMu.Unlock() - _, err := fsCall("close", fd) - return err -} - -func CloseOnExec(fd int) { - // nothing to do - no exec -} - -func Mkdir(path string, perm uint32) error { - if err := checkPath(path); err != nil { - return err - } - _, err := fsCall("mkdir", path, perm) - return err -} - -func ReadDirent(fd int, buf []byte) (int, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - if f.entries == nil { - return 0, EINVAL - } - - n := 0 - for f.dirIdx < len(f.entries) { - entry := f.entries[f.dirIdx] - l := 2 + len(entry) - if l > len(buf) { - break - } - buf[0] = byte(l) - buf[1] = byte(l >> 8) - copy(buf[2:], entry) - buf = buf[l:] - n += l - f.dirIdx++ - } - - return n, nil -} - -func setStat(st *Stat_t, jsSt js.Value) { - st.Dev = int64(jsSt.Get("dev").Int()) - st.Ino = uint64(jsSt.Get("ino").Int()) - st.Mode = uint32(jsSt.Get("mode").Int()) - st.Nlink = uint32(jsSt.Get("nlink").Int()) - st.Uid = uint32(jsSt.Get("uid").Int()) - st.Gid = uint32(jsSt.Get("gid").Int()) - st.Rdev = int64(jsSt.Get("rdev").Int()) - st.Size = int64(jsSt.Get("size").Int()) - st.Blksize = int32(jsSt.Get("blksize").Int()) - st.Blocks = int32(jsSt.Get("blocks").Int()) - atime := int64(jsSt.Get("atimeMs").Int()) - st.Atime = atime / 1000 - st.AtimeNsec = (atime % 1000) * 1000000 - mtime := int64(jsSt.Get("mtimeMs").Int()) - st.Mtime = mtime / 1000 - st.MtimeNsec = (mtime % 1000) * 1000000 - ctime := int64(jsSt.Get("ctimeMs").Int()) - st.Ctime = ctime / 1000 - st.CtimeNsec = (ctime % 1000) * 1000000 -} - -func Stat(path string, st *Stat_t) error { - if err := checkPath(path); err != nil { - return err - } - jsSt, err := fsCall("stat", path) - if err != nil { - return err - } - setStat(st, jsSt) - return nil -} - -func Lstat(path string, st *Stat_t) error { - if err := checkPath(path); err != nil { - return err - } - jsSt, err := fsCall("lstat", path) - if err != nil { - return err - } - setStat(st, jsSt) - return nil -} - -func Fstat(fd int, st *Stat_t) error { - jsSt, err := fsCall("fstat", fd) - if err != nil { - return err - } - setStat(st, jsSt) - return nil -} - -func Unlink(path string) error { - if err := checkPath(path); err != nil { - return err - } - _, err := fsCall("unlink", path) - return err -} - -func Rmdir(path string) error { - if err := checkPath(path); err != nil { - return err - } - _, err := fsCall("rmdir", path) - return err -} - -func Chmod(path string, mode uint32) error { - if err := checkPath(path); err != nil { - return err - } - _, err := fsCall("chmod", path, mode) - return err -} - -func Fchmod(fd int, mode uint32) error { - _, err := fsCall("fchmod", fd, mode) - return err -} - -func Chown(path string, uid, gid int) error { - if err := checkPath(path); err != nil { - return err - } - _, err := fsCall("chown", path, uint32(uid), uint32(gid)) - return err -} - -func Fchown(fd int, uid, gid int) error { - _, err := fsCall("fchown", fd, uint32(uid), uint32(gid)) - return err -} - -func Lchown(path string, uid, gid int) error { - if err := checkPath(path); err != nil { - return err - } - if jsFS.Get("lchown").IsUndefined() { - // fs.lchown is unavailable on Linux until Node.js 10.6.0 - // TODO(neelance): remove when we require at least this Node.js version - return ENOSYS - } - _, err := fsCall("lchown", path, uint32(uid), uint32(gid)) - return err -} - -func UtimesNano(path string, ts []Timespec) error { - // UTIME_OMIT value must match internal/syscall/unix/at_js.go - const UTIME_OMIT = -0x2 - if err := checkPath(path); err != nil { - return err - } - if len(ts) != 2 { - return EINVAL - } - atime := ts[0].Sec - mtime := ts[1].Sec - if atime == UTIME_OMIT || mtime == UTIME_OMIT { - var st Stat_t - if err := Stat(path, &st); err != nil { - return err - } - if atime == UTIME_OMIT { - atime = st.Atime - } - if mtime == UTIME_OMIT { - mtime = st.Mtime - } - } - _, err := fsCall("utimes", path, atime, mtime) - return err -} - -func Rename(from, to string) error { - if err := checkPath(from); err != nil { - return err - } - if err := checkPath(to); err != nil { - return err - } - _, err := fsCall("rename", from, to) - return err -} - -func Truncate(path string, length int64) error { - if err := checkPath(path); err != nil { - return err - } - _, err := fsCall("truncate", path, length) - return err -} - -func Ftruncate(fd int, length int64) error { - _, err := fsCall("ftruncate", fd, length) - return err -} - -func Getcwd(buf []byte) (n int, err error) { - defer recoverErr(&err) - cwd := jsProcess.Call("cwd").String() - n = copy(buf, cwd) - return -} - -func Chdir(path string) (err error) { - if err := checkPath(path); err != nil { - return err - } - defer recoverErr(&err) - jsProcess.Call("chdir", path) - return -} - -func Fchdir(fd int) error { - f, err := fdToFile(fd) - if err != nil { - return err - } - return Chdir(f.path) -} - -func Readlink(path string, buf []byte) (n int, err error) { - if err := checkPath(path); err != nil { - return 0, err - } - dst, err := fsCall("readlink", path) - if err != nil { - return 0, err - } - n = copy(buf, dst.String()) - return n, nil -} - -func Link(path, link string) error { - if err := checkPath(path); err != nil { - return err - } - if err := checkPath(link); err != nil { - return err - } - _, err := fsCall("link", path, link) - return err -} - -func Symlink(path, link string) error { - if err := checkPath(path); err != nil { - return err - } - if err := checkPath(link); err != nil { - return err - } - _, err := fsCall("symlink", path, link) - return err -} - -func Fsync(fd int) error { - _, err := fsCall("fsync", fd) - return err -} - -func Read(fd int, b []byte) (int, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - - if f.seeked { - n, err := Pread(fd, b, f.pos) - f.pos += int64(n) - return n, err - } - - buf := uint8Array.New(len(b)) - n, err := fsCall("read", fd, buf, 0, len(b), nil) - if err != nil { - return 0, err - } - js.CopyBytesToGo(b, buf) - - n2 := n.Int() - f.pos += int64(n2) - return n2, err -} - -func Write(fd int, b []byte) (int, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - - if f.seeked { - n, err := Pwrite(fd, b, f.pos) - f.pos += int64(n) - return n, err - } - - if faketime && (fd == 1 || fd == 2) { - n := faketimeWrite(fd, b) - if n < 0 { - return 0, errnoErr(Errno(-n)) - } - return n, nil - } - - buf := uint8Array.New(len(b)) - js.CopyBytesToJS(buf, b) - n, err := fsCall("write", fd, buf, 0, len(b), nil) - if err != nil { - return 0, err - } - n2 := n.Int() - f.pos += int64(n2) - return n2, err -} - -func Pread(fd int, b []byte, offset int64) (int, error) { - buf := uint8Array.New(len(b)) - n, err := fsCall("read", fd, buf, 0, len(b), offset) - if err != nil { - return 0, err - } - js.CopyBytesToGo(b, buf) - return n.Int(), nil -} - -func Pwrite(fd int, b []byte, offset int64) (int, error) { - buf := uint8Array.New(len(b)) - js.CopyBytesToJS(buf, b) - n, err := fsCall("write", fd, buf, 0, len(b), offset) - if err != nil { - return 0, err - } - return n.Int(), nil -} - -func Seek(fd int, offset int64, whence int) (int64, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - - var newPos int64 - switch whence { - case 0: - newPos = offset - case 1: - newPos = f.pos + offset - case 2: - var st Stat_t - if err := Fstat(fd, &st); err != nil { - return 0, err - } - newPos = st.Size + offset - default: - return 0, errnoErr(EINVAL) - } - - if newPos < 0 { - return 0, errnoErr(EINVAL) - } - - f.seeked = true - f.dirIdx = 0 // Reset directory read position. See issue 35767. - f.pos = newPos - return newPos, nil -} - -func Dup(fd int) (int, error) { - return 0, ENOSYS -} - -func Dup2(fd, newfd int) error { - return ENOSYS -} - -func Pipe(fd []int) error { - return ENOSYS -} - -func fsCall(name string, args ...any) (js.Value, error) { - type callResult struct { - val js.Value - err error - } - - c := make(chan callResult, 1) - f := js.FuncOf(func(this js.Value, args []js.Value) any { - var res callResult - - if len(args) >= 1 { // on Node.js 8, fs.utimes calls the callback without any arguments - if jsErr := args[0]; !jsErr.IsNull() { - res.err = mapJSError(jsErr) - } - } - - res.val = js.Undefined() - if len(args) >= 2 { - res.val = args[1] - } - - c <- res - return nil - }) - defer f.Release() - jsFS.Call(name, append(args, f)...) - res := <-c - return res.val, res.err -} - -// checkPath checks that the path is not empty and that it contains no null characters. -func checkPath(path string) error { - if path == "" { - return EINVAL - } - for i := 0; i < len(path); i++ { - if path[i] == '\x00' { - return EINVAL - } - } - return nil -} - -func recoverErr(errPtr *error) { - if err := recover(); err != nil { - jsErr, ok := err.(js.Error) - if !ok { - panic(err) - } - *errPtr = mapJSError(jsErr.Value) - } -} - -// mapJSError maps an error given by Node.js to the appropriate Go error. -func mapJSError(jsErr js.Value) error { - errno, ok := errnoByCode[jsErr.Get("code").String()] - if !ok { - panic(jsErr) - } - return errnoErr(Errno(errno)) -} |
