root/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIBRARIES_NACL_IO_KERNEL_PROXY_H_
#define LIBRARIES_NACL_IO_KERNEL_PROXY_H_

#include <map>
#include <string>

#include "nacl_io/event_emitter.h"
#include "nacl_io/fs_factory.h"
#include "nacl_io/host_resolver.h"
#include "nacl_io/kernel_object.h"
#include "nacl_io/nacl_io.h"
#include "nacl_io/ossignal.h"
#include "nacl_io/ossocket.h"
#include "nacl_io/ostypes.h"
#include "nacl_io/osutime.h"
#include "nacl_io/stream/stream_fs.h"

struct fuse_operations;
struct timeval;

namespace nacl_io {

class PepperInterface;


// KernelProxy provide one-to-one mapping for libc kernel calls.  Calls to the
// proxy will result in IO access to the provided Filesystem and Node objects.
//
// NOTE: The KernelProxy does not directly take any kernel locks, all locking
// is done by the parent class KernelObject. Instead, KernelProxy is
// responsible for taking the locks of the KernelHandle, and Node objects. For
// this reason, a KernelObject call should not be done while holding a handle
// or node lock. In addition, to ensure locking order, a KernelHandle lock
// must never be taken after taking the associated Node's lock.
//
// NOTE: The KernelProxy is the only class that should be setting errno. All
// other classes should return Error (as defined by nacl_io/error.h).
class KernelProxy : protected KernelObject {
 public:
  typedef std::map<std::string, FsFactory*> FsFactoryMap_t;

  KernelProxy();
  virtual ~KernelProxy();

  // Takes ownership of |ppapi|.
  // |ppapi| may be NULL. If so, no filesystem that uses pepper calls can be
  // mounted.
  virtual Error Init(PepperInterface* ppapi);

  // Register/Unregister a new filesystem type. See the documentation in
  // nacl_io.h for more info.
  bool RegisterFsType(const char* fs_type, fuse_operations* fuse_ops);
  bool UnregisterFsType(const char* fs_type);

  bool RegisterExitHandler(nacl_io_exit_handler_t exit_handler,
                           void* user_data);

  virtual int pipe(int pipefds[2]);

  // NaCl-only function to read resources specified in the NMF file.
  virtual int open_resource(const char* file);

  // KernelHandle and FD allocation and manipulation functions.
  virtual int open(const char* path, int open_flags);
  virtual int close(int fd);
  virtual int dup(int fd);
  virtual int dup2(int fd, int newfd);

  virtual void exit(int status);

  // Path related System calls handled by KernelProxy (not filesystem-specific)
  virtual int chdir(const char* path);
  virtual char* getcwd(char* buf, size_t size);
  virtual char* getwd(char* buf);
  virtual int mount(const char *source,
                    const char *target,
                    const char *filesystemtype,
                    unsigned long mountflags,
                    const void *data);
  virtual int umount(const char *path);

  // Stub system calls that don't do anything (yet), handled by KernelProxy.
  virtual int chown(const char* path, uid_t owner, gid_t group);
  virtual int fchown(int fd, uid_t owner, gid_t group);
  virtual int lchown(const char* path, uid_t owner, gid_t group);
  virtual int utime(const char* filename, const struct utimbuf* times);

  // System calls that take a path as an argument: The kernel proxy will look
  // for the Node associated to the path. To find the node, the kernel proxy
  // calls the corresponding filesystem's GetNode() method. The corresponding
  // method will be called. If the node cannot be found, errno is set and -1 is
  // returned.
  virtual int chmod(const char *path, mode_t mode);
  virtual int mkdir(const char *path, mode_t mode);
  virtual int rmdir(const char *path);
  virtual int stat(const char *path, struct stat *buf);

  // System calls that take a file descriptor as an argument:
  // The kernel proxy will determine to which filesystem the file
  // descriptor's corresponding file handle belongs.  The
  // associated filesystem's function will be called.
  virtual ssize_t read(int fd, void *buf, size_t nbyte);
  virtual ssize_t write(int fd, const void *buf, size_t nbyte);

  virtual int fchmod(int fd, int prot);
  virtual int fcntl(int fd, int request, va_list args);
  virtual int fstat(int fd, struct stat *buf);
  virtual int getdents(int fd, void *buf, unsigned int count);
  virtual int fchdir(int fd);
  virtual int ftruncate(int fd, off_t length);
  virtual int fsync(int fd);
  virtual int fdatasync(int fd);
  virtual int isatty(int fd);
  virtual int ioctl(int fd, int request, va_list args);

  // lseek() relies on the filesystem's Stat() to determine whether or not the
  // file handle corresponding to fd is a directory
  virtual off_t lseek(int fd, off_t offset, int whence);

  // remove() uses the filesystem's GetNode() and Stat() to determine whether
  // or not the path corresponds to a directory or a file. The filesystem's
  // Rmdir() or Unlink() is called accordingly.
  virtual int remove(const char* path);
  // unlink() is a simple wrapper around the filesystem's Unlink function.
  virtual int unlink(const char* path);
  virtual int truncate(const char* path, off_t len);
  virtual int lstat(const char* path, struct stat* buf);
  virtual int rename(const char* path, const char* newpath);
  // access() uses the Filesystem's Stat().
  virtual int access(const char* path, int amode);
  virtual int readlink(const char *path, char *buf, size_t count);
  virtual int utimes(const char *filename, const struct timeval times[2]);

  virtual int link(const char* oldpath, const char* newpath);
  virtual int symlink(const char* oldpath, const char* newpath);

  virtual void* mmap(void* addr,
                     size_t length,
                     int prot,
                     int flags,
                     int fd,
                     size_t offset);
  virtual int munmap(void* addr, size_t length);
  virtual int tcflush(int fd, int queue_selector);
  virtual int tcgetattr(int fd, struct termios* termios_p);
  virtual int tcsetattr(int fd, int optional_actions,
                           const struct termios *termios_p);

  virtual int kill(pid_t pid, int sig);
  virtual int sigaction(int signum, const struct sigaction* action,
                        struct sigaction* oaction);

#ifdef PROVIDES_SOCKET_API
  virtual int select(int nfds, fd_set* readfds, fd_set* writefds,
                    fd_set* exceptfds, struct timeval* timeout);

  virtual int poll(struct pollfd *fds, nfds_t nfds, int timeout);

  // Socket support functions
  virtual int accept(int fd, struct sockaddr* addr, socklen_t* len);
  virtual int bind(int fd, const struct sockaddr* addr, socklen_t len);
  virtual int connect(int fd, const struct sockaddr* addr, socklen_t len);
  virtual struct hostent* gethostbyname(const char* name);
  virtual void freeaddrinfo(struct addrinfo *res);
  virtual int getaddrinfo(const char* node, const char* service,
                          const struct addrinfo* hints,
                          struct addrinfo** res);
  virtual int getpeername(int fd, struct sockaddr* addr, socklen_t* len);
  virtual int getsockname(int fd, struct sockaddr* addr, socklen_t* len);
  virtual int getsockopt(int fd,
                         int lvl,
                         int optname,
                         void* optval,
                         socklen_t* len);
  virtual int listen(int fd, int backlog);
  virtual ssize_t recv(int fd,
                       void* buf,
                       size_t len,
                       int flags);
  virtual ssize_t recvfrom(int fd,
                           void* buf,
                           size_t len,
                           int flags,
                           struct sockaddr* addr,
                           socklen_t* addrlen);
  virtual ssize_t recvmsg(int fd, struct msghdr* msg, int flags);
  virtual ssize_t send(int fd, const void* buf, size_t len, int flags);
  virtual ssize_t sendto(int fd,
                         const void* buf,
                         size_t len,
                         int flags,
                         const struct sockaddr* addr,
                         socklen_t addrlen);
  virtual ssize_t sendmsg(int fd, const struct msghdr* msg, int flags);
  virtual int setsockopt(int fd,
                         int lvl,
                         int optname,
                         const void* optval,
                         socklen_t len);
  virtual int shutdown(int fd, int how);
  virtual int socket(int domain, int type, int protocol);
  virtual int socketpair(int domain, int type, int protocol, int* sv);
#endif  // PROVIDES_SOCKET_API

 protected:
  FsFactoryMap_t factories_;
  sdk_util::ScopedRef<StreamFs> stream_mount_;
  int dev_;
  PepperInterface* ppapi_;
  static KernelProxy *s_instance_;
  struct sigaction sigwinch_handler_;
  nacl_io_exit_handler_t exit_handler_;
  void* exit_handler_user_data_;
#ifdef PROVIDES_SOCKET_API
  HostResolver host_resolver_;
#endif

#ifdef PROVIDES_SOCKET_API
  virtual int AcquireSocketHandle(int fd, ScopedKernelHandle* handle);
#endif

  ScopedEventEmitter signal_emitter_;
  DISALLOW_COPY_AND_ASSIGN(KernelProxy);
};

}  // namespace nacl_io

#endif  // LIBRARIES_NACL_IO_KERNEL_PROXY_H_

/* [<][>][^][v][top][bottom][index][help] */