kernel_proxy.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/kernel_proxy.h"
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <assert.h>
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <errno.h>
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <fcntl.h>
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <limits.h>
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <poll.h>
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <pthread.h>
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <stdio.h>
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string.h>
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <sys/time.h>
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <unistd.h>
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <iterator>
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string>
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/host_resolver.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/kernel_handle.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/kernel_wrap_real.h"
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_dev.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_html5fs.h"
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_http.h"
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_mem.h"
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node.h"
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node_pipe.h"
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node_tcp.h"
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_node_udp.h"
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_passthrough.h"
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/mount_stream.h"
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/osmman.h"
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/ossocket.h"
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/osstat.h"
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/path.h"
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/pepper_interface.h"
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "nacl_io/typed_mount_factory.h"
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sdk_util/auto_lock.h"
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sdk_util/ref_object.h"
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sdk_util/string_util.h"
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifndef MAXPATHLEN
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define MAXPATHLEN 256
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace nacl_io {
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::KernelProxy() : dev_(0), ppapi_(NULL),
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             sigwinch_handler_(SIG_IGN),
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             signal_emitter_(new EventEmitter) {
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochKernelProxy::~KernelProxy() {
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Clean up the MountFactories.
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (MountFactoryMap_t::iterator i = factories_.begin();
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       i != factories_.end();
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       ++i) {
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    delete i->second;
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  delete ppapi_;
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochError KernelProxy::Init(PepperInterface* ppapi) {
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Error rtn = 0;
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ppapi_ = ppapi;
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  dev_ = 1;
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  factories_["memfs"] = new TypedMountFactory<MountMem>;
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  factories_["dev"] = new TypedMountFactory<MountDev>;
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>;
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  factories_["httpfs"] = new TypedMountFactory<MountHttp>;
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>;
79
80  int result;
81  result = mount("", "/", "passthroughfs", 0, NULL);
82  if (result != 0) {
83    assert(false);
84    rtn = errno;
85  }
86
87  result = mount("", "/dev", "dev", 0, NULL);
88  if (result != 0) {
89    assert(false);
90    rtn = errno;
91  }
92
93  // Open the first three in order to get STDIN, STDOUT, STDERR
94  int fd;
95  fd = open("/dev/stdin", O_RDONLY);
96  assert(fd == 0);
97  if (fd < 0)
98    rtn = errno;
99
100  fd = open("/dev/stdout", O_WRONLY);
101  assert(fd == 1);
102  if (fd < 0)
103    rtn = errno;
104
105  fd = open("/dev/stderr", O_WRONLY);
106  assert(fd == 2);
107  if (fd < 0)
108    rtn = errno;
109
110#ifdef PROVIDES_SOCKET_API
111  host_resolver_.Init(ppapi_);
112#endif
113
114  StringMap_t args;
115  stream_mount_.reset(new MountStream());
116  result = stream_mount_->Init(0, args, ppapi);
117  if (result != 0) {
118    assert(false);
119    rtn = result;
120  }
121
122  return rtn;
123}
124
125int KernelProxy::open_resource(const char* path) {
126  ScopedMount mnt;
127  Path rel;
128
129  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
130  if (error) {
131    errno = error;
132    return -1;
133  }
134
135  ScopedMountNode node;
136  error = mnt->OpenResource(rel, &node);
137  if (error) {
138    // OpenResource failed, try Open().
139    error = mnt->Open(rel, O_RDONLY, &node);
140    if (error) {
141      errno = error;
142      return -1;
143    }
144  }
145
146  ScopedKernelHandle handle(new KernelHandle(mnt, node));
147  error = handle->Init(O_RDONLY);
148  if (error) {
149    errno = error;
150    return -1;
151  }
152
153  return AllocateFD(handle);
154}
155
156int KernelProxy::open(const char* path, int open_flags) {
157  ScopedMount mnt;
158  ScopedMountNode node;
159
160  Error error = AcquireMountAndNode(path, open_flags, &mnt, &node);
161  if (error) {
162    errno = error;
163    return -1;
164  }
165
166  ScopedKernelHandle handle(new KernelHandle(mnt, node));
167  error = handle->Init(open_flags);
168  if (error) {
169    errno = error;
170    return -1;
171  }
172
173  return AllocateFD(handle);
174}
175
176int KernelProxy::pipe(int pipefds[2]) {
177  MountNodePipe* pipe = new MountNodePipe(stream_mount_.get());
178  ScopedMountNode node(pipe);
179
180  if (pipe->Init(S_IREAD | S_IWRITE) == 0) {
181    ScopedKernelHandle handle0(new KernelHandle(stream_mount_, node));
182    ScopedKernelHandle handle1(new KernelHandle(stream_mount_, node));
183
184    // Should never fail, but...
185    if (handle0->Init(S_IREAD) || handle1->Init(S_IWRITE)) {
186      errno = EACCES;
187      return -1;
188    }
189
190    pipefds[0] = AllocateFD(handle0);
191    pipefds[1] = AllocateFD(handle1);
192    return 0;
193  }
194
195  errno = ENOSYS;
196  return -1;
197}
198
199int KernelProxy::close(int fd) {
200  ScopedKernelHandle handle;
201  Error error = AcquireHandle(fd, &handle);
202  if (error) {
203    errno = error;
204    return -1;
205  }
206
207  // Remove the FD from the process open file descriptor map
208  FreeFD(fd);
209  return 0;
210}
211
212int KernelProxy::dup(int oldfd) {
213  ScopedKernelHandle handle;
214  Error error = AcquireHandle(oldfd, &handle);
215  if (error) {
216    errno = error;
217    return -1;
218  }
219
220  return AllocateFD(handle);
221}
222
223int KernelProxy::dup2(int oldfd, int newfd) {
224  // If it's the same file handle, just return
225  if (oldfd == newfd)
226    return newfd;
227
228  ScopedKernelHandle old_handle;
229  Error error = AcquireHandle(oldfd, &old_handle);
230  if (error) {
231    errno = error;
232    return -1;
233  }
234
235  FreeAndReassignFD(newfd, old_handle);
236  return newfd;
237}
238
239int KernelProxy::chdir(const char* path) {
240  Error error = SetCWD(path);
241  if (error) {
242    errno = error;
243    return -1;
244  }
245  return 0;
246}
247
248char* KernelProxy::getcwd(char* buf, size_t size) {
249  std::string cwd = GetCWD();
250
251  if (size <= 0) {
252    errno = EINVAL;
253    return NULL;
254  }
255
256  // If size is 0, allocate as much as we need.
257  if (size == 0) {
258    size = cwd.size() + 1;
259  }
260
261  // Verify the buffer is large enough
262  if (size <= cwd.size()) {
263    errno = ERANGE;
264    return NULL;
265  }
266
267  // Allocate the buffer if needed
268  if (buf == NULL) {
269    buf = static_cast<char*>(malloc(size));
270  }
271
272  strcpy(buf, cwd.c_str());
273  return buf;
274}
275
276char* KernelProxy::getwd(char* buf) {
277  if (NULL == buf) {
278    errno = EFAULT;
279    return NULL;
280  }
281  return getcwd(buf, MAXPATHLEN);
282}
283
284int KernelProxy::chmod(const char* path, mode_t mode) {
285  int fd = KernelProxy::open(path, O_RDONLY);
286  if (-1 == fd)
287    return -1;
288
289  int result = fchmod(fd, mode);
290  close(fd);
291  return result;
292}
293
294int KernelProxy::chown(const char* path, uid_t owner, gid_t group) {
295  return 0;
296}
297
298int KernelProxy::fchown(int fd, uid_t owner, gid_t group) {
299  return 0;
300}
301
302int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) {
303  return 0;
304}
305
306int KernelProxy::utime(const char* filename, const struct utimbuf* times) {
307  return 0;
308}
309
310int KernelProxy::mkdir(const char* path, mode_t mode) {
311  ScopedMount mnt;
312  Path rel;
313
314  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
315  if (error) {
316    errno = error;
317    return -1;
318  }
319
320  error = mnt->Mkdir(rel, mode);
321  if (error) {
322    errno = error;
323    return -1;
324  }
325
326  return 0;
327}
328
329int KernelProxy::rmdir(const char* path) {
330  ScopedMount mnt;
331  Path rel;
332
333  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
334  if (error) {
335    errno = error;
336    return -1;
337  }
338
339  error = mnt->Rmdir(rel);
340  if (error) {
341    errno = error;
342    return -1;
343  }
344
345  return 0;
346}
347
348int KernelProxy::stat(const char* path, struct stat* buf) {
349  int fd = open(path, O_RDONLY);
350  if (-1 == fd)
351    return -1;
352
353  int result = fstat(fd, buf);
354  close(fd);
355  return result;
356}
357
358
359int KernelProxy::mount(const char* source,
360                       const char* target,
361                       const char* filesystemtype,
362                       unsigned long mountflags,
363                       const void* data) {
364  std::string abs_path = GetAbsParts(target).Join();
365
366  // Find a factory of that type
367  MountFactoryMap_t::iterator factory = factories_.find(filesystemtype);
368  if (factory == factories_.end()) {
369    errno = ENODEV;
370    return -1;
371  }
372
373  // Create a map of settings
374  StringMap_t smap;
375  smap["SOURCE"] = source;
376  smap["TARGET"] = abs_path;
377
378  if (data) {
379    std::vector<std::string> elements;
380    sdk_util::SplitString(static_cast<const char*>(data), ',', &elements);
381
382    for (std::vector<std::string>::const_iterator it = elements.begin();
383         it != elements.end(); ++it) {
384      size_t location = it->find('=');
385      if (location != std::string::npos) {
386        std::string key = it->substr(0, location);
387        std::string val = it->substr(location + 1);
388        smap[key] = val;
389      } else {
390        smap[*it] = "TRUE";
391      }
392    }
393  }
394
395  ScopedMount mnt;
396  Error error = factory->second->CreateMount(dev_++, smap, ppapi_, &mnt);
397  if (error) {
398    errno = error;
399    return -1;
400  }
401
402  error = AttachMountAtPath(mnt, abs_path);
403  if (error) {
404    errno = error;
405    return -1;
406  }
407
408  return 0;
409}
410
411int KernelProxy::umount(const char* path) {
412  Error error = DetachMountAtPath(path);
413  if (error) {
414    errno = error;
415    return -1;
416  }
417  return 0;
418}
419
420ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) {
421  ScopedKernelHandle handle;
422  Error error = AcquireHandle(fd, &handle);
423  if (error) {
424    errno = error;
425    return -1;
426  }
427
428  int cnt = 0;
429  error = handle->Read(buf, nbytes, &cnt);
430  if (error) {
431    errno = error;
432    return -1;
433  }
434
435  return cnt;
436}
437
438ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) {
439  ScopedKernelHandle handle;
440  Error error = AcquireHandle(fd, &handle);
441  if (error) {
442    errno = error;
443    return -1;
444  }
445
446  int cnt = 0;
447  error = handle->Write(buf, nbytes, &cnt);
448  if (error) {
449    errno = error;
450    return -1;
451  }
452
453  return cnt;
454}
455
456int KernelProxy::fstat(int fd, struct stat* buf) {
457  ScopedKernelHandle handle;
458  Error error = AcquireHandle(fd, &handle);
459  if (error) {
460    errno = error;
461    return -1;
462  }
463
464  error = handle->node()->GetStat(buf);
465  if (error) {
466    errno = error;
467    return -1;
468  }
469
470  return 0;
471}
472
473int KernelProxy::getdents(int fd, void* buf, unsigned int count) {
474  ScopedKernelHandle handle;
475  Error error = AcquireHandle(fd, &handle);
476  if (error) {
477    errno = error;
478    return -1;
479  }
480
481  int cnt = 0;
482  error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt);
483  if (error)
484    errno = error;
485
486  return cnt;
487}
488
489int KernelProxy::fchdir(int fd) {
490  errno = ENOSYS;
491  return -1;
492}
493
494int KernelProxy::ftruncate(int fd, off_t length) {
495  ScopedKernelHandle handle;
496  Error error = AcquireHandle(fd, &handle);
497  if (error) {
498    errno = error;
499    return -1;
500  }
501
502  error = handle->node()->FTruncate(length);
503  if (error) {
504    errno = error;
505    return -1;
506  }
507
508  return 0;
509}
510
511int KernelProxy::fsync(int fd) {
512  ScopedKernelHandle handle;
513  Error error = AcquireHandle(fd, &handle);
514  if (error) {
515    errno = error;
516    return -1;
517  }
518
519  error = handle->node()->FSync();
520  if (error) {
521    errno = error;
522    return -1;
523  }
524
525  return 0;
526}
527
528int KernelProxy::fdatasync(int fd) {
529  errno = ENOSYS;
530  return -1;
531}
532
533int KernelProxy::isatty(int fd) {
534  ScopedKernelHandle handle;
535  Error error = AcquireHandle(fd, &handle);
536  if (error) {
537    errno = error;
538    return -1;
539  }
540
541  error = handle->node()->IsaTTY();
542  if (error) {
543    errno = error;
544    return -1;
545  }
546
547  return 0;
548}
549
550int KernelProxy::ioctl(int fd, int request, va_list args) {
551  ScopedKernelHandle handle;
552  Error error = AcquireHandle(fd, &handle);
553  if (error) {
554    errno = error;
555    return -1;
556  }
557
558  error = handle->node()->VIoctl(request, args);
559  if (error) {
560    errno = error;
561    return -1;
562  }
563
564  return 0;
565}
566
567off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
568  ScopedKernelHandle handle;
569  Error error = AcquireHandle(fd, &handle);
570  if (error) {
571    errno = error;
572    return -1;
573  }
574
575  off_t new_offset;
576  error = handle->Seek(offset, whence, &new_offset);
577  if (error) {
578    errno = error;
579    return -1;
580  }
581
582  return new_offset;
583}
584
585int KernelProxy::unlink(const char* path) {
586  ScopedMount mnt;
587  Path rel;
588
589  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
590  if (error) {
591    errno = error;
592    return -1;
593  }
594
595  error = mnt->Unlink(rel);
596  if (error) {
597    errno = error;
598    return -1;
599  }
600
601  return 0;
602}
603
604int KernelProxy::truncate(const char* path, off_t len) {
605  errno = ENOSYS;
606  return -1;
607}
608
609int KernelProxy::lstat(const char* path, struct stat* buf) {
610  errno = ENOSYS;
611  return -1;
612}
613
614int KernelProxy::rename(const char* path, const char* newpath) {
615  errno = ENOSYS;
616  return -1;
617}
618
619int KernelProxy::remove(const char* path) {
620  ScopedMount mnt;
621  Path rel;
622
623  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
624  if (error) {
625    errno = error;
626    return -1;
627  }
628
629  error = mnt->Remove(rel);
630  if (error) {
631    errno = error;
632    return -1;
633  }
634
635  return 0;
636}
637
638// TODO(noelallen): Needs implementation.
639int KernelProxy::fchmod(int fd, int mode) {
640  ScopedKernelHandle handle;
641  Error error = AcquireHandle(fd, &handle);
642  if (error) {
643    errno = error;
644    return -1;
645  }
646
647  return 0;
648}
649
650int KernelProxy::fcntl(int fd, int request, va_list args) {
651  ScopedKernelHandle handle;
652  Error error = AcquireHandle(fd, &handle);
653  if (error) {
654    errno = error;
655    return -1;
656  }
657
658  int rtn = 0;
659  error = handle->VFcntl(request, &rtn, args);
660  if (error) {
661    errno = error;
662    return -1;
663  }
664
665  return rtn;
666}
667
668int KernelProxy::access(const char* path, int amode) {
669  ScopedMount mnt;
670  Path rel;
671
672  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
673  if (error) {
674    errno = error;
675    return -1;
676  }
677
678  error = mnt->Access(rel, amode);
679  if (error) {
680    errno = error;
681    return -1;
682  }
683  return 0;
684}
685
686int KernelProxy::readlink(const char *path, char *buf, size_t count) {
687  errno = EINVAL;
688  return -1;
689}
690
691int KernelProxy::utimes(const char *filename, const struct timeval times[2]) {
692  errno = EINVAL;
693  return -1;
694}
695
696// TODO(noelallen): Needs implementation.
697int KernelProxy::link(const char* oldpath, const char* newpath) {
698  errno = EINVAL;
699  return -1;
700}
701
702int KernelProxy::symlink(const char* oldpath, const char* newpath) {
703  errno = EINVAL;
704  return -1;
705}
706
707void* KernelProxy::mmap(void* addr,
708                        size_t length,
709                        int prot,
710                        int flags,
711                        int fd,
712                        size_t offset) {
713  // We shouldn't be getting anonymous mmaps here.
714  assert((flags & MAP_ANONYMOUS) == 0);
715  assert(fd != -1);
716
717  ScopedKernelHandle handle;
718  Error error = AcquireHandle(fd, &handle);
719  if (error) {
720    errno = error;
721    return MAP_FAILED;
722  }
723
724  void* new_addr;
725  error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr);
726  if (error) {
727    errno = error;
728    return MAP_FAILED;
729  }
730
731  return new_addr;
732}
733
734int KernelProxy::munmap(void* addr, size_t length) {
735  // NOTE: The comment below is from a previous discarded implementation that
736  // tracks mmap'd regions. For simplicity, we no longer do this; because we
737  // "snapshot" the contents of the file in mmap(), and don't support
738  // write-back or updating the mapped region when the file is written, holding
739  // on to the KernelHandle is pointless.
740  //
741  // If we ever do, these threading issues should be considered.
742
743  //
744  // WARNING: this function may be called by free().
745  //
746  // There is a potential deadlock scenario:
747  // Thread 1: open() -> takes lock1 -> free() -> takes lock2
748  // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1
749  //
750  // Note that open() above could be any function that takes a lock that is
751  // shared with munmap (this includes munmap!)
752  //
753  // To prevent this, we avoid taking locks in munmap() that are used by other
754  // nacl_io functions that may call free. Specifically, we only take the
755  // mmap_lock, which is only shared with mmap() above. There is still a
756  // possibility of deadlock if mmap() or munmap() calls free(), so this is not
757  // allowed.
758  //
759  // Unfortunately, munmap still needs to acquire other locks; see the call to
760  // ReleaseHandle below which takes the process lock. This is safe as long as
761  // this is never executed from free() -- we can be reasonably sure this is
762  // true, because malloc only makes anonymous mmap() requests, and should only
763  // be munmapping those allocations. We never add to mmap_info_list_ for
764  // anonymous maps, so the unmap_list should always be empty when called from
765  // free().
766  return 0;
767}
768
769int KernelProxy::tcflush(int fd, int queue_selector) {
770  ScopedKernelHandle handle;
771  Error error = AcquireHandle(fd, &handle);
772  if (error) {
773    errno = error;
774    return -1;
775  }
776
777  error = handle->node()->Tcflush(queue_selector);
778  if (error) {
779    errno = error;
780    return -1;
781  }
782
783  return 0;
784}
785
786int KernelProxy::tcgetattr(int fd, struct termios* termios_p) {
787  ScopedKernelHandle handle;
788  Error error = AcquireHandle(fd, &handle);
789  if (error) {
790    errno = error;
791    return -1;
792  }
793
794  error = handle->node()->Tcgetattr(termios_p);
795  if (error) {
796    errno = error;
797    return -1;
798  }
799
800  return 0;
801}
802
803int KernelProxy::tcsetattr(int fd, int optional_actions,
804                           const struct termios *termios_p) {
805  ScopedKernelHandle handle;
806  Error error = AcquireHandle(fd, &handle);
807  if (error) {
808    errno = error;
809    return -1;
810  }
811
812  error = handle->node()->Tcsetattr(optional_actions, termios_p);
813  if (error) {
814    errno = error;
815    return -1;
816  }
817
818  return 0;
819}
820
821int KernelProxy::kill(pid_t pid, int sig) {
822  // Currently we don't even pretend that other processes exist
823  // so we can only send a signal to outselves.  For kill(2)
824  // pid 0 means the current process group and -1 means all the
825  // processes we have permission to send signals to.
826  if (pid != getpid() && pid != -1 && pid != 0) {
827    errno = ESRCH;
828    return -1;
829  }
830
831  // Raise an event so that select/poll get interrupted.
832  AUTO_LOCK(signal_emitter_->GetLock())
833  signal_emitter_->RaiseEvents_Locked(POLLERR);
834  switch (sig) {
835    case SIGWINCH:
836      if (sigwinch_handler_ != SIG_IGN)
837        sigwinch_handler_(SIGWINCH);
838      break;
839
840    case SIGUSR1:
841    case SIGUSR2:
842      break;
843
844    default:
845      errno = EINVAL;
846      return -1;
847  }
848  return 0;
849}
850
851sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) {
852  switch (signum) {
853    // Handled signals.
854    case SIGWINCH: {
855      sighandler_t old_value = sigwinch_handler_;
856      if (handler == SIG_DFL)
857        handler = SIG_IGN;
858      sigwinch_handler_ = handler;
859      return old_value;
860    }
861
862    // Known signals
863    case SIGHUP:
864    case SIGINT:
865    case SIGKILL:
866    case SIGPIPE:
867    case SIGPOLL:
868    case SIGPROF:
869    case SIGTERM:
870    case SIGCHLD:
871    case SIGURG:
872    case SIGFPE:
873    case SIGILL:
874    case SIGQUIT:
875    case SIGSEGV:
876    case SIGTRAP:
877      if (handler == SIG_DFL)
878        return SIG_DFL;
879      break;
880  }
881
882  errno = EINVAL;
883  return SIG_ERR;
884}
885
886#ifdef PROVIDES_SOCKET_API
887
888int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds,
889                        fd_set* exceptfds, struct timeval* timeout) {
890  fd_set ignore;
891  std::vector<pollfd> pollfds;
892
893  // Simplify logic, by using an IGNORE set for any undefined set
894  FD_ZERO(&ignore);
895  if (NULL == readfds)
896    readfds = &ignore;
897  if (NULL == writefds)
898    writefds = &ignore;
899  if (NULL == exceptfds)
900    exceptfds = &ignore;
901
902  for (int fd = 0; fd < nfds; fd++) {
903    int events = 0;
904    if (FD_ISSET(fd, readfds))
905      events |= POLLIN;
906
907    if (FD_ISSET(fd, writefds))
908      events |= POLLOUT;
909
910    if (FD_ISSET(fd, exceptfds))
911      events |= POLLERR | POLLHUP;
912
913    if (events) {
914      pollfd info;
915      info.fd = fd;
916      info.events = events;
917      pollfds.push_back(info);
918    }
919  }
920
921  FD_ZERO(readfds);
922  FD_ZERO(writefds);
923  FD_ZERO(exceptfds);
924
925  // NULL timeout signals wait forever.
926  int ms_timeout = -1;
927  if (timeout != NULL) {
928    int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000);
929
930    // If the timeout is invalid or too long (larger than signed 32 bit).
931    if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) ||
932        (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) ||
933        (ms < 0) || (ms >= INT_MAX)) {
934      errno = EINVAL;
935      return -1;
936    }
937
938    ms_timeout = static_cast<int>(ms);
939  }
940
941  int result = poll(&pollfds[0], pollfds.size(), ms_timeout);
942  if (result == -1)
943    return -1;
944
945  int event_cnt = 0;
946  for (size_t index = 0; index < pollfds.size(); index++) {
947    pollfd* info = &pollfds[index];
948    if (info->revents & POLLIN) {
949      FD_SET(info->fd, readfds);
950      event_cnt++;
951    }
952    if (info->revents & POLLOUT) {
953      FD_SET(info->fd, writefds);
954      event_cnt++;
955    }
956    if (info->revents & (POLLHUP | POLLERR)) {
957      FD_SET(info->fd, exceptfds);
958      event_cnt++;
959    }
960  }
961
962  return event_cnt;
963}
964
965struct PollInfo {
966  PollInfo() : index(-1) {};
967
968  std::vector<struct pollfd*> fds;
969  int index;
970};
971
972typedef std::map<EventEmitter*, PollInfo> EventPollMap_t;
973
974int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) {
975  EventPollMap_t event_map;
976
977  std::vector<EventRequest> requests;
978  size_t event_cnt = 0;
979
980  for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) {
981    ScopedKernelHandle handle;
982    struct pollfd* fd_info = &fds[index];
983    Error err = AcquireHandle(fd_info->fd, &handle);
984
985    fd_info->revents = 0;
986
987    // If the node isn't open, or somehow invalid, mark it so.
988    if (err != 0) {
989      fd_info->revents = POLLNVAL;
990      event_cnt++;
991      continue;
992    }
993
994    // If it's already signaled, then just capture the event
995    ScopedEventEmitter emitter(handle->node()->GetEventEmitter());
996    int events = POLLIN | POLLOUT;
997    if (emitter)
998      events = emitter->GetEventStatus();
999
1000    if (events & fd_info->events) {
1001      fd_info->revents = events & fd_info->events;
1002      event_cnt++;
1003      continue;
1004    }
1005
1006    if (NULL == emitter) {
1007      fd_info->revents = POLLNVAL;
1008      event_cnt++;
1009      continue;
1010    }
1011
1012    // Otherwise try to track it.
1013    PollInfo* info = &event_map[emitter.get()];
1014    if (info->index == -1) {
1015      EventRequest request;
1016      request.emitter = emitter;
1017      request.filter = fd_info->events;
1018      request.events = 0;
1019
1020      info->index = requests.size();
1021      requests.push_back(request);
1022    }
1023    info->fds.push_back(fd_info);
1024    requests[info->index].filter |= fd_info->events;
1025  }
1026
1027  // If nothing is signaled, then we must wait on the event map
1028  if (0 == event_cnt) {
1029    EventListenerPoll wait;
1030    Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout);
1031    if ((err != 0) && (err != ETIMEDOUT)) {
1032      errno = err;
1033      return -1;
1034    }
1035
1036    for (size_t rindex = 0; rindex < requests.size(); rindex++) {
1037      EventRequest* request = &requests[rindex];
1038      if (request->events) {
1039        PollInfo* poll_info = &event_map[request->emitter.get()];
1040        for (size_t findex = 0; findex < poll_info->fds.size(); findex++) {
1041          struct pollfd* fd_info = poll_info->fds[findex];
1042          uint32_t events = fd_info->events & request->events;
1043          if (events) {
1044            fd_info->revents = events;
1045            event_cnt++;
1046          }
1047        }
1048      }
1049    }
1050  }
1051
1052  return event_cnt;
1053}
1054
1055
1056// Socket Functions
1057int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
1058  if (NULL == addr || NULL == len) {
1059    errno = EFAULT;
1060    return -1;
1061  }
1062
1063  ScopedKernelHandle handle;
1064  Error error = AcquireHandle(fd, &handle);
1065  if (error) {
1066    errno = error;
1067    return -1;
1068  }
1069
1070  PP_Resource new_sock = 0;
1071  error = handle->Accept(&new_sock, addr, len);
1072  if (error != 0) {
1073    errno = error;
1074    return -1;
1075  }
1076
1077  MountNodeSocket* sock = new MountNodeTCP(stream_mount_.get(), new_sock);
1078
1079  // The MountNodeSocket now holds a reference to the new socket
1080  // so we release ours.
1081  ppapi_->ReleaseResource(new_sock);
1082  error = sock->Init(S_IREAD | S_IWRITE);
1083  if (error != 0) {
1084    errno = error;
1085    return -1;
1086  }
1087
1088  ScopedMountNode node(sock);
1089  ScopedKernelHandle new_handle(new KernelHandle(stream_mount_, node));
1090  return AllocateFD(new_handle);
1091}
1092
1093int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) {
1094  if (NULL == addr) {
1095    errno = EFAULT;
1096    return -1;
1097  }
1098
1099  ScopedKernelHandle handle;
1100  if (AcquireSocketHandle(fd, &handle) == -1)
1101    return -1;
1102
1103  Error err = handle->socket_node()->Bind(addr, len);
1104  if (err != 0) {
1105    errno = err;
1106    return -1;
1107  }
1108
1109  return 0;
1110}
1111
1112int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) {
1113  if (NULL == addr) {
1114    errno = EFAULT;
1115    return -1;
1116  }
1117
1118  ScopedKernelHandle handle;
1119  Error error = AcquireHandle(fd, &handle);
1120  if (error) {
1121    errno = error;
1122    return -1;
1123  }
1124
1125  error = handle->Connect(addr, len);
1126  if (error != 0) {
1127    errno = error;
1128    return -1;
1129  }
1130
1131  return 0;
1132}
1133
1134struct hostent* KernelProxy::gethostbyname(const char* name) {
1135  return host_resolver_.gethostbyname(name);
1136}
1137
1138int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
1139  if (NULL == addr || NULL == len) {
1140    errno = EFAULT;
1141    return -1;
1142  }
1143
1144  ScopedKernelHandle handle;
1145  if (AcquireSocketHandle(fd, &handle) == -1)
1146    return -1;
1147
1148  Error err = handle->socket_node()->GetPeerName(addr, len);
1149  if (err != 0) {
1150    errno = err;
1151    return -1;
1152  }
1153
1154  return 0;
1155}
1156
1157int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
1158  if (NULL == addr || NULL == len) {
1159    errno = EFAULT;
1160    return -1;
1161  }
1162
1163  ScopedKernelHandle handle;
1164  if (AcquireSocketHandle(fd, &handle) == -1)
1165    return -1;
1166
1167  Error err = handle->socket_node()->GetSockName(addr, len);
1168  if (err != 0) {
1169    errno = err;
1170    return -1;
1171  }
1172
1173  return 0;
1174}
1175
1176int KernelProxy::getsockopt(int fd,
1177                            int lvl,
1178                            int optname,
1179                            void* optval,
1180                            socklen_t* len) {
1181  if (NULL == optval || NULL == len) {
1182    errno = EFAULT;
1183    return -1;
1184  }
1185
1186  ScopedKernelHandle handle;
1187  if (AcquireSocketHandle(fd, &handle) == -1)
1188    return -1;
1189
1190  Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len);
1191  if (err != 0) {
1192    errno = err;
1193    return -1;
1194  }
1195
1196  return 0;
1197}
1198
1199int KernelProxy::listen(int fd, int backlog) {
1200  ScopedKernelHandle handle;
1201  if (AcquireSocketHandle(fd, &handle) == -1)
1202    return -1;
1203
1204  Error err = handle->socket_node()->Listen(backlog);
1205  if (err != 0) {
1206    errno = err;
1207    return -1;
1208  }
1209
1210  return 0;
1211}
1212
1213ssize_t KernelProxy::recv(int fd,
1214                          void* buf,
1215                          size_t len,
1216                          int flags) {
1217  if (NULL == buf) {
1218    errno = EFAULT;
1219    return -1;
1220  }
1221
1222  ScopedKernelHandle handle;
1223  Error error = AcquireHandle(fd, &handle);
1224  if (error) {
1225    errno = error;
1226    return -1;
1227  }
1228
1229  int out_len = 0;
1230  error = handle->Recv(buf, len, flags, &out_len);
1231  if (error != 0) {
1232    errno = error;
1233    return -1;
1234  }
1235
1236  return static_cast<ssize_t>(out_len);
1237}
1238
1239ssize_t KernelProxy::recvfrom(int fd,
1240                              void* buf,
1241                              size_t len,
1242                              int flags,
1243                              struct sockaddr* addr,
1244                              socklen_t* addrlen) {
1245  // According to the manpage, recvfrom with a null addr is identical to recv.
1246  if (NULL == addr) {
1247    return recv(fd, buf, len, flags);
1248  }
1249
1250  if (NULL == buf || NULL == addrlen) {
1251    errno = EFAULT;
1252    return -1;
1253  }
1254
1255  ScopedKernelHandle handle;
1256  Error error = AcquireHandle(fd, &handle);
1257  if (error) {
1258    errno = error;
1259    return -1;
1260  }
1261
1262  int out_len = 0;
1263  error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len);
1264  if (error != 0) {
1265    errno = error;
1266    return -1;
1267  }
1268
1269  return static_cast<ssize_t>(out_len);
1270}
1271
1272ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) {
1273  if (NULL == msg ) {
1274    errno = EFAULT;
1275    return -1;
1276  }
1277
1278  ScopedKernelHandle handle;
1279  if (AcquireSocketHandle(fd, &handle) == -1)
1280    return -1;
1281
1282  errno = EOPNOTSUPP;
1283  return -1;
1284}
1285
1286ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) {
1287  if (NULL == buf) {
1288    errno = EFAULT;
1289    return -1;
1290  }
1291
1292  ScopedKernelHandle handle;
1293  Error error = AcquireHandle(fd, &handle);
1294  if (error) {
1295    errno = error;
1296    return -1;
1297  }
1298
1299  int out_len = 0;
1300  error = handle->Send(buf, len, flags, &out_len);
1301  if (error != 0) {
1302    errno = error;
1303    return -1;
1304  }
1305
1306  return static_cast<ssize_t>(out_len);
1307}
1308
1309ssize_t KernelProxy::sendto(int fd,
1310                            const void* buf,
1311                            size_t len,
1312                            int flags,
1313                            const struct sockaddr* addr,
1314                            socklen_t addrlen) {
1315  // According to the manpage, sendto with a null addr is identical to send.
1316  if (NULL == addr) {
1317    return send(fd, buf, len, flags);
1318  }
1319
1320  if (NULL == buf) {
1321    errno = EFAULT;
1322    return -1;
1323  }
1324
1325  ScopedKernelHandle handle;
1326  Error error = AcquireHandle(fd, &handle);
1327  if (error) {
1328    errno = error;
1329    return -1;
1330  }
1331
1332  int out_len = 0;
1333  error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len);
1334  if (error != 0) {
1335    errno = error;
1336    return -1;
1337  }
1338
1339  return static_cast<ssize_t>(out_len);
1340}
1341
1342ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) {
1343  if (NULL == msg) {
1344    errno = EFAULT;
1345    return -1;
1346  }
1347
1348  ScopedKernelHandle handle;
1349  if (AcquireSocketHandle(fd, &handle) == -1)
1350    return -1;
1351
1352  errno = EOPNOTSUPP;
1353  return -1;
1354}
1355
1356int KernelProxy::setsockopt(int fd,
1357                            int lvl,
1358                            int optname,
1359                            const void* optval,
1360                            socklen_t len) {
1361  if (NULL == optval) {
1362    errno = EFAULT;
1363    return -1;
1364  }
1365
1366  ScopedKernelHandle handle;
1367  if (AcquireSocketHandle(fd, &handle) == -1)
1368    return -1;
1369
1370  Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len);
1371  if (err != 0) {
1372    errno = err;
1373    return -1;
1374  }
1375
1376  return 0;
1377}
1378
1379int KernelProxy::shutdown(int fd, int how) {
1380  ScopedKernelHandle handle;
1381  if (AcquireSocketHandle(fd, &handle) == -1)
1382    return -1;
1383
1384  Error err = handle->socket_node()->Shutdown(how);
1385  if (err != 0) {
1386    errno = err;
1387    return -1;
1388  }
1389
1390  return 0;
1391}
1392
1393int KernelProxy::socket(int domain, int type, int protocol) {
1394  if (AF_INET != domain && AF_INET6 != domain) {
1395    errno = EAFNOSUPPORT;
1396    return -1;
1397  }
1398
1399  MountNodeSocket* sock = NULL;
1400  switch (type) {
1401    case SOCK_DGRAM:
1402      sock = new MountNodeUDP(stream_mount_.get());
1403      break;
1404
1405    case SOCK_STREAM:
1406      sock = new MountNodeTCP(stream_mount_.get());
1407      break;
1408
1409    default:
1410      errno = EPROTONOSUPPORT;
1411      return -1;
1412  }
1413
1414  ScopedMountNode node(sock);
1415  Error rtn = sock->Init(S_IREAD | S_IWRITE);
1416  if (rtn != 0) {
1417    errno = rtn;
1418    return -1;
1419  }
1420
1421  ScopedKernelHandle handle(new KernelHandle(stream_mount_, node));
1422  return AllocateFD(handle);
1423}
1424
1425int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) {
1426  if (NULL == sv) {
1427    errno = EFAULT;
1428    return -1;
1429  }
1430
1431  // Catch-22: We don't support AF_UNIX, but any other AF doesn't support
1432  // socket pairs. Thus, this function always fails.
1433  if (AF_UNIX != domain) {
1434    errno = EPROTONOSUPPORT;
1435    return -1;
1436  }
1437
1438  if (AF_INET != domain && AF_INET6 != domain) {
1439    errno = EAFNOSUPPORT;
1440    return -1;
1441  }
1442
1443  // We cannot reach this point.
1444  errno = ENOSYS;
1445  return -1;
1446}
1447
1448int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) {
1449  Error error = AcquireHandle(fd, handle);
1450
1451  if (error) {
1452    errno = error;
1453    return -1;
1454  }
1455
1456  if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) {
1457    errno = ENOTSOCK;
1458    return -1;
1459  }
1460
1461  return 0;
1462}
1463
1464#endif  // PROVIDES_SOCKET_API
1465
1466}  // namespace_nacl_io
1467