mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
make syscall use strings for file names
tweak os to adjust
move StringToBytes into syscall, at least for now
this program still works:
package main
import os "os"
func main() {
os.Stdout.WriteString("hello, world\n");
a, b := os.NewFD(77).WriteString("no way");
os.Stdout.WriteString(b.String() + "\n");
}
R=rsc
DELTA=263 (59 added, 176 deleted, 28 changed)
OCL=15153
CL=15153
This commit is contained in:
parent
c80b06a54e
commit
ccede3e872
9 changed files with 87 additions and 212 deletions
|
|
@ -8,11 +8,11 @@ GC=$(O)g
|
|||
PKG=$(GOROOT)/pkg/os.a
|
||||
|
||||
O1=\
|
||||
os_base.$O os_error.$O
|
||||
os_error.$O
|
||||
O2=\
|
||||
os_file.$O
|
||||
|
||||
install: $(PKG)
|
||||
install: nuke $(PKG)
|
||||
|
||||
$(PKG): a1 a2
|
||||
|
||||
|
|
|
|||
161
src/lib/os/os.go
161
src/lib/os/os.go
|
|
@ -1,161 +0,0 @@
|
|||
// Copyright 2009 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.
|
||||
|
||||
package os
|
||||
|
||||
import syscall "syscall"
|
||||
|
||||
// Support types and routines for OS library
|
||||
|
||||
// FDs are wrappers for file descriptors
|
||||
export type FD struct {
|
||||
fd int64
|
||||
}
|
||||
|
||||
// Errors are singleton structures. Use the Print()/String() methods to get their contents --
|
||||
// they handle the nil (no error) case.
|
||||
export type Error struct {
|
||||
s string
|
||||
}
|
||||
|
||||
export func NewFD(fd int64) *FD {
|
||||
if fd < 0 {
|
||||
return nil
|
||||
}
|
||||
n := new(FD); // TODO(r): how about return &FD{fd} ?
|
||||
n.fd = fd;
|
||||
return n;
|
||||
}
|
||||
|
||||
export var (
|
||||
Stdin = NewFD(0);
|
||||
Stdout = NewFD(1);
|
||||
Stderr = NewFD(2);
|
||||
)
|
||||
|
||||
export func StringToBytes(b *[]byte, s string) bool {
|
||||
if len(s) >= len(b) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s); i++ {
|
||||
b[i] = s[i]
|
||||
}
|
||||
b[len(s)] = '\000'; // not necessary - memory is zeroed - but be explicit
|
||||
return true
|
||||
}
|
||||
|
||||
var ErrorTab = new(map[int64] *Error);
|
||||
|
||||
func ErrnoToError(errno int64) *Error {
|
||||
if errno == 0 {
|
||||
return nil
|
||||
}
|
||||
err, ok := ErrorTab[errno]
|
||||
if ok {
|
||||
return err
|
||||
}
|
||||
e := new(Error);
|
||||
e.s = syscall.errstr(errno);
|
||||
ErrorTab[errno] = e;
|
||||
return e;
|
||||
}
|
||||
|
||||
export var (
|
||||
ENONE = ErrnoToError(syscall.ENONE);
|
||||
EPERM = ErrnoToError(syscall.EPERM);
|
||||
ENOENT = ErrnoToError(syscall.ENOENT);
|
||||
ESRCH = ErrnoToError(syscall.ESRCH);
|
||||
EINTR = ErrnoToError(syscall.EINTR);
|
||||
EIO = ErrnoToError(syscall.EIO);
|
||||
ENXIO = ErrnoToError(syscall.ENXIO);
|
||||
E2BIG = ErrnoToError(syscall.E2BIG);
|
||||
ENOEXEC = ErrnoToError(syscall.ENOEXEC);
|
||||
EBADF = ErrnoToError(syscall.EBADF);
|
||||
ECHILD = ErrnoToError(syscall.ECHILD);
|
||||
EDEADLK = ErrnoToError(syscall.EDEADLK);
|
||||
ENOMEM = ErrnoToError(syscall.ENOMEM);
|
||||
EACCES = ErrnoToError(syscall.EACCES);
|
||||
EFAULT = ErrnoToError(syscall.EFAULT);
|
||||
ENOTBLK = ErrnoToError(syscall.ENOTBLK);
|
||||
EBUSY = ErrnoToError(syscall.EBUSY);
|
||||
EEXIST = ErrnoToError(syscall.EEXIST);
|
||||
EXDEV = ErrnoToError(syscall.EXDEV);
|
||||
ENODEV = ErrnoToError(syscall.ENODEV);
|
||||
ENOTDIR = ErrnoToError(syscall.ENOTDIR);
|
||||
EISDIR = ErrnoToError(syscall.EISDIR);
|
||||
EINVAL = ErrnoToError(syscall.EINVAL);
|
||||
ENFILE = ErrnoToError(syscall.ENFILE);
|
||||
EMFILE = ErrnoToError(syscall.EMFILE);
|
||||
ENOTTY = ErrnoToError(syscall.ENOTTY);
|
||||
ETXTBSY = ErrnoToError(syscall.ETXTBSY);
|
||||
EFBIG = ErrnoToError(syscall.EFBIG);
|
||||
ENOSPC = ErrnoToError(syscall.ENOSPC);
|
||||
ESPIPE = ErrnoToError(syscall.ESPIPE);
|
||||
EROFS = ErrnoToError(syscall.EROFS);
|
||||
EMLINK = ErrnoToError(syscall.EMLINK);
|
||||
EPIPE = ErrnoToError(syscall.EPIPE);
|
||||
EDOM = ErrnoToError(syscall.EDOM);
|
||||
ERANGE = ErrnoToError(syscall.ERANGE);
|
||||
EAGAIN = ErrnoToError(syscall.EAGAIN);
|
||||
)
|
||||
|
||||
export func Open(name string, mode int64, flags int64) (fd *FD, err *Error) {
|
||||
var buf [512]byte;
|
||||
if !StringToBytes(&buf, name) {
|
||||
return nil, EINVAL
|
||||
}
|
||||
r, e := syscall.open(&buf[0], mode, flags);
|
||||
return NewFD(r), ErrnoToError(e)
|
||||
}
|
||||
|
||||
func (fd *FD) Close() *Error {
|
||||
if fd == nil {
|
||||
return EINVAL
|
||||
}
|
||||
r, e := syscall.close(fd.fd);
|
||||
fd.fd = -1; // so it can't be closed again
|
||||
return ErrnoToError(e)
|
||||
}
|
||||
|
||||
func (fd *FD) Read(b *[]byte) (ret int64, err *Error) {
|
||||
if fd == nil {
|
||||
return -1, EINVAL
|
||||
}
|
||||
r, e := syscall.read(fd.fd, &b[0], int64(len(b)));
|
||||
return r, ErrnoToError(e)
|
||||
}
|
||||
|
||||
func (fd *FD) Write(b *[]byte) (ret int64, err *Error) {
|
||||
if fd == nil {
|
||||
return -1, EINVAL
|
||||
}
|
||||
r, e := syscall.write(fd.fd, &b[0], int64(len(b)));
|
||||
return r, ErrnoToError(e)
|
||||
}
|
||||
|
||||
func (fd *FD) WriteString(s string) (ret int64, err *Error) {
|
||||
if fd == nil {
|
||||
return -1, EINVAL
|
||||
}
|
||||
b := new([]byte, len(s)+1);
|
||||
if !StringToBytes(b, s) {
|
||||
return -1, EINVAL
|
||||
}
|
||||
r, e := syscall.write(fd.fd, &b[0], int64(len(s)));
|
||||
return r, ErrnoToError(e)
|
||||
}
|
||||
|
||||
const NoError = "No Error"
|
||||
|
||||
func (e *Error) String() string {
|
||||
if e == nil {
|
||||
return NoError
|
||||
} else {
|
||||
return e.s
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Error) Print() {
|
||||
Stderr.WriteString(e.String())
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright 2009 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.
|
||||
|
||||
package os
|
||||
|
||||
// Support types and routines for OS library
|
||||
|
||||
export func StringToBytes(b *[]byte, s string) bool {
|
||||
if len(s) >= len(b) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s); i++ {
|
||||
b[i] = s[i]
|
||||
}
|
||||
b[len(s)] = '\000'; // not necessary - memory is zeroed - but be explicit
|
||||
return true
|
||||
}
|
||||
|
|
@ -6,8 +6,8 @@ package os
|
|||
|
||||
import syscall "syscall"
|
||||
|
||||
// Errors are singleton structures. Use the Print()/String() methods to get their contents --
|
||||
// they handle the nil (no error) case.
|
||||
// Errors are singleton structures. Use the String() method to get their contents --
|
||||
// it handles the nil (no error) case.
|
||||
export type Error struct {
|
||||
s string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,7 @@ export var (
|
|||
)
|
||||
|
||||
export func Open(name string, mode int64, flags int64) (fd *FD, err *Error) {
|
||||
var buf [512]byte;
|
||||
if !StringToBytes(&buf, name) {
|
||||
return nil, EINVAL
|
||||
}
|
||||
r, e := syscall.open(&buf[0], mode, flags);
|
||||
r, e := syscall.open(name, mode, flags);
|
||||
return NewFD(r), ErrnoToError(e)
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +62,7 @@ func (fd *FD) WriteString(s string) (ret int64, err *Error) {
|
|||
return -1, EINVAL
|
||||
}
|
||||
b := new([]byte, len(s)+1);
|
||||
if !StringToBytes(b, s) {
|
||||
if !syscall.StringToBytes(b, s) {
|
||||
return -1, EINVAL
|
||||
}
|
||||
r, e := syscall.write(fd.fd, &b[0], int64(len(s)));
|
||||
|
|
|
|||
|
|
@ -8,23 +8,31 @@ CC=$(O)c
|
|||
AS=$(O)a
|
||||
GC=$(O)g
|
||||
|
||||
PKG=syscall.a
|
||||
PKG=$(GOROOT)/pkg/syscall.a
|
||||
|
||||
OFILES=\
|
||||
O1=\
|
||||
syscall.$O \
|
||||
errstr_$(GOOS).$O \
|
||||
|
||||
O2=\
|
||||
file_$(GOARCH)_$(GOOS).$O \
|
||||
syscall_$(GOARCH)_$(GOOS).$O \
|
||||
|
||||
|
||||
install: $(PKG)
|
||||
cp $(PKG) $(GOROOT)/pkg/$(PKG)
|
||||
install: nuke $(PKG)
|
||||
|
||||
$(PKG): $(OFILES)
|
||||
$(O)ar grc $(PKG) $(OFILES)
|
||||
$(PKG): a1 a2
|
||||
|
||||
a1: $(O1)
|
||||
$(O)ar grc $(PKG) $(O1)
|
||||
rm *.6
|
||||
|
||||
a2: $(O2)
|
||||
$(O)ar grc $(PKG) $(O2)
|
||||
rm *.6
|
||||
|
||||
nuke:
|
||||
rm -f *.$(O) *.a $(GOROOT)/pkg/$(PKG)
|
||||
rm -f *.$(O) *.a $(PKG)
|
||||
|
||||
clean:
|
||||
rm -f *.$(O) *.a
|
||||
|
|
|
|||
|
|
@ -65,15 +65,25 @@ const (
|
|||
O_TRUNC = 0x400;
|
||||
)
|
||||
|
||||
export func open(name *byte, mode int64, flags int64) (ret int64, errno int64) {
|
||||
const NameBufsize = 512
|
||||
|
||||
export func open(name string, mode int64, perm int64) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSOPEN = 5;
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(name), mode, flags);
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(&namebuf[0]), mode, perm);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
export func creat(name *byte, mode int64) (ret int64, errno int64) {
|
||||
export func creat(name string, perm int64) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSOPEN = 5;
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(name), mode, O_CREAT|O_WRONLY|O_TRUNC);
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(&namebuf[0]), O_CREAT|O_WRONLY|O_TRUNC, perm);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
|
|
@ -106,9 +116,13 @@ export func pipe(fds *[2]int64) (ret int64, errno int64) {
|
|||
return 0, 0;
|
||||
}
|
||||
|
||||
export func stat(name *byte, buf *Stat) (ret int64, errno int64) {
|
||||
export func stat(name string, buf *Stat) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSSTAT = 338;
|
||||
r1, r2, err := syscall.Syscall(SYSSTAT, AddrToInt(name), StatToInt(buf), 0);
|
||||
r1, r2, err := syscall.Syscall(SYSSTAT, AddrToInt(&namebuf[0]), StatToInt(buf), 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
|
|
@ -124,8 +138,12 @@ export func fstat(fd int64, buf *Stat) (ret int64, errno int64) {
|
|||
return r1, err;
|
||||
}
|
||||
|
||||
export func unlink(name *byte) (ret int64, errno int64) {
|
||||
export func unlink(name string) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSUNLINK = 10;
|
||||
r1, r2, err := syscall.Syscall(SYSUNLINK, AddrToInt(name), 0, 0);
|
||||
r1, r2, err := syscall.Syscall(SYSUNLINK, AddrToInt(&namebuf[0]), 0, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,15 +66,25 @@ const (
|
|||
O_TRUNC = 0x200;
|
||||
)
|
||||
|
||||
export func open(name *byte, mode int64, flags int64) (ret int64, errno int64) {
|
||||
const NameBufsize = 512
|
||||
|
||||
export func open(name string, mode int64, perm int64) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSOPEN = 2;
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(name), mode, flags);
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(&namebuf[0]), mode, perm);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
export func creat(name *byte, mode int64) (ret int64, errno int64) {
|
||||
export func creat(name string, perm int64) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSOPEN = 2;
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(name), mode, O_CREAT|O_WRONLY|O_TRUNC);
|
||||
r1, r2, err := syscall.Syscall(SYSOPEN, AddrToInt(&namebuf[0]), O_CREAT|O_WRONLY|O_TRUNC, perm);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
|
|
@ -108,9 +118,13 @@ export func pipe(fds *[2]int64) (ret int64, errno int64) {
|
|||
return 0, 0;
|
||||
}
|
||||
|
||||
export func stat(name *byte, buf *Stat) (ret int64, errno int64) {
|
||||
export func stat(name string, buf *Stat) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSSTAT = 4;
|
||||
r1, r2, err := syscall.Syscall(SYSSTAT, AddrToInt(name), StatToInt(buf), 0);
|
||||
r1, r2, err := syscall.Syscall(SYSSTAT, AddrToInt(&namebuf[0]), StatToInt(buf), 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
|
|
@ -126,8 +140,12 @@ export func fstat(fd int64, buf *Stat) (ret int64, errno int64) {
|
|||
return r1, err;
|
||||
}
|
||||
|
||||
export func unlink(name *byte) (ret int64, errno int64) {
|
||||
export func unlink(name string) (ret int64, errno int64) {
|
||||
var namebuf [NameBufsize]byte;
|
||||
if !StringToBytes(&namebuf, name) {
|
||||
return -1, syscall.ENAMETOOLONG
|
||||
}
|
||||
const SYSUNLINK = 87;
|
||||
r1, r2, err := syscall.Syscall(SYSUNLINK, AddrToInt(name), 0, 0);
|
||||
r1, r2, err := syscall.Syscall(SYSUNLINK, AddrToInt(&namebuf[0]), 0, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,3 +11,17 @@ package syscall
|
|||
export func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
|
||||
export func AddrToInt(b *byte) int64;
|
||||
|
||||
/*
|
||||
* Used to convert file names to byte arrays for passing to kernel,
|
||||
* but useful elsewhere too.
|
||||
*/
|
||||
export func StringToBytes(b *[]byte, s string) bool {
|
||||
if len(s) >= len(b) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s); i++ {
|
||||
b[i] = s[i]
|
||||
}
|
||||
b[len(s)] = '\000'; // not necessary - memory is zeroed - but be explicit
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue