From e9177c893288ce48ea2d546c1bb4ad142bb256b7 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Sat, 12 Oct 2024 11:58:53 +0800 Subject: [PATCH] os/errno:fix os.Errno 's nil pointer derefer in linux --- _demo/checkfile/demo.go | 28 +++++++++++++++++++ c/os/_os/os.c | 3 ++ c/os/os.go | 4 +-- c/os/os_linux.go | 3 +- .../build/_overlay/net/textproto/textproto.go | 6 ++-- internal/lib/os/os.go | 2 +- internal/lib/os/types.go | 4 +-- internal/lib/syscall/exec_libc2.go | 4 +-- internal/lib/syscall/syscall.go | 20 ++++++------- internal/lib/syscall/syscall_bsd.go | 2 +- 10 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 _demo/checkfile/demo.go diff --git a/_demo/checkfile/demo.go b/_demo/checkfile/demo.go new file mode 100644 index 00000000..7ba9d27b --- /dev/null +++ b/_demo/checkfile/demo.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" +) + +func main() { + tempDir := os.TempDir() + noexist := filepath.Join(tempDir, "noexist.txt") + + if _, err := os.Stat(noexist); err != nil { + if os.IsNotExist(err) { + fmt.Println("noexist:", err.Error()) + } else { + fmt.Println("exist,other err:", err.Error()) + } + } + + if _, err := os.Open(noexist); err != nil { + if os.IsNotExist(err) { + fmt.Println("noexist:", err.Error()) + } else { + fmt.Println("exist,other err:", err.Error()) + } + } +} diff --git a/c/os/_os/os.c b/c/os/_os/os.c index 5dd2fac7..1d904faf 100644 --- a/c/os/_os/os.c +++ b/c/os/_os/os.c @@ -1,4 +1,5 @@ #include +#include int llgoClearenv() { extern char **environ; @@ -7,3 +8,5 @@ int llgoClearenv() { } return 0; } + +int llgoErrno() { return errno; } diff --git a/c/os/os.go b/c/os/os.go index 59401763..b7a81770 100644 --- a/c/os/os.go +++ b/c/os/os.go @@ -70,8 +70,8 @@ type ( StatT = syscall.Stat_t ) -//go:linkname Errno errno -var Errno c.Int +//go:linkname Errno C.llgoErrno +func Errno() c.Int //go:linkname Umask C.umask func Umask(cmask ModeT) ModeT diff --git a/c/os/os_linux.go b/c/os/os_linux.go index 0ea364b6..6886a3f2 100644 --- a/c/os/os_linux.go +++ b/c/os/os_linux.go @@ -21,7 +21,8 @@ package os import "C" const ( - LLGoPackage = "decl" + LLGoFiles = "_os/os.c" + LLGoPackage = "link" ) //go:linkname Clearenv C.clearenv diff --git a/internal/build/_overlay/net/textproto/textproto.go b/internal/build/_overlay/net/textproto/textproto.go index a912089d..7f2bc815 100644 --- a/internal/build/_overlay/net/textproto/textproto.go +++ b/internal/build/_overlay/net/textproto/textproto.go @@ -108,7 +108,7 @@ func (conn *cConn) Read(p []byte) (n int, err error) { for n < len(p) { result := os.Read(conn.socketFd, unsafe.Pointer(&p[n:][0]), uintptr(len(p)-n)) if result < 0 { - if os.Errno == c.Int(syscall.EINTR) { + if os.Errno() == c.Int(syscall.EINTR) { continue } return n, errors.New("read error") @@ -128,7 +128,7 @@ func (conn *cConn) Write(p []byte) (n int, err error) { for n < len(p) { result := os.Write(conn.socketFd, unsafe.Pointer(&p[n:][0]), uintptr(len(p)-n)) if result < 0 { - if os.Errno == c.Int(syscall.EINTR) { + if os.Errno() == c.Int(syscall.EINTR) { continue } return n, errors.New("write error") @@ -151,7 +151,7 @@ func (conn *cConn) Close() error { conn.closed = true result := os.Close(conn.socketFd) if result < 0 { - return errors.New(c.GoString(c.Strerror(os.Errno))) + return errors.New(c.GoString(c.Strerror(os.Errno()))) } return nil } diff --git a/internal/lib/os/os.go b/internal/lib/os/os.go index 2156a203..9d1ef33f 100644 --- a/internal/lib/os/os.go +++ b/internal/lib/os/os.go @@ -183,7 +183,7 @@ func Getwd() (dir string, err error) { if wd != nil { return c.GoString(wd), nil } - return "", syscall.Errno(os.Errno) + return "", syscall.Errno(os.Errno()) } // TODO(xsw): diff --git a/internal/lib/os/types.go b/internal/lib/os/types.go index af840c98..908ed0a3 100644 --- a/internal/lib/os/types.go +++ b/internal/lib/os/types.go @@ -33,7 +33,7 @@ func (f *File) write(b []byte) (int, error) { if ret >= 0 { return int(ret), nil } - return 0, syscall.Errno(os.Errno) + return 0, syscall.Errno(os.Errno()) } /* TODO(xsw): @@ -56,7 +56,7 @@ func (f *File) read(b []byte) (int, error) { if ret == 0 { return 0, io.EOF } - return 0, syscall.Errno(os.Errno) + return 0, syscall.Errno(os.Errno()) } /* TODO(xsw): diff --git a/internal/lib/syscall/exec_libc2.go b/internal/lib/syscall/exec_libc2.go index 3a5dede4..6077f163 100644 --- a/internal/lib/syscall/exec_libc2.go +++ b/internal/lib/syscall/exec_libc2.go @@ -264,14 +264,14 @@ func forkAndExecInChild(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char, // dup2(i, i) won't clear close-on-exec flag on Linux, // probably not elsewhere either. if ret := os.Fcntl(c.Int(fd[i]), syscall.F_SETFD, 0); ret < 0 { - err1 = Errno(os.Errno) + err1 = Errno(os.Errno()) goto childerror } continue } // The new fd is created NOT close-on-exec, if ret := os.Dup2(c.Int(fd[i]), c.Int(i)); ret < 0 { - err1 = Errno(os.Errno) + err1 = Errno(os.Errno()) goto childerror } } diff --git a/internal/lib/syscall/syscall.go b/internal/lib/syscall/syscall.go index bac53d5d..8c9be793 100644 --- a/internal/lib/syscall/syscall.go +++ b/internal/lib/syscall/syscall.go @@ -62,7 +62,7 @@ func Getcwd(buf []byte) (n int, err error) { if ret != nil { return int(c.Strlen(ret)), nil } - return 0, Errno(os.Errno) + return 0, Errno(os.Errno()) } func Getwd() (string, error) { @@ -70,7 +70,7 @@ func Getwd() (string, error) { if wd != nil { return c.GoString(wd), nil } - return "", Errno(os.Errno) + return "", Errno(os.Errno()) } func Getpid() (pid int) { @@ -90,7 +90,7 @@ func fork() (uintptr, Errno) { if ret >= 0 { return uintptr(ret), Errno(0) } - return 0, Errno(os.Errno) + return 0, Errno(os.Errno()) } func wait4(pid int, wstatus *c.Int, options int, rusage *syscall.Rusage) (wpid int, err error) { @@ -98,7 +98,7 @@ func wait4(pid int, wstatus *c.Int, options int, rusage *syscall.Rusage) (wpid i if ret >= 0 { return int(ret), nil } - return 0, Errno(os.Errno) + return 0, Errno(os.Errno()) } func Open(path string, mode int, perm uint32) (fd int, err error) { @@ -106,7 +106,7 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { if ret >= 0 { return int(ret), nil } - return 0, Errno(os.Errno) + return 0, Errno(os.Errno()) } func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { @@ -114,7 +114,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { if ret >= 0 { return int64(ret), nil } - return -1, Errno(os.Errno) + return -1, Errno(os.Errno()) } func Read(fd int, p []byte) (n int, err error) { @@ -122,7 +122,7 @@ func Read(fd int, p []byte) (n int, err error) { if ret >= 0 { return ret, nil // TODO(xsw): confirm err == nil (not io.EOF) when ret == 0 } - return 0, Errno(os.Errno) + return 0, Errno(os.Errno()) } func readlen(fd int, buf *byte, nbuf int) (n int, err error) { @@ -130,7 +130,7 @@ func readlen(fd int, buf *byte, nbuf int) (n int, err error) { if ret >= 0 { return ret, nil // TODO(xsw): confirm err == nil (not io.EOF) when ret == 0 } - return 0, Errno(os.Errno) + return 0, Errno(os.Errno()) } func Close(fd int) (err error) { @@ -148,7 +148,7 @@ func Lstat(path string, stat *Stat_t) (err error) { if ret == 0 { return nil } - return Errno(os.Errno) + return Errno(os.Errno()) } func Stat(path string, stat *Stat_t) (err error) { @@ -156,7 +156,7 @@ func Stat(path string, stat *Stat_t) (err error) { if ret == 0 { return nil } - return Errno(os.Errno) + return Errno(os.Errno()) } func Pipe(p []int) (err error) { diff --git a/internal/lib/syscall/syscall_bsd.go b/internal/lib/syscall/syscall_bsd.go index 86c34364..28ec535a 100644 --- a/internal/lib/syscall/syscall_bsd.go +++ b/internal/lib/syscall/syscall_bsd.go @@ -466,7 +466,7 @@ func SysctlUint32(name string) (value uint32, err error) { n := uintptr(4) ret := os.Sysctlbyname(c.AllocaCStr(name), unsafe.Pointer(&value), &n, nil, 0) if ret != 0 { - err = Errno(os.Errno) + err = Errno(os.Errno()) } return }