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 : #include <fcntl.h>
8 : #include <string.h>
9 :
10 : #include <map>
11 : #include <string>
12 : #include <sstream>
13 :
14 : using std::stringstream;
15 : #include "native_client/src/shared/platform/nacl_log.h"
16 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
17 : #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h"
18 : #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
19 : #include "native_client/src/trusted/sel_universal/parsing.h"
20 : #include "native_client/src/trusted/sel_universal/rpc_universal.h"
21 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
22 :
23 :
24 0 : bool HandlerSyncSocketCreate(NaClCommandLoop* ncl,
25 0 : const vector<string>& args) {
26 0 : if (args.size() < 3) {
27 0 : NaClLog(LOG_ERROR, "not enough args\n");
28 0 : return false;
29 : }
30 :
31 0 : NaClHandle handles[2] = {NACL_INVALID_HANDLE, NACL_INVALID_HANDLE};
32 0 : if (NaClSocketPair(handles) != 0) {
33 0 : return false;
34 : }
35 :
36 0 : nacl::DescWrapperFactory factory;
37 0 : nacl::DescWrapper* desc1 = factory.ImportSyncSocketHandle(handles[0]);
38 0 : ncl->AddDesc(desc1->desc(), args[1]);
39 :
40 0 : nacl::DescWrapper* desc2 = factory.ImportSyncSocketHandle(handles[1]);
41 0 : ncl->AddDesc(desc2->desc(), args[2]);
42 0 : return true;
43 0 : }
44 :
45 0 : bool HandlerSyncSocketWrite(NaClCommandLoop* ncl,
46 0 : const vector<string>& args) {
47 0 : if (args.size() < 3) {
48 0 : NaClLog(LOG_ERROR, "not enough args\n");
49 0 : return false;
50 : }
51 :
52 0 : NaClDesc* raw_desc = ExtractDesc(args[1], ncl);
53 0 : if (raw_desc == NULL) {
54 0 : NaClLog(LOG_ERROR, "cannot find desciptor %s\n", args[1].c_str());
55 0 : return false;
56 : }
57 :
58 0 : const int value = ExtractInt32(args[2]);
59 0 : nacl::DescWrapperFactory factory;
60 : // TODO(robertm): eliminate use of NaClDesc in sel_universal and standardize
61 : // on DescWrapper to eliminate the memory leak here
62 0 : factory.MakeGeneric(raw_desc)->Write(&value, sizeof value);
63 0 : return true;
64 0 : }
65 :
66 :
67 : // create a descriptor representing a readonly file
68 0 : bool HandlerReadonlyFile(NaClCommandLoop* ncl, const vector<string>& args) {
69 0 : if (args.size() < 3) {
70 0 : NaClLog(LOG_ERROR, "not enough args\n");
71 0 : return false;
72 : }
73 :
74 0 : nacl::DescWrapperFactory factory;
75 0 : nacl::DescWrapper* desc = factory.OpenHostFile(args[2].c_str(),
76 : NACL_ABI_O_RDONLY, 0);
77 0 : if (NULL == desc) {
78 0 : NaClLog(LOG_ERROR, "cound not create file desc for %s\n", args[2].c_str());
79 0 : return false;
80 : }
81 0 : ncl->AddDesc(desc->desc(), args[1]);
82 0 : return true;
83 0 : }
84 :
85 : // create a descriptor representing a read-write file.
86 : // Used for temporary files created by the pnacl translator.
87 0 : bool HandlerReadwriteFile(NaClCommandLoop* ncl, const vector<string>& args) {
88 0 : if (args.size() < 3) {
89 0 : NaClLog(LOG_ERROR, "not enough args\n");
90 0 : return false;
91 : }
92 :
93 0 : nacl::DescWrapperFactory factory;
94 0 : nacl::DescWrapper* desc =
95 0 : factory.OpenHostFile(args[2].c_str(),
96 : NACL_ABI_O_RDWR | NACL_ABI_O_CREAT, 0666);
97 0 : if (NULL == desc) {
98 0 : NaClLog(LOG_ERROR, "cound not create file desc for %s\n", args[2].c_str());
99 0 : return false;
100 : }
101 0 : ncl->AddDesc(desc->desc(), args[1]);
102 0 : return true;
103 0 : }
104 :
105 : // create a descriptor representing a read-write file with quota management.
106 0 : bool HandlerReadwriteFileQuota(NaClCommandLoop* ncl,
107 0 : const vector<string>& args) {
108 0 : if (args.size() < 3) {
109 0 : NaClLog(LOG_ERROR, "not enough args\n");
110 0 : return false;
111 : }
112 :
113 : static const uint8_t kFileId[] = "SelUniversal000";
114 0 : nacl::DescWrapperFactory factory;
115 0 : nacl::DescWrapper* desc =
116 0 : factory.OpenHostFileQuota(args[2].c_str(),
117 : NACL_ABI_O_RDWR | NACL_ABI_O_CREAT, 0666,
118 : kFileId);
119 0 : if (NULL == desc) {
120 0 : NaClLog(LOG_ERROR, "cound not create file desc for %s\n", args[2].c_str());
121 0 : return false;
122 : }
123 0 : ncl->AddDesc(desc->desc(), args[1]);
124 0 : return true;
125 0 : }
126 :
127 : // sleep for a given number of seconds
128 0 : bool HandlerSleep(NaClCommandLoop* ncl, const vector<string>& args) {
129 0 : UNREFERENCED_PARAMETER(ncl);
130 0 : if (args.size() < 2) {
131 0 : NaClLog(LOG_ERROR, "not enough args\n");
132 0 : return false;
133 : }
134 0 : const int secs = ExtractInt32(args[1]);
135 : #if (NACL_LINUX || NACL_OSX)
136 0 : sleep(secs);
137 : #elif NACL_WINDOWS
138 : Sleep(secs * 1000);
139 : #else
140 : #error "Please specify platform as NACL_LINUX, NACL_OSX or NACL_WINDOWS"
141 : #endif
142 0 : return true;
143 0 : }
144 :
145 : // save a memory region to a file
146 0 : bool HandlerSaveToFile(NaClCommandLoop* ncl, const vector<string>& args) {
147 0 : UNREFERENCED_PARAMETER(ncl);
148 0 : if (args.size() < 5) {
149 0 : NaClLog(LOG_ERROR, "not enough args\n");
150 0 : return false;
151 : }
152 :
153 0 : const char* filename = args[1].c_str();
154 0 : const char* start = reinterpret_cast<char*>(ExtractInt64(args[2]));
155 0 : const int offset = ExtractInt32(args[3]);
156 0 : const int size = ExtractInt32(args[4]);
157 :
158 0 : NaClLog(1, "opening %s\n", filename);
159 0 : FILE* fp = fopen(filename, "wb");
160 0 : if (fp == NULL) {
161 0 : NaClLog(LOG_ERROR, "cannot open %s\n", filename);
162 0 : return false;
163 : }
164 :
165 :
166 0 : NaClLog(1, "writing %d bytes from %p\n", (int) size, start + offset);
167 0 : const size_t n = fwrite(start + offset, 1, size, fp);
168 0 : if (static_cast<int>(n) != size) {
169 0 : NaClLog(LOG_ERROR, "wrote %d bytes, expected %d\n",
170 : static_cast<int>(n), size);
171 0 : fclose(fp);
172 0 : return false;
173 : }
174 0 : fclose(fp);
175 0 : return true;
176 0 : }
177 :
178 : // load file into memory region
179 0 : bool HandlerLoadFromFile(NaClCommandLoop* ncl, const vector<string>& args) {
180 0 : UNREFERENCED_PARAMETER(ncl);
181 0 : if (args.size() < 5) {
182 0 : NaClLog(LOG_ERROR, "not enough args\n");
183 0 : return false;
184 : }
185 :
186 0 : const char* filename = args[1].c_str();
187 0 : char* start = reinterpret_cast<char*>(ExtractInt64(args[2]));
188 0 : const int offset = ExtractInt32(args[3]);
189 0 : const int size = ExtractInt32(args[4]);
190 :
191 0 : NaClLog(1, "opening %s\n", filename);
192 0 : FILE* fp = fopen(filename, "rb");
193 0 : if (fp == NULL) {
194 0 : NaClLog(LOG_ERROR, "cannot open %s\n", filename);
195 0 : return false;
196 : }
197 :
198 0 : NaClLog(1, "loading %d bytes to %p\n", (int) size, start + offset);
199 0 : const size_t n = fread(start + offset, 1, size, fp);
200 0 : if (static_cast<int>(n) != size) {
201 0 : NaClLog(LOG_ERROR, "read %d bytes, expected %d\n",
202 : static_cast<int>(n), size);
203 0 : fclose(fp);
204 0 : return false;
205 : }
206 0 : fclose(fp);
207 0 : return true;
208 0 : }
209 :
210 : // Determine filesize and write it into a variable
211 0 : bool HandlerFileSize(NaClCommandLoop* ncl, const vector<string>& args) {
212 0 : UNREFERENCED_PARAMETER(ncl);
213 0 : if (args.size() < 3) {
214 0 : NaClLog(LOG_ERROR, "not enough args\n");
215 0 : return false;
216 : }
217 :
218 0 : const char* filename = args[1].c_str();
219 0 : FILE* fp = fopen(filename, "rb");
220 0 : if (fp == NULL) {
221 0 : NaClLog(LOG_ERROR, "cannot open %s\n", filename);
222 0 : return false;
223 : }
224 0 : fseek(fp, 0, SEEK_END);
225 0 : int size = static_cast<int>(ftell(fp));
226 0 : fclose(fp);
227 :
228 0 : NaClLog(1, "filesize is %d\n", size);
229 :
230 0 : stringstream str;
231 0 : str << size;
232 0 : ncl->SetVariable(args[2], str.str());
233 0 : return true;
234 0 : }
|