]> Cypherpunks repositories - gostls13.git/commitdiff
make FD a struct with Read, Write, etc.
authorRob Pike <r@golang.org>
Wed, 10 Sep 2008 22:23:28 +0000 (15:23 -0700)
committerRob Pike <r@golang.org>
Wed, 10 Sep 2008 22:23:28 +0000 (15:23 -0700)
as methods

R=gri,rsc
DELTA=99  (56 added, 31 deleted, 12 changed)
OCL=15103
CL=15103

src/lib/os/os.go

index 85417ba239d9e785e2709ab839a7025258f88bb2..6f1941343f1aa625aa574856a8ea5f96b32af55b 100644 (file)
@@ -8,42 +8,41 @@ import syscall "syscall"
 
 // Support types and routines for OS library
 
-func WriteString(fd int64, s string) (ret int64, err *Error);
-
-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
+// 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 --
-// it handles the nil (no error) case.
-
+// they handle the nil (no error) case.
 export type Error struct {
        s string
 }
 
-const NoError = "No Error"
-
-func (e *Error) Print() {
-       if e == nil {
-               WriteString(2, NoError)
-       } else {
-               WriteString(2, e.s)
+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;
 }
 
-func (e *Error) String() string {
-       if e == nil {
-               return NoError
-       } else {
-               return e.s
+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);
@@ -101,36 +100,62 @@ export var (
        EAGAIN = ErrnoToError(syscall.EAGAIN);
 )
 
-export func Open(name string, mode int64, flags int64) (ret int64, err *Error) {
+export func Open(name string, mode int64, flags int64) (fd *FD, err *Error) {
        var buf [512]byte;
        if !StringToBytes(&buf, name) {
-               return -1, ErrnoToError(syscall.ENAMETOOLONG)
+               return nil, EINVAL
        }
        r, e := syscall.open(&buf[0], mode, flags);
-       return r, ErrnoToError(e)
+       return NewFD(r), ErrnoToError(e)
 }
 
-export func Close(fd int64) (ret int64, err *Error) {
-       r, e := syscall.close(fd);
-       return 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)
 }
 
-export func Read(fd int64, b *[]byte) (ret int64, err *Error) {
-       r, e := syscall.read(fd, &b[0], int64(len(b)));
+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)
 }
 
-export func Write(fd int64, b *[]byte) (ret int64, err *Error) {
-       r, e := syscall.write(fd, &b[0], int64(len(b)));
+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)
 }
 
-export func WriteString(fd int64, s string) (ret int64, err *Error) {
+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, ErrnoToError(syscall.ENAMETOOLONG)
+               return -1, EINVAL
        }
-       r, e := syscall.write(fd, &b[0], int64(len(s)));
+       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())
+}