1// Copyright 2014 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#include "nacl_io/passthroughfs/real_node.h"
6
7#include <errno.h>
8
9#include "nacl_io/kernel_handle.h"
10#include "nacl_io/kernel_wrap_real.h"
11
12namespace nacl_io {
13RealNode::RealNode(Filesystem* filesystem, int real_fd, bool close_on_destroy)
14  : Node(filesystem),
15    real_fd_(real_fd),
16    close_on_destroy_(close_on_destroy)
17{
18}
19
20void RealNode::Destroy() {
21  if (close_on_destroy_)
22    _real_close(real_fd_);
23  real_fd_ = -1;
24}
25
26// Normal read/write operations on a file
27Error RealNode::Read(const HandleAttr& attr,
28                   void* buf,
29                   size_t count,
30                   int* out_bytes) {
31  *out_bytes = 0;
32
33  int64_t new_offset;
34  int err = _real_lseek(real_fd_, attr.offs, 0, &new_offset);
35  if (err && err != ESPIPE)
36    return err;
37
38  size_t nread;
39  err = _real_read(real_fd_, buf, count, &nread);
40  if (err)
41    return err;
42
43  *out_bytes = static_cast<int>(nread);
44  return 0;
45}
46
47Error RealNode::Write(const HandleAttr& attr,
48                      const void* buf,
49                      size_t count,
50                      int* out_bytes) {
51  //nacl_io_log("Real::Write\n");
52  int err;
53  *out_bytes = 0;
54
55  int64_t new_offset;
56  err = _real_lseek(real_fd_, attr.offs, 0, &new_offset);
57  if (err && err != ESPIPE)
58    return err;
59
60  size_t nwrote;
61  err = _real_write(real_fd_, buf, count, &nwrote);
62  if (err)
63    return err;
64
65  *out_bytes = static_cast<int>(nwrote);
66  return 0;
67}
68
69Error RealNode::FTruncate(off_t size) {
70  // TODO(binji): what to do here?
71  return ENOSYS;
72}
73
74Error RealNode::GetDents(size_t offs,
75                         struct dirent* pdir,
76                         size_t count,
77                         int* out_bytes) {
78  size_t nread;
79  int err = _real_getdents(real_fd_, pdir, count, &nread);
80  if (err)
81    return err;
82  return nread;
83}
84
85Error RealNode::GetStat(struct stat* stat) {
86  int err = _real_fstat(real_fd_, stat);
87  if (err)
88    return err;
89  return 0;
90}
91
92Error RealNode::Isatty() {
93#ifdef __GLIBC__
94  // isatty is not yet hooked up to the IRT interface under glibc.
95  return ENOTTY;
96#else
97  int result = 0;
98  int err = _real_isatty(real_fd_, &result);
99  if (err)
100    return err;
101  return 0;
102#endif
103}
104
105Error RealNode::MMap(void* addr,
106                     size_t length,
107                     int prot,
108                     int flags,
109                     size_t offset,
110                     void** out_addr) {
111  *out_addr = addr;
112  int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset);
113  if (err)
114    return err;
115  return 0;
116}
117
118}
119