1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * A NaClDesc subclass that exposes a /dev/null interface.
9 : */
10 :
11 : #include "native_client/src/trusted/desc/nacl_desc_null.h"
12 :
13 : #include <string.h>
14 :
15 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
16 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
17 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
18 :
19 : static struct NaClDescVtbl const kNaClDescNullVtbl; /* fwd */
20 :
21 0 : int NaClDescNullCtor(struct NaClDescNull *self) {
22 0 : if (!NaClDescCtor((struct NaClDesc *) self)) {
23 0 : return 0;
24 : }
25 : NACL_VTBL(NaClRefCount, self) =
26 0 : (struct NaClRefCountVtbl *) &kNaClDescNullVtbl;
27 0 : return 1;
28 0 : }
29 :
30 0 : static void NaClDescNullDtor(struct NaClRefCount *vself) {
31 0 : struct NaClDescNull *self = (struct NaClDescNull *) vself;
32 :
33 0 : NACL_VTBL(NaClDesc, self) = &kNaClDescVtbl;
34 0 : (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
35 0 : }
36 :
37 : static ssize_t NaClDescNullRead(struct NaClDesc *vself,
38 : void *buf,
39 0 : size_t len) {
40 : UNREFERENCED_PARAMETER(vself);
41 : UNREFERENCED_PARAMETER(buf);
42 : UNREFERENCED_PARAMETER(len);
43 :
44 0 : return 0;
45 0 : }
46 :
47 : static ssize_t NaClDescNullWrite(struct NaClDesc *vself,
48 : void const *buf,
49 0 : size_t len) {
50 : UNREFERENCED_PARAMETER(vself);
51 : UNREFERENCED_PARAMETER(buf);
52 :
53 0 : return len;
54 0 : }
55 :
56 : static ssize_t NaClDescNullPRead(struct NaClDesc *vself,
57 : void *buf,
58 : size_t len,
59 0 : nacl_off64_t offset) {
60 : UNREFERENCED_PARAMETER(vself);
61 : UNREFERENCED_PARAMETER(buf);
62 : UNREFERENCED_PARAMETER(len);
63 0 : if (offset < 0) {
64 0 : return -NACL_ABI_EINVAL;
65 : }
66 :
67 0 : return 0;
68 0 : }
69 :
70 : static ssize_t NaClDescNullPWrite(struct NaClDesc *vself,
71 : void const *buf,
72 : size_t len,
73 0 : nacl_off64_t offset) {
74 : UNREFERENCED_PARAMETER(vself);
75 : UNREFERENCED_PARAMETER(buf);
76 0 : if (offset < 0) {
77 0 : return -NACL_ABI_EINVAL;
78 : }
79 :
80 0 : return len;
81 0 : }
82 :
83 : static int NaClDescNullFstat(struct NaClDesc *vself,
84 0 : struct nacl_abi_stat *statbuf) {
85 : UNREFERENCED_PARAMETER(vself);
86 :
87 0 : memset(statbuf, 0, sizeof *statbuf);
88 0 : statbuf->nacl_abi_st_dev = 0;
89 : #if defined(NACL_MASK_INODES)
90 : statbuf->nacl_abi_st_ino = NACL_FAKE_INODE_NUM;
91 : #else
92 0 : statbuf->nacl_abi_st_ino = 0;
93 : #endif
94 0 : statbuf->nacl_abi_st_mode = NACL_ABI_S_IRUSR | NACL_ABI_S_IFCHR;
95 0 : statbuf->nacl_abi_st_nlink = 1;
96 0 : statbuf->nacl_abi_st_uid = -1;
97 0 : statbuf->nacl_abi_st_gid = -1;
98 0 : statbuf->nacl_abi_st_rdev = 0;
99 0 : statbuf->nacl_abi_st_size = 0;
100 0 : statbuf->nacl_abi_st_blksize = 0;
101 0 : statbuf->nacl_abi_st_blocks = 0;
102 0 : statbuf->nacl_abi_st_atime = 0;
103 0 : statbuf->nacl_abi_st_atimensec = 0;
104 0 : statbuf->nacl_abi_st_mtime = 0;
105 0 : statbuf->nacl_abi_st_mtimensec = 0;
106 0 : statbuf->nacl_abi_st_ctime = 0;
107 0 : statbuf->nacl_abi_st_ctimensec = 0;
108 :
109 0 : return 0;
110 0 : }
111 :
112 : /*
113 : * We allow descriptor "transfer", where in reality we create a
114 : * separate null device locally at the recipient end. Read/write
115 : * operations on /dev/null are allowed, but does not make use of flags
116 : * nor are there opportunity to use metadata, so like the invalid
117 : * descriptor, we don't bother to transfer that data.
118 : */
119 : static int NaClDescNullExternalizeSize(struct NaClDesc *vself,
120 : size_t *nbytes,
121 0 : size_t *nhandles) {
122 : UNREFERENCED_PARAMETER(vself);
123 :
124 0 : *nbytes = 0;
125 0 : *nhandles = 0;
126 0 : return 0;
127 0 : }
128 :
129 : static int NaClDescNullExternalize(struct NaClDesc *vself,
130 0 : struct NaClDescXferState *xfer) {
131 : UNREFERENCED_PARAMETER(vself);
132 : UNREFERENCED_PARAMETER(xfer);
133 :
134 0 : return 0;
135 0 : }
136 :
137 : static struct NaClDescVtbl const kNaClDescNullVtbl = {
138 : {
139 : NaClDescNullDtor,
140 : },
141 : NaClDescMapNotImplemented,
142 : NACL_DESC_UNMAP_NOT_IMPLEMENTED
143 : NaClDescNullRead,
144 : NaClDescNullWrite,
145 : NaClDescSeekNotImplemented,
146 : NaClDescNullPRead,
147 : NaClDescNullPWrite,
148 : NaClDescNullFstat,
149 : NaClDescGetdentsNotImplemented,
150 : NaClDescNullExternalizeSize,
151 : NaClDescNullExternalize,
152 : NaClDescLockNotImplemented,
153 : NaClDescTryLockNotImplemented,
154 : NaClDescUnlockNotImplemented,
155 : NaClDescWaitNotImplemented,
156 : NaClDescTimedWaitAbsNotImplemented,
157 : NaClDescSignalNotImplemented,
158 : NaClDescBroadcastNotImplemented,
159 : NaClDescSendMsgNotImplemented,
160 : NaClDescRecvMsgNotImplemented,
161 : NaClDescLowLevelSendMsgNotImplemented,
162 : NaClDescLowLevelRecvMsgNotImplemented,
163 : NaClDescConnectAddrNotImplemented,
164 : NaClDescAcceptConnNotImplemented,
165 : NaClDescPostNotImplemented,
166 : NaClDescSemWaitNotImplemented,
167 : NaClDescGetValueNotImplemented,
168 : NaClDescSetMetadata,
169 : NaClDescGetMetadata,
170 : NaClDescSetFlags,
171 : NaClDescGetFlags,
172 : NaClDescIsattyNotImplemented,
173 : NACL_DESC_NULL,
174 : };
175 :
176 : int NaClDescNullInternalize(struct NaClDesc **out_desc,
177 : struct NaClDescXferState *xfer,
178 0 : struct NaClDescQuotaInterface *quota_interface) {
179 : int rv;
180 0 : struct NaClDescNull *d_null = malloc(sizeof *d_null);
181 :
182 : UNREFERENCED_PARAMETER(xfer);
183 : UNREFERENCED_PARAMETER(quota_interface);
184 0 : if (NULL == d_null) {
185 0 : rv = -NACL_ABI_ENOMEM;
186 0 : goto cleanup;
187 : }
188 0 : if (!NaClDescNullCtor(d_null)) {
189 0 : rv = -NACL_ABI_EIO;
190 0 : goto cleanup;
191 : }
192 0 : *out_desc = (struct NaClDesc *) d_null;
193 0 : rv = 0; /* yay! */
194 : cleanup:
195 0 : return rv;
196 0 : }
|