Commit 7a706fb3 authored by Russ Cox's avatar Russ Cox

Rename os.FD to os.File.

Make Fstat, Readdirnames, and Readdir methods
on os.File.

R=r
DELTA=281  (79 added, 3 deleted, 199 changed)
OCL=25891
CL=26130
parent 6479d893
...@@ -18,20 +18,20 @@ const ( ...@@ -18,20 +18,20 @@ const (
) )
// A Cmd represents a running command. // A Cmd represents a running command.
// Stdin, Stdout, and Stderr are file descriptors to pipes // Stdin, Stdout, and Stderr are Files representing pipes
// connected to the running command's standard input, output, and error, // connected to the running command's standard input, output, and error,
// or else nil, depending on the arguments to Run. // or else nil, depending on the arguments to Run.
// Pid is the running command's operating system process ID. // Pid is the running command's operating system process ID.
type Cmd struct { type Cmd struct {
Stdin *os.FD; Stdin *os.File;
Stdout *os.FD; Stdout *os.File;
Stderr *os.FD; Stderr *os.File;
Pid int; Pid int;
} }
// Given mode (DevNull, etc), return fd for child // Given mode (DevNull, etc), return file for child
// and fd to record in Cmd structure. // and file to record in Cmd structure.
func modeToFDs(mode, fd int) (*os.FD, *os.FD, *os.Error) { func modeToFiles(mode, fd int) (*os.File, *os.File, *os.Error) {
switch mode { switch mode {
case DevNull: case DevNull:
rw := os.O_WRONLY; rw := os.O_WRONLY;
...@@ -80,17 +80,17 @@ func modeToFDs(mode, fd int) (*os.FD, *os.FD, *os.Error) { ...@@ -80,17 +80,17 @@ func modeToFDs(mode, fd int) (*os.FD, *os.FD, *os.Error) {
func Run(argv0 string, argv, envv []string, stdin, stdout, stderr int) (p *Cmd, err *os.Error) func Run(argv0 string, argv, envv []string, stdin, stdout, stderr int) (p *Cmd, err *os.Error)
{ {
p = new(Cmd); p = new(Cmd);
var fd [3]*os.FD; var fd [3]*os.File;
if fd[0], p.Stdin, err = modeToFDs(stdin, 0); err != nil { if fd[0], p.Stdin, err = modeToFiles(stdin, 0); err != nil {
goto Error; goto Error;
} }
if fd[1], p.Stdout, err = modeToFDs(stdout, 1); err != nil { if fd[1], p.Stdout, err = modeToFiles(stdout, 1); err != nil {
goto Error; goto Error;
} }
if stderr == MergeWithStdout { if stderr == MergeWithStdout {
p.Stderr = p.Stdout; p.Stderr = p.Stdout;
} else if fd[2], p.Stderr, err = modeToFDs(stderr, 2); err != nil { } else if fd[2], p.Stderr, err = modeToFiles(stderr, 2); err != nil {
goto Error; goto Error;
} }
......
...@@ -22,23 +22,28 @@ import ( ...@@ -22,23 +22,28 @@ import (
"strconv"; "strconv";
) )
var ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush") // Errors introduced by the HTTP server.
var ErrHijacked = os.NewError("Conn has been hijacked") var (
ErrWriteAfterFlush = os.NewError("Conn.Write called after Flush");
ErrHijacked = os.NewError("Conn has been hijacked");
)
type Conn struct type Conn struct
// Interface implemented by servers using this library. // Objects implemeting the Handler interface can be
// registered to serve a particular path or subtree
// in the HTTP server.
type Handler interface { type Handler interface {
ServeHTTP(*Conn, *Request); ServeHTTP(*Conn, *Request);
} }
// Active HTTP connection (server side). // A Conn represents the server side of a single active HTTP connection.
type Conn struct { type Conn struct {
RemoteAddr string; // network address of remote side RemoteAddr string; // network address of remote side
Req *Request; // current HTTP request Req *Request; // current HTTP request
fd io.ReadWriteClose; // i/o connection rwc io.ReadWriteClose; // i/o connection
buf *bufio.BufReadWrite; // buffered fd buf *bufio.BufReadWrite; // buffered rwc
handler Handler; // request handler handler Handler; // request handler
hijacked bool; // connection has been hijacked by handler hijacked bool; // connection has been hijacked by handler
...@@ -54,7 +59,7 @@ func newConn(rwc io.ReadWriteClose, raddr string, handler Handler) (c *Conn, err ...@@ -54,7 +59,7 @@ func newConn(rwc io.ReadWriteClose, raddr string, handler Handler) (c *Conn, err
c = new(Conn); c = new(Conn);
c.RemoteAddr = raddr; c.RemoteAddr = raddr;
c.handler = handler; c.handler = handler;
c.fd = rwc; c.rwc = rwc;
br := bufio.NewBufRead(rwc); br := bufio.NewBufRead(rwc);
bw := bufio.NewBufWrite(rwc); bw := bufio.NewBufWrite(rwc);
c.buf = bufio.NewBufReadWrite(br, bw); c.buf = bufio.NewBufReadWrite(br, bw);
...@@ -99,11 +104,25 @@ func (c *Conn) readRequest() (req *Request, err *os.Error) { ...@@ -99,11 +104,25 @@ func (c *Conn) readRequest() (req *Request, err *os.Error) {
return req, nil return req, nil
} }
// SetHeader sets a header line in the eventual reply.
// For example, SetHeader("Content-Type", "text/html; charset=utf-8")
// will result in the header line
//
// Content-Type: text/html; charset=utf-8
//
// being sent. UTF-8 encoded HTML is the default setting for
// Content-Type in this library, so users need not make that
// particular call. Calls to SetHeader after WriteHeader (or Write)
// are ignored.
func (c *Conn) SetHeader(hdr, val string) { func (c *Conn) SetHeader(hdr, val string) {
c.header[CanonicalHeaderKey(hdr)] = val; c.header[CanonicalHeaderKey(hdr)] = val;
} }
// Write header. // WriteHeader sends an HTTP response header with status code.
// If WriteHeader is not called explicitly, the first call to Write
// will trigger an implicit WriteHeader(http.StatusOK).
// Thus explicit calls to WriteHeader are mainly used to
// send error codes.
func (c *Conn) WriteHeader(code int) { func (c *Conn) WriteHeader(code int) {
if c.hijacked { if c.hijacked {
log.Stderr("http: Conn.WriteHeader on hijacked connection"); log.Stderr("http: Conn.WriteHeader on hijacked connection");
...@@ -133,10 +152,10 @@ func (c *Conn) WriteHeader(code int) { ...@@ -133,10 +152,10 @@ func (c *Conn) WriteHeader(code int) {
io.WriteString(c.buf, "\r\n"); io.WriteString(c.buf, "\r\n");
} }
// TODO(rsc): BUG in 6g: must return "nn int" not "n int" // Write writes the data to the connection as part of an HTTP reply.
// so that the implicit struct assignment in // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
// return c.buf.Write(data) works. oops // before writing the data.
func (c *Conn) Write(data []byte) (nn int, err *os.Error) { func (c *Conn) Write(data []byte) (n int, err *os.Error) {
if c.hijacked { if c.hijacked {
log.Stderr("http: Conn.Write on hijacked connection"); log.Stderr("http: Conn.Write on hijacked connection");
return 0, ErrHijacked return 0, ErrHijacked
...@@ -175,9 +194,9 @@ func (c *Conn) close() { ...@@ -175,9 +194,9 @@ func (c *Conn) close() {
c.buf.Flush(); c.buf.Flush();
c.buf = nil; c.buf = nil;
} }
if c.fd != nil { if c.rwc != nil {
c.fd.Close(); c.rwc.Close();
c.fd = nil; c.rwc = nil;
} }
} }
...@@ -203,25 +222,30 @@ func (c *Conn) serve() { ...@@ -203,25 +222,30 @@ func (c *Conn) serve() {
c.close(); c.close();
} }
// Allow client to take over the connection. // Hijack lets the caller take over the connection.
// After a handler calls c.Hijack(), the HTTP server library // After a call to c.Hijack(), the HTTP server library
// will never touch the connection again. // will not do anything else with the connection.
// It is the caller's responsibility to manage and close // It becomes the caller's responsibility to manage
// the connection. // and close the connection.
func (c *Conn) Hijack() (fd io.ReadWriteClose, buf *bufio.BufReadWrite, err *os.Error) { func (c *Conn) Hijack() (rwc io.ReadWriteClose, buf *bufio.BufReadWrite, err *os.Error) {
if c.hijacked { if c.hijacked {
return nil, nil, ErrHijacked; return nil, nil, ErrHijacked;
} }
c.hijacked = true; c.hijacked = true;
fd = c.fd; rwc = c.rwc;
buf = c.buf; buf = c.buf;
c.fd = nil; c.rwc = nil;
c.buf = nil; c.buf = nil;
return; return;
} }
// Adapter: can use HandlerFunc(f) as Handler // The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler object that calls f.
type HandlerFunc func(*Conn, *Request) type HandlerFunc func(*Conn, *Request)
// ServeHTTP calls f(c, req).
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) { func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
f(c, req); f(c, req);
} }
...@@ -235,7 +259,11 @@ func notFound(c *Conn, req *Request) { ...@@ -235,7 +259,11 @@ func notFound(c *Conn, req *Request) {
io.WriteString(c, "404 page not found\n"); io.WriteString(c, "404 page not found\n");
} }
var NotFoundHandler = HandlerFunc(notFound) // NotFoundHandler returns a simple request handler
// that replies to each request with a ``404 page not found'' reply.
func NotFoundHandler() Handler {
return HandlerFunc(notFound)
}
// Redirect to a fixed URL // Redirect to a fixed URL
type redirectHandler struct { type redirectHandler struct {
...@@ -246,28 +274,42 @@ func (h *redirectHandler) ServeHTTP(c *Conn, req *Request) { ...@@ -246,28 +274,42 @@ func (h *redirectHandler) ServeHTTP(c *Conn, req *Request) {
c.WriteHeader(StatusMovedPermanently); c.WriteHeader(StatusMovedPermanently);
} }
func RedirectHandler(to string) Handler { // RedirectHandler returns a request handler that redirects
return &redirectHandler{to}; // each request it receives to the given url.
func RedirectHandler(url string) Handler {
return &redirectHandler{url};
} }
// Path-based HTTP request multiplexer. // ServeMux is an HTTP request multiplexer.
// Patterns name fixed paths, like "/favicon.ico", // It matches the URL of each incoming request against a list of registered
// or subtrees, like "/images/". // patterns and calls the handler for the pattern that
// For now, patterns must begin with /. // most closely matches the URL.
// Eventually, might want to allow host name //
// at beginning of pattern, so that you could register // Patterns named fixed paths, like "/favicon.ico",
// /codesearch // or subtrees, like "/images/" (note the trailing slash).
// codesearch.google.com/ // Patterns must begin with /.
// but not take over /. // Longer patterns take precedence over shorter ones, so that
// if there are handlers registered for both "/images/"
// and "/images/thumbnails/", the latter handler will be
// called for paths beginning "/images/thumbnails/" and the
// former will receiver requests for any other paths in the
// "/images/" subtree.
//
// In the future, the pattern syntax may be relaxed to allow
// an optional host-name at the beginning of the pattern,
// so that a handler might register for the two patterns
// "/codesearch" and "codesearch.google.com/"
// without taking over requests for http://www.google.com/.
type ServeMux struct { type ServeMux struct {
m map[string] Handler m map[string] Handler
} }
// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux { func NewServeMux() *ServeMux {
return &ServeMux{make(map[string] Handler)}; return &ServeMux{make(map[string] Handler)};
} }
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = NewServeMux(); var DefaultServeMux = NewServeMux();
// Does path match pattern? // Does path match pattern?
...@@ -283,6 +325,8 @@ func pathMatch(pattern, path string) bool { ...@@ -283,6 +325,8 @@ func pathMatch(pattern, path string) bool {
return len(path) >= n && path[0:n] == pattern; return len(path) >= n && path[0:n] == pattern;
} }
// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(c *Conn, req *Request) { func (mux *ServeMux) ServeHTTP(c *Conn, req *Request) {
// Most-specific (longest) pattern wins. // Most-specific (longest) pattern wins.
var h Handler; var h Handler;
...@@ -297,11 +341,12 @@ func (mux *ServeMux) ServeHTTP(c *Conn, req *Request) { ...@@ -297,11 +341,12 @@ func (mux *ServeMux) ServeHTTP(c *Conn, req *Request) {
} }
} }
if h == nil { if h == nil {
h = NotFoundHandler; h = NotFoundHandler();
} }
h.ServeHTTP(c, req); h.ServeHTTP(c, req);
} }
// Handle registers the handler for the given pattern.
func (mux *ServeMux) Handle(pattern string, handler Handler) { func (mux *ServeMux) Handle(pattern string, handler Handler) {
if pattern == "" || pattern[0] != '/' { if pattern == "" || pattern[0] != '/' {
panicln("http: invalid pattern", pattern); panicln("http: invalid pattern", pattern);
...@@ -317,12 +362,16 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) { ...@@ -317,12 +362,16 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
} }
} }
func Handle(pattern string, h Handler) { // Handle registers the handler for the given pattern
DefaultServeMux.Handle(pattern, h); // in the DefaultServeMux.
func Handle(pattern string, handler Handler) {
DefaultServeMux.Handle(pattern, handler);
} }
// Serve accepts incoming HTTP connections on the listener l,
// Web server: listening on l, call handler.ServeHTTP for each request. // creating a new service thread for each. The service threads
// read requests and then call handler to reply to them.
// Handler is typically nil, in which case the DefaultServeMux is used.
func Serve(l net.Listener, handler Handler) *os.Error { func Serve(l net.Listener, handler Handler) *os.Error {
if handler == nil { if handler == nil {
handler = DefaultServeMux; handler = DefaultServeMux;
...@@ -341,7 +390,32 @@ func Serve(l net.Listener, handler Handler) *os.Error { ...@@ -341,7 +390,32 @@ func Serve(l net.Listener, handler Handler) *os.Error {
panic("not reached") panic("not reached")
} }
// Web server: listen on address, call f for each request. // ListenAndServe listens on the TCP network address addr
// and then calls Serve with handler to handle requests
// on incoming connections. Handler is typically nil,
// in which case the DefaultServeMux is used.
//
// A trivial example server is:
//
// package main
//
// import (
// "http";
// "io";
// )
//
// // hello world, the web server
// func HelloServer(c *http.Conn, req *http.Request) {
// io.WriteString(c, "hello, world!\n");
// }
//
// func main() {
// http.Handle("/hello", http.HandlerFunc(HelloServer));
// err := http.ListenAndServe(":12345", nil);
// if err != nil {
// panic("ListenAndServe: ", err.String())
// }
// }
func ListenAndServe(addr string, handler Handler) *os.Error { func ListenAndServe(addr string, handler Handler) *os.Error {
l, e := net.Listen("tcp", addr); l, e := net.Listen("tcp", addr);
if e != nil { if e != nil {
......
...@@ -35,14 +35,15 @@ var webroot = flag.String("root", "/home/rsc", "web root directory") ...@@ -35,14 +35,15 @@ var webroot = flag.String("root", "/home/rsc", "web root directory")
func FileServer(c *http.Conn, req *http.Request) { func FileServer(c *http.Conn, req *http.Request) {
c.SetHeader("content-type", "text/plain; charset=utf-8"); c.SetHeader("content-type", "text/plain; charset=utf-8");
path := *webroot + req.Url.Path; // TODO: insecure: use os.CleanName path := *webroot + req.Url.Path; // TODO: insecure: use os.CleanName
fd, err := os.Open(path, os.O_RDONLY, 0); f, err := os.Open(path, os.O_RDONLY, 0);
if err != nil { if err != nil {
c.WriteHeader(http.StatusNotFound); c.WriteHeader(http.StatusNotFound);
fmt.Fprintf(c, "open %s: %v\n", path, err); fmt.Fprintf(c, "open %s: %v\n", path, err);
return; return;
} }
n, err1 := io.Copy(fd, c); n, err1 := io.Copy(f, c);
fmt.Fprintf(c, "[%d bytes]\n", n); fmt.Fprintf(c, "[%d bytes]\n", n);
f.Close();
} }
// simple flag server // simple flag server
......
...@@ -47,14 +47,14 @@ var tests = []tester { ...@@ -47,14 +47,14 @@ var tests = []tester {
// Test using Log("hello", 23, "world") or using Logf("hello %d world", 23) // Test using Log("hello", 23, "world") or using Logf("hello %d world", 23)
func testLog(t *testing.T, flag int, prefix string, pattern string, useLogf bool) { func testLog(t *testing.T, flag int, prefix string, pattern string, useLogf bool) {
fd0, fd1, err1 := os.Pipe(); r, w, err1 := os.Pipe();
if err1 != nil { if err1 != nil {
t.Fatal("pipe", err1); t.Fatal("pipe", err1);
} }
defer fd0.Close(); defer r.Close();
defer fd1.Close(); defer w.Close();
buf := bufio.NewBufRead(fd0); buf := bufio.NewBufRead(r);
l := NewLogger(fd1, nil, prefix, flag); l := NewLogger(w, nil, prefix, flag);
if useLogf { if useLogf {
l.Logf("hello %d world", 23); l.Logf("hello %d world", 23);
} else { } else {
......
...@@ -18,7 +18,7 @@ import ( ...@@ -18,7 +18,7 @@ import (
type netFD struct { type netFD struct {
// immutable until Close // immutable until Close
fd int64; fd int64;
osfd *os.FD; file *os.File;
cr chan *netFD; cr chan *netFD;
cw chan *netFD; cw chan *netFD;
net string; net string;
...@@ -90,7 +90,7 @@ func setBlock(fd int64) { ...@@ -90,7 +90,7 @@ func setBlock(fd int64) {
type pollServer struct { type pollServer struct {
cr, cw chan *netFD; // buffered >= 1 cr, cw chan *netFD; // buffered >= 1
pr, pw *os.FD; pr, pw *os.File;
pending map[int64] *netFD; pending map[int64] *netFD;
poll *pollster; // low-level OS hooks poll *pollster; // low-level OS hooks
deadline int64; // next deadline (nsec since 1970) deadline int64; // next deadline (nsec since 1970)
...@@ -309,14 +309,14 @@ func newFD(fd int64, net, laddr, raddr string) (f *netFD, err *os.Error) { ...@@ -309,14 +309,14 @@ func newFD(fd int64, net, laddr, raddr string) (f *netFD, err *os.Error) {
f.net = net; f.net = net;
f.laddr = laddr; f.laddr = laddr;
f.raddr = raddr; f.raddr = raddr;
f.osfd = os.NewFD(fd, "net: " + net + " " + laddr + " " + raddr); f.file = os.NewFile(fd, "net: " + net + " " + laddr + " " + raddr);
f.cr = make(chan *netFD, 1); f.cr = make(chan *netFD, 1);
f.cw = make(chan *netFD, 1); f.cw = make(chan *netFD, 1);
return f, nil return f, nil
} }
func (fd *netFD) Close() *os.Error { func (fd *netFD) Close() *os.Error {
if fd == nil || fd.osfd == nil { if fd == nil || fd.file == nil {
return os.EINVAL return os.EINVAL
} }
...@@ -326,16 +326,16 @@ func (fd *netFD) Close() *os.Error { ...@@ -326,16 +326,16 @@ func (fd *netFD) Close() *os.Error {
// we can handle the extra OS processes. // we can handle the extra OS processes.
// Otherwise we'll need to use the pollserver // Otherwise we'll need to use the pollserver
// for Close too. Sigh. // for Close too. Sigh.
setBlock(fd.osfd.Fd()); setBlock(fd.file.Fd());
e := fd.osfd.Close(); e := fd.file.Close();
fd.osfd = nil; fd.file = nil;
fd.fd = -1; fd.fd = -1;
return e return e
} }
func (fd *netFD) Read(p []byte) (n int, err *os.Error) { func (fd *netFD) Read(p []byte) (n int, err *os.Error) {
if fd == nil || fd.osfd == nil { if fd == nil || fd.file == nil {
return -1, os.EINVAL return -1, os.EINVAL
} }
fd.rio.Lock(); fd.rio.Lock();
...@@ -345,16 +345,16 @@ func (fd *netFD) Read(p []byte) (n int, err *os.Error) { ...@@ -345,16 +345,16 @@ func (fd *netFD) Read(p []byte) (n int, err *os.Error) {
} else { } else {
fd.rdeadline = 0; fd.rdeadline = 0;
} }
n, err = fd.osfd.Read(p); n, err = fd.file.Read(p);
for err == os.EAGAIN && fd.rdeadline >= 0 { for err == os.EAGAIN && fd.rdeadline >= 0 {
pollserver.WaitRead(fd); pollserver.WaitRead(fd);
n, err = fd.osfd.Read(p) n, err = fd.file.Read(p)
} }
return n, err return n, err
} }
func (fd *netFD) Write(p []byte) (n int, err *os.Error) { func (fd *netFD) Write(p []byte) (n int, err *os.Error) {
if fd == nil || fd.osfd == nil { if fd == nil || fd.file == nil {
return -1, os.EINVAL return -1, os.EINVAL
} }
fd.wio.Lock(); fd.wio.Lock();
...@@ -367,7 +367,7 @@ func (fd *netFD) Write(p []byte) (n int, err *os.Error) { ...@@ -367,7 +367,7 @@ func (fd *netFD) Write(p []byte) (n int, err *os.Error) {
err = nil; err = nil;
nn := 0; nn := 0;
for nn < len(p) { for nn < len(p) {
n, err = fd.osfd.Write(p[nn:len(p)]); n, err = fd.file.Write(p[nn:len(p)]);
if n > 0 { if n > 0 {
nn += n nn += n
} }
...@@ -388,7 +388,7 @@ func (fd *netFD) Write(p []byte) (n int, err *os.Error) { ...@@ -388,7 +388,7 @@ func (fd *netFD) Write(p []byte) (n int, err *os.Error) {
func sockaddrToHostPort(sa *syscall.Sockaddr) (hostport string, err *os.Error) func sockaddrToHostPort(sa *syscall.Sockaddr) (hostport string, err *os.Error)
func (fd *netFD) Accept(sa *syscall.Sockaddr) (nfd *netFD, err *os.Error) { func (fd *netFD) Accept(sa *syscall.Sockaddr) (nfd *netFD, err *os.Error) {
if fd == nil || fd.osfd == nil { if fd == nil || fd.file == nil {
return nil, os.EINVAL return nil, os.EINVAL
} }
......
...@@ -187,11 +187,11 @@ type connBase struct { ...@@ -187,11 +187,11 @@ type connBase struct {
raddr string; raddr string;
} }
func (c *connBase) FD() *os.FD { func (c *connBase) File() *os.File {
if c == nil { if c == nil {
return nil return nil
} }
return c.fd.osfd; return c.fd.file;
} }
func (c *connBase) sysFD() int64 { func (c *connBase) sysFD() int64 {
......
...@@ -13,12 +13,12 @@ import ( ...@@ -13,12 +13,12 @@ import (
) )
type file struct { type file struct {
fd *os.FD; file *os.File;
data []byte; data []byte;
} }
func (f *file) close() { func (f *file) close() {
f.fd.Close() f.file.Close()
} }
func (f *file) getLineFromData() (s string, ok bool) { func (f *file) getLineFromData() (s string, ok bool) {
...@@ -46,7 +46,7 @@ func (f *file) readLine() (s string, ok bool) { ...@@ -46,7 +46,7 @@ func (f *file) readLine() (s string, ok bool) {
} }
if len(f.data) < cap(f.data) { if len(f.data) < cap(f.data) {
ln := len(f.data); ln := len(f.data);
n, err := io.Readn(f.fd, f.data[ln:cap(f.data)]); n, err := io.Readn(f.file, f.data[ln:cap(f.data)]);
if n >= 0 { if n >= 0 {
f.data = f.data[0:ln+n]; f.data = f.data[0:ln+n];
} }
......
...@@ -15,15 +15,15 @@ const ( ...@@ -15,15 +15,15 @@ const (
) )
// Negative count means read until EOF. // Negative count means read until EOF.
func Readdirnames(fd *FD, count int) (names []string, err *os.Error) { func readdirnames(file *File, count int) (names []string, err *os.Error) {
// If this fd has no dirinfo, create one. // If this file has no dirinfo, create one.
if fd.dirinfo == nil { if file.dirinfo == nil {
fd.dirinfo = new(dirInfo); file.dirinfo = new(dirInfo);
// The buffer must be at least a block long. // The buffer must be at least a block long.
// TODO(r): use fstatfs to find fs block size. // TODO(r): use fstatfs to find fs block size.
fd.dirinfo.buf = make([]byte, blockSize); file.dirinfo.buf = make([]byte, blockSize);
} }
d := fd.dirinfo; d := file.dirinfo;
size := count; size := count;
if size < 0 { if size < 0 {
size = 100 size = 100
...@@ -34,7 +34,7 @@ func Readdirnames(fd *FD, count int) (names []string, err *os.Error) { ...@@ -34,7 +34,7 @@ func Readdirnames(fd *FD, count int) (names []string, err *os.Error) {
if d.bufp == d.nbuf { if d.bufp == d.nbuf {
var errno int64; var errno int64;
// Final argument is (basep *int64) and the syscall doesn't take nil. // Final argument is (basep *int64) and the syscall doesn't take nil.
d.nbuf, errno = syscall.Getdirentries(fd.fd, &d.buf[0], int64(len(d.buf)), new(int64)); d.nbuf, errno = syscall.Getdirentries(file.fd, &d.buf[0], int64(len(d.buf)), new(int64));
if d.nbuf < 0 { if d.nbuf < 0 {
return names, os.ErrnoToError(errno) return names, os.ErrnoToError(errno)
} }
......
...@@ -24,15 +24,15 @@ func clen(n []byte) int { ...@@ -24,15 +24,15 @@ func clen(n []byte) int {
} }
// Negative count means read until EOF. // Negative count means read until EOF.
func Readdirnames(fd *FD, count int) (names []string, err *os.Error) { func readdirnames(file *File, count int) (names []string, err *os.Error) {
// If this fd has no dirinfo, create one. // If this file has no dirinfo, create one.
if fd.dirinfo == nil { if file.dirinfo == nil {
fd.dirinfo = new(dirInfo); file.dirinfo = new(dirInfo);
// The buffer must be at least a block long. // The buffer must be at least a block long.
// TODO(r): use fstatfs to find fs block size. // TODO(r): use fstatfs to find fs block size.
fd.dirinfo.buf = make([]byte, blockSize); file.dirinfo.buf = make([]byte, blockSize);
} }
d := fd.dirinfo; d := file.dirinfo;
size := count; size := count;
if size < 0 { if size < 0 {
size = 100 size = 100
...@@ -43,7 +43,7 @@ func Readdirnames(fd *FD, count int) (names []string, err *os.Error) { ...@@ -43,7 +43,7 @@ func Readdirnames(fd *FD, count int) (names []string, err *os.Error) {
if d.bufp == d.nbuf { if d.bufp == d.nbuf {
var errno int64; var errno int64;
dbuf := (*syscall.Dirent)(unsafe.Pointer(&d.buf[0])); dbuf := (*syscall.Dirent)(unsafe.Pointer(&d.buf[0]));
d.nbuf, errno = syscall.Getdents(fd.fd, dbuf, int64(len(d.buf))); d.nbuf, errno = syscall.Getdents(file.fd, dbuf, int64(len(d.buf)));
if d.nbuf < 0 { if d.nbuf < 0 {
return names, os.ErrnoToError(errno) return names, os.ErrnoToError(errno)
} }
......
...@@ -15,7 +15,7 @@ import ( ...@@ -15,7 +15,7 @@ import (
// file descriptors to be set up in the new process: fd[0] will be Unix file // file descriptors to be set up in the new process: fd[0] will be Unix file
// descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil entry // descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil entry
// will cause the child to have no open file descriptor with that index. // will cause the child to have no open file descriptor with that index.
func ForkExec(argv0 string, argv []string, envv []string, fd []*FD) func ForkExec(argv0 string, argv []string, envv []string, fd []*File)
(pid int, err *Error) (pid int, err *Error)
{ {
// Create array of integer (system) fds. // Create array of integer (system) fds.
......
...@@ -11,45 +11,44 @@ import ( ...@@ -11,45 +11,44 @@ import (
"syscall"; "syscall";
) )
// Auxiliary information if the FD describes a directory // Auxiliary information if the File describes a directory
type dirInfo struct { // TODO(r): 6g bug means this can't be private type dirInfo struct { // TODO(r): 6g bug means this can't be private
buf []byte; // buffer for directory I/O buf []byte; // buffer for directory I/O
nbuf int64; // length of buf; return value from Getdirentries nbuf int64; // length of buf; return value from Getdirentries
bufp int64; // location of next record in buf. bufp int64; // location of next record in buf.
} }
// FD represents an open file. // File represents an open file descriptor.
// TODO(r): is FD the right name? Would File be better? type File struct {
type FD struct {
fd int64; fd int64;
name string; name string;
dirinfo *dirInfo; // nil unless directory being read dirinfo *dirInfo; // nil unless directory being read
} }
// Fd returns the integer Unix file descriptor referencing the open file. // Fd returns the integer Unix file descriptor referencing the open file.
func (fd *FD) Fd() int64 { func (file *File) Fd() int64 {
return fd.fd return file.fd
} }
// Name returns the name of the file as presented to Open. // Name returns the name of the file as presented to Open.
func (fd *FD) Name() string { func (file *File) Name() string {
return fd.name return file.name
} }
// NewFD returns a new FD with the given file descriptor and name. // NewFile returns a new File with the given file descriptor and name.
func NewFD(fd int64, name string) *FD { func NewFile(file int64, name string) *File {
if fd < 0 { if file < 0 {
return nil return nil
} }
return &FD{fd, name, nil} return &File{file, name, nil}
} }
// Stdin, Stdout, and Stderr are open FDs pointing to the standard input, // Stdin, Stdout, and Stderr are open Files pointing to the standard input,
// standard output, and standard error file descriptors. // standard output, and standard error file descriptors.
var ( var (
Stdin = NewFD(0, "/dev/stdin"); Stdin = NewFile(0, "/dev/stdin");
Stdout = NewFD(1, "/dev/stdout"); Stdout = NewFile(1, "/dev/stdout");
Stderr = NewFD(2, "/dev/stderr"); Stderr = NewFile(2, "/dev/stderr");
) )
// Flags to Open wrapping those of the underlying system. Not all flags // Flags to Open wrapping those of the underlying system. Not all flags
...@@ -69,9 +68,9 @@ const ( ...@@ -69,9 +68,9 @@ const (
) )
// Open opens the named file with specified flag (O_RDONLY etc.) and perm, (0666 etc.) // Open opens the named file with specified flag (O_RDONLY etc.) and perm, (0666 etc.)
// if applicable. If successful, methods on the returned FD can be used for I/O. // if applicable. If successful, methods on the returned File can be used for I/O.
// It returns the FD and an Error, if any. // It returns the File and an Error, if any.
func Open(name string, flag int, perm int) (fd *FD, err *Error) { func Open(name string, flag int, perm int) (file *File, err *Error) {
r, e := syscall.Open(name, int64(flag | syscall.O_CLOEXEC), int64(perm)); r, e := syscall.Open(name, int64(flag | syscall.O_CLOEXEC), int64(perm));
if e != 0 { if e != 0 {
return nil, ErrnoToError(e); return nil, ErrnoToError(e);
...@@ -83,31 +82,31 @@ func Open(name string, flag int, perm int) (fd *FD, err *Error) { ...@@ -83,31 +82,31 @@ func Open(name string, flag int, perm int) (fd *FD, err *Error) {
syscall.CloseOnExec(r); syscall.CloseOnExec(r);
} }
return NewFD(r, name), ErrnoToError(e) return NewFile(r, name), ErrnoToError(e)
} }
// Close closes the FD, rendering it unusable for I/O. // Close closes the File, rendering it unusable for I/O.
// It returns an Error, if any. // It returns an Error, if any.
func (fd *FD) Close() *Error { func (file *File) Close() *Error {
if fd == nil { if file == nil {
return EINVAL return EINVAL
} }
r, e := syscall.Close(fd.fd); r, e := syscall.Close(file.fd);
fd.fd = -1; // so it can't be closed again file.fd = -1; // so it can't be closed again
return ErrnoToError(e) return ErrnoToError(e)
} }
// Read reads up to len(b) bytes from the FD. // Read reads up to len(b) bytes from the File.
// It returns the number of bytes read and an Error, if any. // It returns the number of bytes read and an Error, if any.
// EOF is signaled by a zero count with a nil Error. // EOF is signaled by a zero count with a nil Error.
// TODO(r): Add Pread, Pwrite (maybe ReadAt, WriteAt). // TODO(r): Add Pread, Pwrite (maybe ReadAt, WriteAt).
func (fd *FD) Read(b []byte) (ret int, err *Error) { func (file *File) Read(b []byte) (ret int, err *Error) {
if fd == nil { if file == nil {
return 0, EINVAL return 0, EINVAL
} }
var r, e int64; var r, e int64;
if len(b) > 0 { // because we access b[0] if len(b) > 0 { // because we access b[0]
r, e = syscall.Read(fd.fd, &b[0], int64(len(b))); r, e = syscall.Read(file.fd, &b[0], int64(len(b)));
if r < 0 { if r < 0 {
r = 0 r = 0
} }
...@@ -115,16 +114,16 @@ func (fd *FD) Read(b []byte) (ret int, err *Error) { ...@@ -115,16 +114,16 @@ func (fd *FD) Read(b []byte) (ret int, err *Error) {
return int(r), ErrnoToError(e) return int(r), ErrnoToError(e)
} }
// Write writes len(b) bytes to the FD. // Write writes len(b) bytes to the File.
// It returns the number of bytes written and an Error, if any. // It returns the number of bytes written and an Error, if any.
// If the byte count differs from len(b), it usually implies an error occurred. // If the byte count differs from len(b), it usually implies an error occurred.
func (fd *FD) Write(b []byte) (ret int, err *Error) { func (file *File) Write(b []byte) (ret int, err *Error) {
if fd == nil { if file == nil {
return 0, EINVAL return 0, EINVAL
} }
var r, e int64; var r, e int64;
if len(b) > 0 { // because we access b[0] if len(b) > 0 { // because we access b[0]
r, e = syscall.Write(fd.fd, &b[0], int64(len(b))); r, e = syscall.Write(file.fd, &b[0], int64(len(b)));
if r < 0 { if r < 0 {
r = 0 r = 0
} }
...@@ -132,16 +131,16 @@ func (fd *FD) Write(b []byte) (ret int, err *Error) { ...@@ -132,16 +131,16 @@ func (fd *FD) Write(b []byte) (ret int, err *Error) {
return int(r), ErrnoToError(e) return int(r), ErrnoToError(e)
} }
// Seek sets the offset for the next Read or Write on FD to offset, interpreted // Seek sets the offset for the next Read or Write on file to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means // according to whence: 0 means relative to the origin of the file, 1 means
// relative to the current offset, and 2 means relative to the end. // relative to the current offset, and 2 means relative to the end.
// It returns the new offset and an Error, if any. // It returns the new offset and an Error, if any.
func (fd *FD) Seek(offset int64, whence int) (ret int64, err *Error) { func (file *File) Seek(offset int64, whence int) (ret int64, err *Error) {
r, e := syscall.Seek(fd.fd, offset, int64(whence)); r, e := syscall.Seek(file.fd, offset, int64(whence));
if e != 0 { if e != 0 {
return -1, ErrnoToError(e) return -1, ErrnoToError(e)
} }
if fd.dirinfo != nil && r != 0 { if file.dirinfo != nil && r != 0 {
return -1, ErrnoToError(syscall.EISDIR) return -1, ErrnoToError(syscall.EISDIR)
} }
return r, nil return r, nil
...@@ -149,20 +148,20 @@ func (fd *FD) Seek(offset int64, whence int) (ret int64, err *Error) { ...@@ -149,20 +148,20 @@ func (fd *FD) Seek(offset int64, whence int) (ret int64, err *Error) {
// WriteString is like Write, but writes the contents of string s rather than // WriteString is like Write, but writes the contents of string s rather than
// an array of bytes. // an array of bytes.
func (fd *FD) WriteString(s string) (ret int, err *Error) { func (file *File) WriteString(s string) (ret int, err *Error) {
if fd == nil { if file == nil {
return 0, EINVAL return 0, EINVAL
} }
r, e := syscall.Write(fd.fd, syscall.StringBytePtr(s), int64(len(s))); r, e := syscall.Write(file.fd, syscall.StringBytePtr(s), int64(len(s)));
if r < 0 { if r < 0 {
r = 0 r = 0
} }
return int(r), ErrnoToError(e) return int(r), ErrnoToError(e)
} }
// Pipe returns a connected pair of FDs; reads from r return bytes written to w. // Pipe returns a connected pair of Files; reads from r return bytes written to w.
// It returns the FDs and an Error, if any. // It returns the files and an Error, if any.
func Pipe() (r *FD, w *FD, err *Error) { func Pipe() (r *File, w *File, err *Error) {
var p [2]int64; var p [2]int64;
// See ../syscall/exec.go for description of lock. // See ../syscall/exec.go for description of lock.
...@@ -176,7 +175,7 @@ func Pipe() (r *FD, w *FD, err *Error) { ...@@ -176,7 +175,7 @@ func Pipe() (r *FD, w *FD, err *Error) {
syscall.CloseOnExec(p[1]); syscall.CloseOnExec(p[1]);
syscall.ForkLock.RUnlock(); syscall.ForkLock.RUnlock();
return NewFD(p[0], "|0"), NewFD(p[1], "|1"), nil return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
} }
// Mkdir creates a new directory with the specified name and permission bits. // Mkdir creates a new directory with the specified name and permission bits.
...@@ -199,15 +198,15 @@ func Stat(name string) (dir *Dir, err *Error) { ...@@ -199,15 +198,15 @@ func Stat(name string) (dir *Dir, err *Error) {
return dirFromStat(name, new(Dir), stat), nil return dirFromStat(name, new(Dir), stat), nil
} }
// Fstat returns the Dir structure describing the file associated with the FD. // Stat returns the Dir structure describing file.
// It returns the Dir and an error, if any. // It returns the Dir and an error, if any.
func Fstat(fd *FD) (dir *Dir, err *Error) { func (file *File) Stat() (dir *Dir, err *Error) {
stat := new(syscall.Stat_t); stat := new(syscall.Stat_t);
r, e := syscall.Fstat(fd.fd, stat); r, e := syscall.Fstat(file.fd, stat);
if e != 0 { if e != 0 {
return nil, ErrnoToError(e) return nil, ErrnoToError(e)
} }
return dirFromStat(fd.name, new(Dir), stat), nil return dirFromStat(file.name, new(Dir), stat), nil
} }
// Lstat returns the Dir structure describing the named file. If the file // Lstat returns the Dir structure describing the named file. If the file
...@@ -224,26 +223,29 @@ func Lstat(name string) (dir *Dir, err *Error) { ...@@ -224,26 +223,29 @@ func Lstat(name string) (dir *Dir, err *Error) {
// Readdirnames has a non-portable implemenation so its code is separated into an // Readdirnames has a non-portable implemenation so its code is separated into an
// operating-system-dependent file. // operating-system-dependent file.
func readdirnames(file *File, count int) (names []string, err *os.Error)
// Readdirnames reads the contents of the directory associated with fd and // Readdirnames reads the contents of the directory associated with file and
// returns an array of up to count names, in directory order. Subsequent // returns an array of up to count names, in directory order. Subsequent
// calls on the same fd will yield further names. // calls on the same file will yield further names.
// A negative count means to read until EOF. // A negative count means to read until EOF.
// It returns the array and an Error, if any. // It returns the array and an Error, if any.
func Readdirnames(fd *FD, count int) (names []string, err *os.Error) func (file *File) Readdirnames(count int) (names []string, err *os.Error) {
return readdirnames(file, count);
}
// Readdir reads the contents of the directory associated with fd and // Readdir reads the contents of the directory associated with file and
// returns an array of up to count Dir structures, in directory order. Subsequent // returns an array of up to count Dir structures, in directory order. Subsequent
// calls on the same fd will yield further Dirs. // calls on the same file will yield further Dirs.
// A negative count means to read until EOF. // A negative count means to read until EOF.
// It returns the array and an Error, if any. // It returns the array and an Error, if any.
func Readdir(fd *FD, count int) (dirs []Dir, err *os.Error) { func (file *File) Readdir(count int) (dirs []Dir, err *os.Error) {
dirname := fd.name; dirname := file.name;
if dirname == "" { if dirname == "" {
dirname = "."; dirname = ".";
} }
dirname += "/"; dirname += "/";
names, err1 := Readdirnames(fd, count); names, err1 := file.Readdirnames(count);
if err1 != nil { if err1 != nil {
return nil, err1 return nil, err1
} }
......
...@@ -29,16 +29,16 @@ var etc = []string{ ...@@ -29,16 +29,16 @@ var etc = []string{
"passwd", "passwd",
} }
func size(file string, t *testing.T) uint64 { func size(name string, t *testing.T) uint64 {
fd, err := Open(file, O_RDONLY, 0); file, err := Open(name, O_RDONLY, 0);
defer fd.Close(); defer file.Close();
if err != nil { if err != nil {
t.Fatal("open failed:", err); t.Fatal("open failed:", err);
} }
var buf [100]byte; var buf [100]byte;
len := 0; len := 0;
for { for {
n, e := fd.Read(buf); n, e := file.Read(buf);
if n < 0 || e != nil { if n < 0 || e != nil {
t.Fatal("read failed:", err); t.Fatal("read failed:", err);
} }
...@@ -65,12 +65,12 @@ func TestStat(t *testing.T) { ...@@ -65,12 +65,12 @@ func TestStat(t *testing.T) {
} }
func TestFstat(t *testing.T) { func TestFstat(t *testing.T) {
fd, err1 := Open("/etc/passwd", O_RDONLY, 0); file, err1 := Open("/etc/passwd", O_RDONLY, 0);
defer fd.Close(); defer file.Close();
if err1 != nil { if err1 != nil {
t.Fatal("open failed:", err1); t.Fatal("open failed:", err1);
} }
dir, err2 := Fstat(fd); dir, err2 := file.Stat();
if err2 != nil { if err2 != nil {
t.Fatal("fstat failed:", err2); t.Fatal("fstat failed:", err2);
} }
...@@ -98,12 +98,12 @@ func TestLstat(t *testing.T) { ...@@ -98,12 +98,12 @@ func TestLstat(t *testing.T) {
} }
func testReaddirnames(dir string, contents []string, t *testing.T) { func testReaddirnames(dir string, contents []string, t *testing.T) {
fd, err := Open(dir, O_RDONLY, 0); file, err := Open(dir, O_RDONLY, 0);
defer fd.Close(); defer file.Close();
if err != nil { if err != nil {
t.Fatalf("open %q failed: %v", dir, err); t.Fatalf("open %q failed: %v", dir, err);
} }
s, err2 := Readdirnames(fd, -1); s, err2 := file.Readdirnames(-1);
if err2 != nil { if err2 != nil {
t.Fatalf("readdirnames %q failed: %v", err2); t.Fatalf("readdirnames %q failed: %v", err2);
} }
...@@ -124,12 +124,12 @@ func testReaddirnames(dir string, contents []string, t *testing.T) { ...@@ -124,12 +124,12 @@ func testReaddirnames(dir string, contents []string, t *testing.T) {
} }
func testReaddir(dir string, contents []string, t *testing.T) { func testReaddir(dir string, contents []string, t *testing.T) {
fd, err := Open(dir, O_RDONLY, 0); file, err := Open(dir, O_RDONLY, 0);
defer fd.Close(); defer file.Close();
if err != nil { if err != nil {
t.Fatalf("open %q failed: %v", dir, err); t.Fatalf("open %q failed: %v", dir, err);
} }
s, err2 := Readdir(fd, -1); s, err2 := file.Readdir(-1);
if err2 != nil { if err2 != nil {
t.Fatalf("readdir %q failed: %v", dir, err2); t.Fatalf("readdir %q failed: %v", dir, err2);
} }
...@@ -160,13 +160,13 @@ func TestReaddir(t *testing.T) { ...@@ -160,13 +160,13 @@ func TestReaddir(t *testing.T) {
} }
// Read the directory one entry at a time. // Read the directory one entry at a time.
func smallReaddirnames(fd *FD, length int, t *testing.T) []string { func smallReaddirnames(file *File, length int, t *testing.T) []string {
names := make([]string, length); names := make([]string, length);
count := 0; count := 0;
for { for {
d, err := Readdirnames(fd, 1); d, err := file.Readdirnames(1);
if err != nil { if err != nil {
t.Fatalf("readdir %q failed: %v", fd.Name(), err); t.Fatalf("readdir %q failed: %v", file.Name(), err);
} }
if len(d) == 0 { if len(d) == 0 {
break break
...@@ -181,20 +181,20 @@ func smallReaddirnames(fd *FD, length int, t *testing.T) []string { ...@@ -181,20 +181,20 @@ func smallReaddirnames(fd *FD, length int, t *testing.T) []string {
// as reading it all at once. // as reading it all at once.
func TestReaddirnamesOneAtATime(t *testing.T) { func TestReaddirnamesOneAtATime(t *testing.T) {
dir := "/usr/bin"; // big directory that doesn't change often. dir := "/usr/bin"; // big directory that doesn't change often.
fd, err := Open(dir, O_RDONLY, 0); file, err := Open(dir, O_RDONLY, 0);
defer fd.Close(); defer file.Close();
if err != nil { if err != nil {
t.Fatalf("open %q failed: %v", dir, err); t.Fatalf("open %q failed: %v", dir, err);
} }
all, err1 := Readdirnames(fd, -1); all, err1 := file.Readdirnames(-1);
if err1 != nil { if err1 != nil {
t.Fatalf("readdirnames %q failed: %v", dir, err1); t.Fatalf("readdirnames %q failed: %v", dir, err1);
} }
fd1, err2 := Open(dir, O_RDONLY, 0); file1, err2 := Open(dir, O_RDONLY, 0);
if err2 != nil { if err2 != nil {
t.Fatalf("open %q failed: %v", dir, err2); t.Fatalf("open %q failed: %v", dir, err2);
} }
small := smallReaddirnames(fd1, len(all)+100, t); // +100 in case we screw up small := smallReaddirnames(file1, len(all)+100, t); // +100 in case we screw up
for i, n := range all { for i, n := range all {
if small[i] != n { if small[i] != n {
t.Errorf("small read %q %q mismatch: %v", small[i], n); t.Errorf("small read %q %q mismatch: %v", small[i], n);
......
...@@ -94,12 +94,13 @@ func myatof32(s string) (f float32, ok bool) { ...@@ -94,12 +94,13 @@ func myatof32(s string) (f float32, ok bool) {
} }
func TestFp(t *testing.T) { func TestFp(t *testing.T) {
fd, err := os.Open("testfp.txt", os.O_RDONLY, 0); f, err := os.Open("testfp.txt", os.O_RDONLY, 0);
if err != nil { if err != nil {
panicln("testfp: open testfp.txt:", err.String()); panicln("testfp: open testfp.txt:", err.String());
} }
defer f.Close();
b := bufio.NewBufRead(fd); b := bufio.NewBufRead(f);
lineno := 0; lineno := 0;
for { for {
......
...@@ -204,13 +204,13 @@ func parseinfo(bytes []byte) (zt []zonetime, err *os.Error) { ...@@ -204,13 +204,13 @@ func parseinfo(bytes []byte) (zt []zonetime, err *os.Error) {
} }
func readfile(name string, max int) (p []byte, err *os.Error) { func readfile(name string, max int) (p []byte, err *os.Error) {
fd, e := os.Open(name, os.O_RDONLY, 0); f, e := os.Open(name, os.O_RDONLY, 0);
if e != nil { if e != nil {
return nil, e; return nil, e;
} }
p = make([]byte, max); p = make([]byte, max);
n, err1 := io.Readn(fd, p); n, err1 := io.Readn(f, p);
fd.Close(); f.Close();
if err1 == nil { // too long if err1 == nil { // too long
return nil, badZoneinfo; return nil, badZoneinfo;
} }
......
...@@ -136,12 +136,10 @@ func Compile(src_file string, flags *Flags) (*AST.Program, int) { ...@@ -136,12 +136,10 @@ func Compile(src_file string, flags *Flags) (*AST.Program, int) {
func fileExists(name string) bool { func fileExists(name string) bool {
fd, err := os.Open(name, os.O_RDONLY, 0); dir, err := os.Stat(name);
defer fd.Close();
return err == nil; return err == nil;
} }
/* /*
func printDep(localset map [string] bool, wset *vector.Vector, decl AST.Decl2) { func printDep(localset map [string] bool, wset *vector.Vector, decl AST.Decl2) {
src := decl.Val.(*AST.BasicLit).Val; src := decl.Val.(*AST.BasicLit).Val;
......
...@@ -57,7 +57,7 @@ func serveDir(c *http.Conn, dirname string) { ...@@ -57,7 +57,7 @@ func serveDir(c *http.Conn, dirname string) {
return; return;
} }
list, err2 := os.Readdir(fd, -1); list, err2 := fd.Readdir(-1);
if err2 != nil { if err2 != nil {
c.WriteHeader(http.StatusNotFound); c.WriteHeader(http.StatusNotFound);
fmt.Fprintf(c, "Error: %v (%s)\n", err2, dirname); fmt.Fprintf(c, "Error: %v (%s)\n", err2, dirname);
......
...@@ -38,13 +38,13 @@ const ( ...@@ -38,13 +38,13 @@ const (
) )
func readfile(filename string) ([]byte, *OS.Error) { func readfile(filename string) ([]byte, *OS.Error) {
fd, err := OS.Open(filename, OS.O_RDONLY, 0); f, err := OS.Open(filename, OS.O_RDONLY, 0);
if err != nil { if err != nil {
return []byte{}, err; return []byte{}, err;
} }
var buf [1<<20]byte; var buf [1<<20]byte;
n, err1 := IO.Readn(fd, buf); n, err1 := IO.Readn(f, buf);
fd.Close(); f.Close();
if err1 == IO.ErrEOF { if err1 == IO.ErrEOF {
err1 = nil; err1 = nil;
} }
......
...@@ -16,14 +16,14 @@ type Template struct { ...@@ -16,14 +16,14 @@ type Template struct {
func (T *Template) Init(filename string) *os.Error { func (T *Template) Init(filename string) *os.Error {
fd, err0 := os.Open(filename, os.O_RDONLY, 0); f, err0 := os.Open(filename, os.O_RDONLY, 0);
defer fd.Close(); defer f.Close();
if err0 != nil { if err0 != nil {
return err0; return err0;
} }
var buf io.ByteBuffer; var buf io.ByteBuffer;
len, err1 := io.Copy(fd, &buf); len, err1 := io.Copy(f, &buf);
if err1 == io.ErrEOF { if err1 == io.ErrEOF {
err1 = nil; err1 = nil;
} }
......
...@@ -25,7 +25,7 @@ func error(format string, params ...) { ...@@ -25,7 +25,7 @@ func error(format string, params ...) {
} }
func untab(name string, src *os.FD, dst *tabwriter.Writer) { func untab(name string, src *os.File, dst *tabwriter.Writer) {
n, err := io.Copy(src, dst); n, err := io.Copy(src, dst);
if err != nil { if err != nil {
error("error while processing %s (%v)", name, err); error("error while processing %s (%v)", name, err);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment