OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "nacl_io/passthroughfs/real_node.h" | 5 #include "nacl_io/passthroughfs/real_node.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <string.h> |
8 | 9 |
9 #include "nacl_io/kernel_handle.h" | 10 #include "nacl_io/kernel_handle.h" |
10 #include "nacl_io/kernel_wrap_real.h" | 11 #include "nacl_io/kernel_wrap_real.h" |
| 12 #include "nacl_io/log.h" |
11 | 13 |
12 namespace nacl_io { | 14 namespace nacl_io { |
13 RealNode::RealNode(Filesystem* filesystem, int real_fd, bool close_on_destroy) | 15 RealNode::RealNode(Filesystem* filesystem, int real_fd, bool close_on_destroy) |
14 : Node(filesystem), | 16 : Node(filesystem), |
15 real_fd_(real_fd), | 17 real_fd_(real_fd), |
16 close_on_destroy_(close_on_destroy) | 18 close_on_destroy_(close_on_destroy) |
17 { | 19 { |
18 } | 20 } |
19 | 21 |
20 void RealNode::Destroy() { | 22 void RealNode::Destroy() { |
21 if (close_on_destroy_) | 23 if (close_on_destroy_) |
22 _real_close(real_fd_); | 24 _real_close(real_fd_); |
23 real_fd_ = -1; | 25 real_fd_ = -1; |
24 } | 26 } |
25 | 27 |
26 // Normal read/write operations on a file | 28 // Normal read/write operations on a file |
27 Error RealNode::Read(const HandleAttr& attr, | 29 Error RealNode::Read(const HandleAttr& attr, |
28 void* buf, | 30 void* buf, |
29 size_t count, | 31 size_t count, |
30 int* out_bytes) { | 32 int* out_bytes) { |
| 33 int err; |
31 *out_bytes = 0; | 34 *out_bytes = 0; |
32 | 35 |
33 int64_t new_offset; | 36 if (IsaFile()) { |
34 int err = _real_lseek(real_fd_, attr.offs, 0, &new_offset); | 37 int64_t new_offset; |
35 if (err && err != ESPIPE) | 38 err = _real_lseek(real_fd_, attr.offs, SEEK_SET, &new_offset); |
36 return err; | 39 if (err) { |
| 40 LOG_WARN("_real_lseek failed: %s\n", strerror(err)); |
| 41 return err; |
| 42 } |
| 43 } |
37 | 44 |
38 size_t nread; | 45 size_t nread; |
39 err = _real_read(real_fd_, buf, count, &nread); | 46 err = _real_read(real_fd_, buf, count, &nread); |
40 if (err) | 47 if (err) { |
| 48 LOG_WARN("_real_read failed: %s\n", strerror(err)); |
41 return err; | 49 return err; |
| 50 } |
42 | 51 |
43 *out_bytes = static_cast<int>(nread); | 52 *out_bytes = static_cast<int>(nread); |
44 return 0; | 53 return 0; |
45 } | 54 } |
46 | 55 |
47 Error RealNode::Write(const HandleAttr& attr, | 56 Error RealNode::Write(const HandleAttr& attr, |
48 const void* buf, | 57 const void* buf, |
49 size_t count, | 58 size_t count, |
50 int* out_bytes) { | 59 int* out_bytes) { |
51 //nacl_io_log("Real::Write\n"); | |
52 int err; | 60 int err; |
53 *out_bytes = 0; | 61 *out_bytes = 0; |
54 | 62 |
55 int64_t new_offset; | 63 if (IsaFile()) { |
56 err = _real_lseek(real_fd_, attr.offs, 0, &new_offset); | 64 int64_t new_offset; |
57 if (err && err != ESPIPE) | 65 err = _real_lseek(real_fd_, attr.offs, SEEK_SET, &new_offset); |
58 return err; | 66 if (err) { |
| 67 LOG_WARN("_real_lseek failed: %s\n", strerror(err)); |
| 68 return err; |
| 69 } |
| 70 } |
59 | 71 |
60 size_t nwrote; | 72 size_t nwrote; |
61 err = _real_write(real_fd_, buf, count, &nwrote); | 73 err = _real_write(real_fd_, buf, count, &nwrote); |
62 if (err) | 74 if (err) { |
| 75 LOG_WARN("_real_write failed: %s\n", strerror(err)); |
63 return err; | 76 return err; |
| 77 } |
64 | 78 |
65 *out_bytes = static_cast<int>(nwrote); | 79 *out_bytes = static_cast<int>(nwrote); |
66 return 0; | 80 return 0; |
67 } | 81 } |
68 | 82 |
69 Error RealNode::FTruncate(off_t size) { | 83 Error RealNode::FTruncate(off_t size) { |
70 // TODO(binji): what to do here? | 84 // TODO(binji): what to do here? |
71 return ENOSYS; | 85 return ENOSYS; |
72 } | 86 } |
73 | 87 |
74 Error RealNode::GetDents(size_t offs, | 88 Error RealNode::GetDents(size_t offs, |
75 struct dirent* pdir, | 89 struct dirent* pdir, |
76 size_t count, | 90 size_t count, |
77 int* out_bytes) { | 91 int* out_bytes) { |
78 size_t nread; | 92 size_t nread; |
79 int err = _real_getdents(real_fd_, pdir, count, &nread); | 93 int err = _real_getdents(real_fd_, pdir, count, &nread); |
80 if (err) | 94 if (err) |
81 return err; | 95 return err; |
82 return nread; | 96 return nread; |
83 } | 97 } |
84 | 98 |
85 Error RealNode::GetStat(struct stat* stat) { | 99 Error RealNode::GetStat(struct stat* stat) { |
86 int err = _real_fstat(real_fd_, stat); | 100 int err = _real_fstat(real_fd_, stat); |
87 if (err) | 101 if (err) |
88 return 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; |
89 return 0; | 109 return 0; |
90 } | 110 } |
91 | 111 |
92 Error RealNode::Isatty() { | 112 Error RealNode::Isatty() { |
93 #ifdef __GLIBC__ | 113 #ifdef __GLIBC__ |
94 // isatty is not yet hooked up to the IRT interface under glibc. | 114 // isatty is not yet hooked up to the IRT interface under glibc. |
95 return ENOTTY; | 115 return ENOTTY; |
96 #else | 116 #else |
97 int result = 0; | 117 int result = 0; |
98 int err = _real_isatty(real_fd_, &result); | 118 int err = _real_isatty(real_fd_, &result); |
(...skipping 10 matching lines...) Expand all Loading... |
109 size_t offset, | 129 size_t offset, |
110 void** out_addr) { | 130 void** out_addr) { |
111 *out_addr = addr; | 131 *out_addr = addr; |
112 int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset); | 132 int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset); |
113 if (err) | 133 if (err) |
114 return err; | 134 return err; |
115 return 0; | 135 return 0; |
116 } | 136 } |
117 | 137 |
118 } | 138 } |
OLD | NEW |