blob: fcd54d7460bebcbe282de2c919bab41f14ca806e [file] [log] [blame]
// Copyright 2014 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 server provides RPC access to a local program being debugged.
// It is the remote end of the client implementation of the Program interface.
package server
import (
"fmt"
"os"
"code.google.com/p/ogle/program"
"code.google.com/p/ogle/program/proxyrpc"
)
type Server struct {
// TODO: Needs mutex.
files []*file // Index == file descriptor.
}
type file struct {
mode string
index int
f program.File
}
func (s *Server) Open(req *proxyrpc.OpenRequest, resp *proxyrpc.OpenResponse) error {
// TODO: Better simulation. For now we just open the named OS file.
var flag int
switch req.Mode {
case "r":
flag = os.O_RDONLY
case "w":
flag = os.O_WRONLY
case "rw":
flag = os.O_RDWR
default:
return fmt.Errorf("Open: bad open mode %q", req.Mode)
}
osFile, err := os.OpenFile(req.Name, flag, 0)
if err != nil {
return err
}
// Find a file descriptor (index) slot.
index := 0
for ; index < len(s.files) && s.files[index] != nil; index++ {
}
f := &file{
mode: req.Mode,
index: index,
f: osFile,
}
if index == len(s.files) {
s.files = append(s.files, f)
} else {
s.files[index] = f
}
return nil
}
func (s *Server) ReadAt(req *proxyrpc.ReadAtRequest, resp *proxyrpc.ReadAtResponse) error {
fd := req.FD
if fd < 0 || len(s.files) <= fd || s.files[fd] == nil {
return fmt.Errorf("ReadAt: bad file descriptor %d", fd)
}
f := s.files[fd]
buf := make([]byte, req.Len) // TODO: Don't allocate every time
n, err := f.f.ReadAt(buf, req.Offset)
resp.Data = buf[:n]
return err
}
func (s *Server) Close(req *proxyrpc.CloseRequest, resp *proxyrpc.CloseResponse) error {
fd := req.FD
if fd < 0 || fd >= len(s.files) || s.files[fd] == nil {
return fmt.Errorf("Close: bad file descriptor %d", fd)
}
err := s.files[fd].f.Close()
// Remove it regardless
s.files[fd] = nil
return err
}