Merge pull request #828 from luoliwoshang/os/errno
os:fix os.Errno 's nil pointer derefer in linux
This commit is contained in:
28
_demo/checkfile/demo.go
Normal file
28
_demo/checkfile/demo.go
Normal file
@@ -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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
int llgoClearenv() {
|
int llgoClearenv() {
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
@@ -7,3 +8,5 @@ int llgoClearenv() {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int llgoErrno() { return errno; }
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ type (
|
|||||||
StatT = syscall.Stat_t
|
StatT = syscall.Stat_t
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname Errno errno
|
//go:linkname Errno C.llgoErrno
|
||||||
var Errno c.Int
|
func Errno() c.Int
|
||||||
|
|
||||||
//go:linkname Umask C.umask
|
//go:linkname Umask C.umask
|
||||||
func Umask(cmask ModeT) ModeT
|
func Umask(cmask ModeT) ModeT
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ package os
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LLGoPackage = "decl"
|
LLGoFiles = "_os/os.c"
|
||||||
|
LLGoPackage = "link"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname Clearenv C.clearenv
|
//go:linkname Clearenv C.clearenv
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ func (conn *cConn) Read(p []byte) (n int, err error) {
|
|||||||
for n < len(p) {
|
for n < len(p) {
|
||||||
result := os.Read(conn.socketFd, unsafe.Pointer(&p[n:][0]), uintptr(len(p)-n))
|
result := os.Read(conn.socketFd, unsafe.Pointer(&p[n:][0]), uintptr(len(p)-n))
|
||||||
if result < 0 {
|
if result < 0 {
|
||||||
if os.Errno == c.Int(syscall.EINTR) {
|
if os.Errno() == c.Int(syscall.EINTR) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return n, errors.New("read error")
|
return n, errors.New("read error")
|
||||||
@@ -128,7 +128,7 @@ func (conn *cConn) Write(p []byte) (n int, err error) {
|
|||||||
for n < len(p) {
|
for n < len(p) {
|
||||||
result := os.Write(conn.socketFd, unsafe.Pointer(&p[n:][0]), uintptr(len(p)-n))
|
result := os.Write(conn.socketFd, unsafe.Pointer(&p[n:][0]), uintptr(len(p)-n))
|
||||||
if result < 0 {
|
if result < 0 {
|
||||||
if os.Errno == c.Int(syscall.EINTR) {
|
if os.Errno() == c.Int(syscall.EINTR) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return n, errors.New("write error")
|
return n, errors.New("write error")
|
||||||
@@ -151,7 +151,7 @@ func (conn *cConn) Close() error {
|
|||||||
conn.closed = true
|
conn.closed = true
|
||||||
result := os.Close(conn.socketFd)
|
result := os.Close(conn.socketFd)
|
||||||
if result < 0 {
|
if result < 0 {
|
||||||
return errors.New(c.GoString(c.Strerror(os.Errno)))
|
return errors.New(c.GoString(c.Strerror(os.Errno())))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ func Getwd() (dir string, err error) {
|
|||||||
if wd != nil {
|
if wd != nil {
|
||||||
return c.GoString(wd), nil
|
return c.GoString(wd), nil
|
||||||
}
|
}
|
||||||
return "", syscall.Errno(os.Errno)
|
return "", syscall.Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(xsw):
|
// TODO(xsw):
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (f *File) write(b []byte) (int, error) {
|
|||||||
if ret >= 0 {
|
if ret >= 0 {
|
||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
}
|
}
|
||||||
return 0, syscall.Errno(os.Errno)
|
return 0, syscall.Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(xsw):
|
/* TODO(xsw):
|
||||||
@@ -56,7 +56,7 @@ func (f *File) read(b []byte) (int, error) {
|
|||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
return 0, syscall.Errno(os.Errno)
|
return 0, syscall.Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(xsw):
|
/* TODO(xsw):
|
||||||
|
|||||||
@@ -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,
|
// dup2(i, i) won't clear close-on-exec flag on Linux,
|
||||||
// probably not elsewhere either.
|
// probably not elsewhere either.
|
||||||
if ret := os.Fcntl(c.Int(fd[i]), syscall.F_SETFD, 0); ret < 0 {
|
if ret := os.Fcntl(c.Int(fd[i]), syscall.F_SETFD, 0); ret < 0 {
|
||||||
err1 = Errno(os.Errno)
|
err1 = Errno(os.Errno())
|
||||||
goto childerror
|
goto childerror
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// The new fd is created NOT close-on-exec,
|
// The new fd is created NOT close-on-exec,
|
||||||
if ret := os.Dup2(c.Int(fd[i]), c.Int(i)); ret < 0 {
|
if ret := os.Dup2(c.Int(fd[i]), c.Int(i)); ret < 0 {
|
||||||
err1 = Errno(os.Errno)
|
err1 = Errno(os.Errno())
|
||||||
goto childerror
|
goto childerror
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func Getcwd(buf []byte) (n int, err error) {
|
|||||||
if ret != nil {
|
if ret != nil {
|
||||||
return int(c.Strlen(ret)), nil
|
return int(c.Strlen(ret)), nil
|
||||||
}
|
}
|
||||||
return 0, Errno(os.Errno)
|
return 0, Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Getwd() (string, error) {
|
func Getwd() (string, error) {
|
||||||
@@ -70,7 +70,7 @@ func Getwd() (string, error) {
|
|||||||
if wd != nil {
|
if wd != nil {
|
||||||
return c.GoString(wd), nil
|
return c.GoString(wd), nil
|
||||||
}
|
}
|
||||||
return "", Errno(os.Errno)
|
return "", Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Getpid() (pid int) {
|
func Getpid() (pid int) {
|
||||||
@@ -90,7 +90,7 @@ func fork() (uintptr, Errno) {
|
|||||||
if ret >= 0 {
|
if ret >= 0 {
|
||||||
return uintptr(ret), Errno(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) {
|
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 {
|
if ret >= 0 {
|
||||||
return int(ret), nil
|
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) {
|
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 {
|
if ret >= 0 {
|
||||||
return int(ret), nil
|
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) {
|
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 {
|
if ret >= 0 {
|
||||||
return int64(ret), nil
|
return int64(ret), nil
|
||||||
}
|
}
|
||||||
return -1, Errno(os.Errno)
|
return -1, Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Read(fd int, p []byte) (n int, err error) {
|
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 {
|
if ret >= 0 {
|
||||||
return ret, nil // TODO(xsw): confirm err == nil (not io.EOF) when 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) {
|
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 {
|
if ret >= 0 {
|
||||||
return ret, nil // TODO(xsw): confirm err == nil (not io.EOF) when 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) {
|
func Close(fd int) (err error) {
|
||||||
@@ -148,7 +148,7 @@ func Lstat(path string, stat *Stat_t) (err error) {
|
|||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return Errno(os.Errno)
|
return Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Stat(path string, stat *Stat_t) (err error) {
|
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 {
|
if ret == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return Errno(os.Errno)
|
return Errno(os.Errno())
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pipe(p []int) (err error) {
|
func Pipe(p []int) (err error) {
|
||||||
|
|||||||
@@ -466,7 +466,7 @@ func SysctlUint32(name string) (value uint32, err error) {
|
|||||||
n := uintptr(4)
|
n := uintptr(4)
|
||||||
ret := os.Sysctlbyname(c.AllocaCStr(name), unsafe.Pointer(&value), &n, nil, 0)
|
ret := os.Sysctlbyname(c.AllocaCStr(name), unsafe.Pointer(&value), &n, nil, 0)
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
err = Errno(os.Errno)
|
err = Errno(os.Errno())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user