1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef LIBRARIES_NACL_IO_KERNEL_HANDLE_H_
6#define LIBRARIES_NACL_IO_KERNEL_HANDLE_H_
7
8#include <fcntl.h>
9#include <pthread.h>
10#include <ppapi/c/pp_resource.h>
11
12#include "nacl_io/error.h"
13#include "nacl_io/filesystem.h"
14#include "nacl_io/node.h"
15#include "nacl_io/ossocket.h"
16#include "nacl_io/ostypes.h"
17
18#include "sdk_util/macros.h"
19#include "sdk_util/ref_object.h"
20#include "sdk_util/scoped_ref.h"
21#include "sdk_util/simple_lock.h"
22
23namespace nacl_io {
24
25class SocketNode;
26
27// HandleAttr struct is passed the Node in calls
28// to Read and Write.  It contains handle specific state
29// such as the file offset and the open flags.
30struct HandleAttr {
31  HandleAttr() : offs(0), flags(0) {}
32  bool IsBlocking() const { return !(flags & O_NONBLOCK); }
33
34  off_t offs;
35  int flags;
36};
37
38// KernelHandle provides a reference counted container for the open
39// file information, such as it's filesystem, node, access type and offset.
40// KernelHandle can only be referenced when the KernelProxy lock is held.
41class KernelHandle : public sdk_util::RefObject {
42 public:
43  KernelHandle();
44  KernelHandle(const ScopedFilesystem& fs, const ScopedNode& node);
45  ~KernelHandle();
46
47  Error Init(int open_flags);
48
49  Error Accept(PP_Resource* new_sock, struct sockaddr* addr, socklen_t* len);
50  Error Connect(const struct sockaddr* addr, socklen_t len);
51  Error Fcntl(int request, int* result, ...);
52  Error VFcntl(int request, int* result, va_list args);
53  Error GetDents(struct dirent* pdir, size_t count, int* bytes_written);
54  Error Read(void* buf, size_t nbytes, int* bytes_read);
55  Error Recv(void* buf, size_t len, int flags, int* out_len);
56  Error RecvFrom(void* buf,
57                 size_t len,
58                 int flags,
59                 struct sockaddr* src_addr,
60                 socklen_t* addrlen,
61                 int* out_len);
62  // Assumes |out_offset| is non-NULL.
63  Error Seek(off_t offset, int whence, off_t* out_offset);
64  Error Send(const void* buf, size_t len, int flags, int* out_len);
65  Error SendTo(const void* buf,
66               size_t len,
67               int flags,
68               const struct sockaddr* dest_addr,
69               socklen_t addrlen,
70               int* out_len);
71  Error Write(const void* buf, size_t nbytes, int* bytes_written);
72
73  const ScopedNode& node() { return node_; }
74  const ScopedFilesystem& filesystem() { return filesystem_; }
75
76  const HandleAttr& Attr() { return handle_attr_; }
77
78  int OpenMode() { return handle_attr_.flags & 3; }
79
80 private:
81  // Returns the SocketNode* if this node is a socket otherwise returns
82  // NULL.
83  SocketNode* socket_node();
84
85  ScopedFilesystem filesystem_;
86  ScopedNode node_;
87  sdk_util::SimpleLock handle_lock_;
88  HandleAttr handle_attr_;
89
90  friend class KernelProxy;
91  DISALLOW_COPY_AND_ASSIGN(KernelHandle);
92};
93
94typedef sdk_util::ScopedRef<KernelHandle> ScopedKernelHandle;
95
96}  // namespace nacl_io
97
98#endif  // LIBRARIES_NACL_IO_KERNEL_HANDLE_H_
99