| // 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 |
| |
| } |