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 #include <string.h>
9
10 #include "nacl_io/kernel_handle.h"
11 #include "nacl_io/kernel_wrap_real.h"
12 #include "nacl_io/log.h"
13
14 namespace nacl_io {
RealNode(Filesystem * filesystem,int real_fd,bool close_on_destroy)15 RealNode::RealNode(Filesystem* filesystem, int real_fd, bool close_on_destroy)
16 : Node(filesystem),
17 real_fd_(real_fd),
18 close_on_destroy_(close_on_destroy)
19 {
20 }
21
Destroy()22 void RealNode::Destroy() {
23 if (close_on_destroy_)
24 _real_close(real_fd_);
25 real_fd_ = -1;
26 }
27
28 // Normal read/write operations on a file
Read(const HandleAttr & attr,void * buf,size_t count,int * out_bytes)29 Error RealNode::Read(const HandleAttr& attr,
30 void* buf,
31 size_t count,
32 int* out_bytes) {
33 int err;
34 *out_bytes = 0;
35
36 if (IsaFile()) {
37 int64_t new_offset;
38 err = _real_lseek(real_fd_, attr.offs, SEEK_SET, &new_offset);
39 if (err) {
40 LOG_WARN("_real_lseek failed: %s\n", strerror(err));
41 return err;
42 }
43 }
44
45 size_t nread;
46 err = _real_read(real_fd_, buf, count, &nread);
47 if (err) {
48 LOG_WARN("_real_read failed: %s\n", strerror(err));
49 return err;
50 }
51
52 *out_bytes = static_cast<int>(nread);
53 return 0;
54 }
55
Write(const HandleAttr & attr,const void * buf,size_t count,int * out_bytes)56 Error RealNode::Write(const HandleAttr& attr,
57 const void* buf,
58 size_t count,
59 int* out_bytes) {
60 int err;
61 *out_bytes = 0;
62
63 if (IsaFile()) {
64 int64_t new_offset;
65 err = _real_lseek(real_fd_, attr.offs, SEEK_SET, &new_offset);
66 if (err) {
67 LOG_WARN("_real_lseek failed: %s\n", strerror(err));
68 return err;
69 }
70 }
71
72 size_t nwrote;
73 err = _real_write(real_fd_, buf, count, &nwrote);
74 if (err) {
75 LOG_WARN("_real_write failed: %s\n", strerror(err));
76 return err;
77 }
78
79 *out_bytes = static_cast<int>(nwrote);
80 return 0;
81 }
82
FTruncate(off_t size)83 Error RealNode::FTruncate(off_t size) {
84 // TODO(binji): what to do here?
85 return ENOSYS;
86 }
87
GetDents(size_t offs,struct dirent * pdir,size_t count,int * out_bytes)88 Error RealNode::GetDents(size_t offs,
89 struct dirent* pdir,
90 size_t count,
91 int* out_bytes) {
92 size_t nread;
93 int err = _real_getdents(real_fd_, pdir, count, &nread);
94 if (err)
95 return err;
96 return nread;
97 }
98
GetStat(struct stat * stat)99 Error RealNode::GetStat(struct stat* stat) {
100 int err = _real_fstat(real_fd_, stat);
101 if (err)
102 return err;
103 // On windows, fstat() of stdin/stdout/stderr returns all zeros
104 // for the permission bits. This can cause problems down the
105 // line. For example, CanOpen() will fail.
106 // TODO(sbc): Fix this within sel_ldr instead.
107 if (S_ISCHR(stat->st_mode) && (stat->st_mode & S_IRWXU) == 0)
108 stat->st_mode |= S_IRWXU;
109 return 0;
110 }
111
Isatty()112 Error RealNode::Isatty() {
113 #ifdef __GLIBC__
114 // isatty is not yet hooked up to the IRT interface under glibc.
115 return ENOTTY;
116 #else
117 int result = 0;
118 int err = _real_isatty(real_fd_, &result);
119 if (err)
120 return err;
121 return 0;
122 #endif
123 }
124
MMap(void * addr,size_t length,int prot,int flags,size_t offset,void ** out_addr)125 Error RealNode::MMap(void* addr,
126 size_t length,
127 int prot,
128 int flags,
129 size_t offset,
130 void** out_addr) {
131 *out_addr = addr;
132 int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset);
133 if (err)
134 return err;
135 return 0;
136 }
137
138 }
139