ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / native_client_sdk / src / libraries / nacl_io / kernel_proxy.cc
blob5329f60aa46089ef233f10224f129d010f9e8e11
1 // Copyright (c) 2012 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.
5 #include "nacl_io/kernel_proxy.h"
7 #include <assert.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <limits.h>
11 #include <poll.h>
12 #include <pthread.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/time.h>
16 #include <unistd.h>
18 #include <iterator>
19 #include <string>
21 #include "nacl_io/devfs/dev_fs.h"
22 #include "nacl_io/filesystem.h"
23 #include "nacl_io/fusefs/fuse_fs_factory.h"
24 #include "nacl_io/host_resolver.h"
25 #include "nacl_io/html5fs/html5_fs.h"
26 #include "nacl_io/httpfs/http_fs.h"
27 #include "nacl_io/kernel_handle.h"
28 #include "nacl_io/kernel_wrap_real.h"
29 #include "nacl_io/log.h"
30 #include "nacl_io/memfs/mem_fs.h"
31 #include "nacl_io/node.h"
32 #include "nacl_io/osinttypes.h"
33 #include "nacl_io/osmman.h"
34 #include "nacl_io/ossocket.h"
35 #include "nacl_io/osstat.h"
36 #include "nacl_io/passthroughfs/passthrough_fs.h"
37 #include "nacl_io/path.h"
38 #include "nacl_io/pepper_interface.h"
39 #include "nacl_io/pipe/pipe_node.h"
40 #include "nacl_io/socket/tcp_node.h"
41 #include "nacl_io/socket/udp_node.h"
42 #include "nacl_io/stream/stream_fs.h"
43 #include "nacl_io/typed_fs_factory.h"
44 #include "sdk_util/auto_lock.h"
45 #include "sdk_util/ref_object.h"
46 #include "sdk_util/string_util.h"
48 #ifndef MAXPATHLEN
49 #define MAXPATHLEN 256
50 #endif
52 namespace nacl_io {
54 KernelProxy::KernelProxy()
55 : dev_(0),
56 ppapi_(NULL),
57 exit_callback_(NULL),
58 exit_callback_user_data_(NULL),
59 mount_callback_(NULL),
60 mount_callback_user_data_(NULL),
61 signal_emitter_(new EventEmitter) {
62 memset(&sigwinch_handler_, 0, sizeof(sigwinch_handler_));
63 sigwinch_handler_.sa_handler = SIG_DFL;
66 KernelProxy::~KernelProxy() {
67 // Clean up the FsFactories.
68 for (FsFactoryMap_t::iterator i = factories_.begin(); i != factories_.end();
69 ++i) {
70 delete i->second;
74 Error KernelProxy::Init(PepperInterface* ppapi) {
75 Error rtn = 0;
76 ppapi_ = ppapi;
77 dev_ = 1;
79 factories_["memfs"] = new TypedFsFactory<MemFs>;
80 factories_["dev"] = new TypedFsFactory<DevFs>;
81 factories_["html5fs"] = new TypedFsFactory<Html5Fs>;
82 factories_["httpfs"] = new TypedFsFactory<HttpFs>;
83 factories_["passthroughfs"] = new TypedFsFactory<PassthroughFs>;
85 ScopedFilesystem root_fs;
86 rtn = MountInternal("", "/", "passthroughfs", 0, NULL, false, &root_fs);
87 if (rtn != 0)
88 return rtn;
90 ScopedFilesystem fs;
91 rtn = MountInternal("", "/dev", "dev", 0, NULL, false, &fs);
92 if (rtn != 0)
93 return rtn;
94 dev_fs_ = sdk_util::static_scoped_ref_cast<DevFs>(fs);
96 // Create the filesystem nodes for / and /dev afterward. They can't be
97 // created the normal way because the dev filesystem didn't exist yet.
98 rtn = CreateFsNode(root_fs);
99 if (rtn != 0)
100 return rtn;
102 rtn = CreateFsNode(dev_fs_);
103 if (rtn != 0)
104 return rtn;
106 // Open the first three in order to get STDIN, STDOUT, STDERR
107 int fd;
108 fd = open("/dev/stdin", O_RDONLY, 0);
109 if (fd < 0) {
110 LOG_ERROR("failed to open /dev/stdin: %s", strerror(errno));
111 return errno;
113 assert(fd == 0);
115 fd = open("/dev/stdout", O_WRONLY, 0);
116 if (fd < 0) {
117 LOG_ERROR("failed to open /dev/stdout: %s", strerror(errno));
118 return errno;
120 assert(fd == 1);
122 fd = open("/dev/stderr", O_WRONLY, 0);
123 if (fd < 0) {
124 LOG_ERROR("failed to open /dev/sterr: %s", strerror(errno));
125 return errno;
127 assert(fd == 2);
129 #ifdef PROVIDES_SOCKET_API
130 host_resolver_.Init(ppapi_);
131 #endif
133 FsInitArgs args;
134 args.dev = dev_++;
135 args.ppapi = ppapi_;
136 stream_fs_.reset(new StreamFs());
137 int result = stream_fs_->Init(args);
138 if (result != 0) {
139 LOG_ERROR("initializing streamfs failed: %s", strerror(result));
140 return result;
143 return 0;
146 bool KernelProxy::RegisterFsType(const char* fs_type,
147 fuse_operations* fuse_ops) {
148 FsFactoryMap_t::iterator iter = factories_.find(fs_type);
149 if (iter != factories_.end())
150 return false;
152 factories_[fs_type] = new FuseFsFactory(fuse_ops);
153 return true;
156 bool KernelProxy::UnregisterFsType(const char* fs_type) {
157 FsFactoryMap_t::iterator iter = factories_.find(fs_type);
158 if (iter == factories_.end())
159 return false;
161 delete iter->second;
162 factories_.erase(iter);
163 return true;
166 void KernelProxy::SetExitCallback(nacl_io_exit_callback_t exit_callback,
167 void* user_data) {
168 exit_callback_ = exit_callback;
169 exit_callback_user_data_ = user_data;
172 void KernelProxy::SetMountCallback(nacl_io_mount_callback_t mount_callback,
173 void* user_data) {
174 mount_callback_ = mount_callback;
175 mount_callback_user_data_ = user_data;
178 int KernelProxy::open_resource(const char* path) {
179 ScopedFilesystem fs;
180 Path rel;
182 Error error = AcquireFsAndRelPath(path, &fs, &rel);
183 if (error) {
184 errno = error;
185 return -1;
188 ScopedNode node;
189 error = fs->OpenResource(rel, &node);
190 if (error) {
191 // OpenResource failed, try Open().
192 error = fs->Open(rel, O_RDONLY, &node);
193 if (error) {
194 errno = error;
195 return -1;
199 ScopedKernelHandle handle(new KernelHandle(fs, node));
200 error = handle->Init(O_RDONLY);
201 if (error) {
202 errno = error;
203 return -1;
206 return AllocateFD(handle, path);
209 int KernelProxy::open(const char* path, int open_flags, mode_t mode) {
210 ScopedFilesystem fs;
211 ScopedNode node;
212 mode_t mask = ~GetUmask() & S_MODEBITS;
214 Error error = AcquireFsAndNode(path, open_flags, mode & mask, &fs, &node);
215 if (error) {
216 errno = error;
217 return -1;
220 ScopedKernelHandle handle(new KernelHandle(fs, node));
221 error = handle->Init(open_flags);
222 if (error) {
223 errno = error;
224 return -1;
227 return AllocateFD(handle, path);
230 int KernelProxy::pipe(int pipefds[2]) {
231 PipeNode* pipe = new PipeNode(stream_fs_.get());
232 ScopedNode node(pipe);
234 if (pipe->Init(O_RDWR) == 0) {
235 ScopedKernelHandle handle0(new KernelHandle(stream_fs_, node));
236 ScopedKernelHandle handle1(new KernelHandle(stream_fs_, node));
238 // Should never fail, but...
239 if (handle0->Init(O_RDONLY) || handle1->Init(O_WRONLY)) {
240 errno = EACCES;
241 return -1;
244 pipefds[0] = AllocateFD(handle0);
245 pipefds[1] = AllocateFD(handle1);
246 return 0;
249 errno = ENOSYS;
250 return -1;
253 int KernelProxy::close(int fd) {
254 ScopedKernelHandle handle;
255 Error error = AcquireHandle(fd, &handle);
256 if (error) {
257 errno = error;
258 return -1;
261 // Remove the FD from the process open file descriptor map
262 FreeFD(fd);
263 return 0;
266 int KernelProxy::dup(int oldfd) {
267 ScopedKernelHandle handle;
268 std::string path;
269 Error error = AcquireHandleAndPath(oldfd, &handle, &path);
270 if (error) {
271 errno = error;
272 return -1;
274 return AllocateFD(handle, path);
277 int KernelProxy::dup2(int oldfd, int newfd) {
278 // If it's the same file handle, just return
279 if (oldfd == newfd)
280 return newfd;
282 if (newfd < 0) {
283 errno = EBADF;
284 return -1;
287 ScopedKernelHandle old_handle;
288 std::string old_path;
289 Error error = AcquireHandleAndPath(oldfd, &old_handle, &old_path);
290 if (error) {
291 errno = error;
292 return -1;
295 FreeAndReassignFD(newfd, old_handle, old_path);
296 return newfd;
299 int KernelProxy::chdir(const char* path) {
300 Error error = SetCWD(path);
301 if (error) {
302 errno = error;
303 return -1;
305 return 0;
308 void KernelProxy::exit(int status) {
309 if (exit_callback_)
310 exit_callback_(status, exit_callback_user_data_);
313 char* KernelProxy::getcwd(char* buf, size_t size) {
314 if (NULL == buf) {
315 errno = EFAULT;
316 return NULL;
319 std::string cwd = GetCWD();
321 // Verify the buffer is large enough
322 if (size <= cwd.size()) {
323 errno = ERANGE;
324 return NULL;
327 strcpy(buf, cwd.c_str());
328 return buf;
331 char* KernelProxy::getwd(char* buf) {
332 if (NULL == buf) {
333 errno = EFAULT;
334 return NULL;
336 return getcwd(buf, MAXPATHLEN);
339 int KernelProxy::chmod(const char* path, mode_t mode) {
340 ScopedFilesystem fs;
341 ScopedNode node;
343 Error error = AcquireFsAndNode(path, O_RDONLY, 0, &fs, &node);
344 if (error) {
345 errno = error;
346 return -1;
349 error = node->Fchmod(mode & S_MODEBITS);
350 if (error) {
351 errno = error;
352 return -1;
355 return 0;
358 int KernelProxy::chown(const char* path, uid_t owner, gid_t group) {
359 return 0;
362 int KernelProxy::fchown(int fd, uid_t owner, gid_t group) {
363 return 0;
366 int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) {
367 return 0;
370 int KernelProxy::mkdir(const char* path, mode_t mode) {
371 ScopedFilesystem fs;
372 Path rel;
374 Error error = AcquireFsAndRelPath(path, &fs, &rel);
375 if (error) {
376 errno = error;
377 return -1;
380 mode_t mask = ~GetUmask() & S_MODEBITS;
381 error = fs->Mkdir(rel, mode & mask);
382 if (error) {
383 errno = error;
384 return -1;
387 return 0;
390 int KernelProxy::rmdir(const char* path) {
391 ScopedFilesystem fs;
392 Path rel;
394 Error error = AcquireFsAndRelPath(path, &fs, &rel);
395 if (error) {
396 errno = error;
397 return -1;
400 error = fs->Rmdir(rel);
401 if (error) {
402 errno = error;
403 return -1;
406 return 0;
409 int KernelProxy::stat(const char* path, struct stat* buf) {
410 ScopedFilesystem fs;
411 ScopedNode node;
413 Error error = AcquireFsAndNode(path, O_RDONLY, 0, &fs, &node);
414 if (error) {
415 errno = error;
416 return -1;
419 error = node->GetStat(buf);
420 if (error) {
421 errno = error;
422 return -1;
425 return 0;
428 int KernelProxy::mount(const char* source,
429 const char* target,
430 const char* filesystemtype,
431 unsigned long mountflags,
432 const void* data) {
433 ScopedFilesystem fs;
434 Error error = MountInternal(
435 source, target, filesystemtype, mountflags, data, true, &fs);
436 if (error) {
437 errno = error;
438 return -1;
441 return 0;
444 Error KernelProxy::MountInternal(const char* source,
445 const char* target,
446 const char* filesystemtype,
447 unsigned long mountflags,
448 const void* data,
449 bool create_fs_node,
450 ScopedFilesystem* out_filesystem) {
451 std::string abs_path = GetAbsParts(target).Join();
453 // Find a factory of that type
454 FsFactoryMap_t::iterator factory = factories_.find(filesystemtype);
455 if (factory == factories_.end()) {
456 LOG_ERROR("Unknown filesystem type: %s", filesystemtype);
457 return ENODEV;
460 // Create a map of settings
461 StringMap_t smap;
462 smap["SOURCE"] = source;
464 if (data) {
465 std::vector<std::string> elements;
466 sdk_util::SplitString(static_cast<const char*>(data), ',', &elements);
468 for (std::vector<std::string>::const_iterator it = elements.begin();
469 it != elements.end();
470 ++it) {
471 size_t location = it->find('=');
472 if (location != std::string::npos) {
473 std::string key = it->substr(0, location);
474 std::string val = it->substr(location + 1);
475 smap[key] = val;
476 } else {
477 smap[*it] = "TRUE";
482 FsInitArgs args;
483 args.dev = dev_++;
484 args.string_map = smap;
485 args.ppapi = ppapi_;
487 ScopedFilesystem fs;
488 Error error = factory->second->CreateFilesystem(args, &fs);
489 if (error)
490 return error;
492 error = AttachFsAtPath(fs, abs_path);
493 if (error)
494 return error;
496 if (create_fs_node) {
497 error = CreateFsNode(fs);
498 if (error) {
499 DetachFsAtPath(abs_path, &fs);
500 return error;
504 *out_filesystem = fs;
506 if (mount_callback_) {
507 mount_callback_(source,
508 target,
509 filesystemtype,
510 mountflags,
511 data,
512 fs->dev(),
513 mount_callback_user_data_);
516 return 0;
519 Error KernelProxy::CreateFsNode(const ScopedFilesystem& fs) {
520 assert(dev_fs_);
522 return dev_fs_->CreateFsNode(fs.get());
525 int KernelProxy::umount(const char* path) {
526 ScopedFilesystem fs;
527 Error error = DetachFsAtPath(path, &fs);
528 if (error) {
529 errno = error;
530 return -1;
533 error = dev_fs_->DestroyFsNode(fs.get());
534 if (error) {
535 // Ignore any errors here, just log.
536 LOG_ERROR("Unable to destroy FsNode: %s", strerror(error));
538 return 0;
541 ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) {
542 ScopedKernelHandle handle;
543 Error error = AcquireHandle(fd, &handle);
544 if (error) {
545 errno = error;
546 return -1;
549 int cnt = 0;
550 error = handle->Read(buf, nbytes, &cnt);
551 if (error) {
552 errno = error;
553 return -1;
556 return cnt;
559 ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) {
560 ScopedKernelHandle handle;
561 Error error = AcquireHandle(fd, &handle);
562 if (error) {
563 errno = error;
564 return -1;
567 int cnt = 0;
568 error = handle->Write(buf, nbytes, &cnt);
569 if (error) {
570 errno = error;
571 return -1;
574 return cnt;
577 int KernelProxy::fstat(int fd, struct stat* buf) {
578 ScopedKernelHandle handle;
579 Error error = AcquireHandle(fd, &handle);
580 if (error) {
581 errno = error;
582 return -1;
585 error = handle->node()->GetStat(buf);
586 if (error) {
587 errno = error;
588 return -1;
591 return 0;
594 int KernelProxy::getdents(int fd, void* buf, unsigned int count) {
595 ScopedKernelHandle handle;
596 Error error = AcquireHandle(fd, &handle);
597 if (error) {
598 errno = error;
599 return -1;
602 int cnt = 0;
603 error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt);
604 if (error)
605 errno = error;
607 return cnt;
610 int KernelProxy::fchdir(int fd) {
611 ScopedKernelHandle handle;
612 std::string path;
613 Error error = AcquireHandleAndPath(fd, &handle, &path);
614 if (error) {
615 errno = error;
616 return -1;
619 if (!handle->node()->IsaDir()) {
620 errno = ENOTDIR;
621 return -1;
624 if (path.empty()) {
625 errno = EBADF;
626 return -1;
629 error = SetCWD(path);
630 if (error) {
631 // errno is return value from SetCWD
632 errno = error;
633 return -1;
635 return 0;
638 int KernelProxy::ftruncate(int fd, off_t length) {
639 ScopedKernelHandle handle;
640 Error error = AcquireHandle(fd, &handle);
641 if (error) {
642 errno = error;
643 return -1;
646 if (handle->OpenMode() == O_RDONLY) {
647 errno = EACCES;
648 return -1;
651 error = handle->node()->FTruncate(length);
652 if (error) {
653 errno = error;
654 return -1;
657 return 0;
660 int KernelProxy::fsync(int fd) {
661 ScopedKernelHandle handle;
662 Error error = AcquireHandle(fd, &handle);
663 if (error) {
664 errno = error;
665 return -1;
668 error = handle->node()->FSync();
669 if (error) {
670 errno = error;
671 return -1;
674 return 0;
677 int KernelProxy::fdatasync(int fd) {
678 errno = ENOSYS;
679 return -1;
682 int KernelProxy::isatty(int fd) {
683 ScopedKernelHandle handle;
684 Error error = AcquireHandle(fd, &handle);
685 if (error) {
686 errno = error;
687 return 0;
690 error = handle->node()->Isatty();
691 if (error) {
692 errno = error;
693 return 0;
696 return 1;
699 int KernelProxy::ioctl(int fd, int request, va_list args) {
700 ScopedKernelHandle handle;
701 Error error = AcquireHandle(fd, &handle);
702 if (error) {
703 errno = error;
704 return -1;
707 error = handle->node()->VIoctl(request, args);
708 if (error) {
709 errno = error;
710 return -1;
713 return 0;
716 int KernelProxy::futimens(int fd, const struct timespec times[2]) {
717 ScopedKernelHandle handle;
718 Error error = AcquireHandle(fd, &handle);
719 if (error) {
720 errno = error;
721 return -1;
724 return FutimensInternal(handle->node(), times);
727 Error KernelProxy::FutimensInternal(const ScopedNode& node,
728 const struct timespec times[2]) {
729 Error error(0);
730 if (times == NULL) {
731 struct timespec now[2];
732 struct timeval tm;
733 error = gettimeofday(&tm, NULL);
734 if (error) {
735 errno = error;
736 return -1;
739 now[0].tv_sec = now[1].tv_sec = tm.tv_sec;
740 now[0].tv_nsec = now[1].tv_nsec = tm.tv_usec * 1000;
741 error = node->Futimens(now);
742 } else {
743 error = node->Futimens(times);
746 if (error) {
747 errno = error;
748 return -1;
751 return 0;
754 off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
755 ScopedKernelHandle handle;
756 Error error = AcquireHandle(fd, &handle);
757 if (error) {
758 errno = error;
759 return -1;
762 off_t new_offset;
763 error = handle->Seek(offset, whence, &new_offset);
764 if (error) {
765 errno = error;
766 return -1;
769 return new_offset;
772 int KernelProxy::unlink(const char* path) {
773 ScopedFilesystem fs;
774 Path rel;
776 Error error = AcquireFsAndRelPath(path, &fs, &rel);
777 if (error) {
778 errno = error;
779 return -1;
782 error = fs->Unlink(rel);
783 if (error) {
784 errno = error;
785 return -1;
788 return 0;
791 int KernelProxy::truncate(const char* path, off_t len) {
792 ScopedFilesystem fs;
793 ScopedNode node;
795 Error error = AcquireFsAndNode(path, O_WRONLY, 0, &fs, &node);
796 if (error) {
797 errno = error;
798 return -1;
801 // Directories cannot be truncated.
802 if (node->IsaDir()) {
803 return EISDIR;
806 if (!node->CanOpen(O_WRONLY)) {
807 errno = EACCES;
808 return -1;
811 error = node->FTruncate(len);
812 if (error) {
813 errno = error;
814 return -1;
817 return 0;
820 int KernelProxy::lstat(const char* path, struct stat* buf) {
821 return stat(path, buf);
824 int KernelProxy::rename(const char* path, const char* newpath) {
825 ScopedFilesystem fs;
826 Path rel;
827 Error error = AcquireFsAndRelPath(path, &fs, &rel);
828 if (error) {
829 errno = error;
830 return -1;
833 ScopedFilesystem newfs;
834 Path newrel;
835 error = AcquireFsAndRelPath(newpath, &newfs, &newrel);
836 if (error) {
837 errno = error;
838 return -1;
841 if (newfs.get() != fs.get()) {
842 // Renaming accross mountpoints is not allowed
843 errno = EXDEV;
844 return -1;
847 // They already point to the same path
848 if (rel == newrel)
849 return 0;
851 error = fs->Rename(rel, newrel);
852 if (error) {
853 errno = error;
854 return -1;
857 return 0;
860 int KernelProxy::remove(const char* path) {
861 ScopedFilesystem fs;
862 Path rel;
864 Error error = AcquireFsAndRelPath(path, &fs, &rel);
865 if (error) {
866 errno = error;
867 return -1;
870 error = fs->Remove(rel);
871 if (error) {
872 errno = error;
873 return -1;
876 return 0;
879 int KernelProxy::fchmod(int fd, mode_t mode) {
880 ScopedKernelHandle handle;
881 Error error = AcquireHandle(fd, &handle);
882 if (error) {
883 errno = error;
884 return -1;
887 error = handle->node()->Fchmod(mode & S_MODEBITS);
888 if (error) {
889 errno = error;
890 return -1;
893 return 0;
896 int KernelProxy::fcntl(int fd, int request, va_list args) {
897 Error error = 0;
899 // F_GETFD and F_SETFD are descriptor specific flags that
900 // are stored in the KernelObject's decriptor map unlike
901 // F_GETFL and F_SETFL which are handle specific.
902 switch (request) {
903 case F_GETFD: {
904 int rtn = -1;
905 error = GetFDFlags(fd, &rtn);
906 if (error) {
907 errno = error;
908 return -1;
910 return rtn;
912 case F_SETFD: {
913 int flags = va_arg(args, int);
914 error = SetFDFlags(fd, flags);
915 if (error) {
916 errno = error;
917 return -1;
919 return 0;
923 ScopedKernelHandle handle;
924 error = AcquireHandle(fd, &handle);
925 if (error) {
926 errno = error;
927 return -1;
930 int rtn = 0;
931 error = handle->VFcntl(request, &rtn, args);
932 if (error) {
933 errno = error;
934 return -1;
937 return rtn;
940 int KernelProxy::access(const char* path, int amode) {
941 struct stat buf;
942 int rtn = stat(path, &buf);
943 if (rtn != 0)
944 return rtn;
946 if (((amode & R_OK) && !(buf.st_mode & S_IREAD)) ||
947 ((amode & W_OK) && !(buf.st_mode & S_IWRITE)) ||
948 ((amode & X_OK) && !(buf.st_mode & S_IEXEC))) {
949 errno = EACCES;
950 return -1;
953 return 0;
956 int KernelProxy::readlink(const char* path, char* buf, size_t count) {
957 LOG_TRACE("readlink is not implemented.");
958 errno = EINVAL;
959 return -1;
962 int KernelProxy::utimens(const char* path, const struct timespec times[2]) {
963 ScopedFilesystem fs;
964 ScopedNode node;
966 Error error = AcquireFsAndNode(path, O_WRONLY, 0, &fs, &node);
967 if (error) {
968 errno = error;
969 return -1;
972 return FutimensInternal(node, times);
975 // TODO(bradnelson): Needs implementation.
976 int KernelProxy::link(const char* oldpath, const char* newpath) {
977 LOG_TRACE("link is not implemented.");
978 errno = EINVAL;
979 return -1;
982 int KernelProxy::symlink(const char* oldpath, const char* newpath) {
983 LOG_TRACE("symlink is not implemented.");
984 errno = EINVAL;
985 return -1;
988 void* KernelProxy::mmap(void* addr,
989 size_t length,
990 int prot,
991 int flags,
992 int fd,
993 size_t offset) {
994 // We shouldn't be getting anonymous mmaps here.
995 assert((flags & MAP_ANONYMOUS) == 0);
996 assert(fd != -1);
998 ScopedKernelHandle handle;
999 Error error = AcquireHandle(fd, &handle);
1000 if (error) {
1001 errno = error;
1002 return MAP_FAILED;
1005 void* new_addr;
1006 error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr);
1007 if (error) {
1008 errno = error;
1009 return MAP_FAILED;
1012 return new_addr;
1015 int KernelProxy::munmap(void* addr, size_t length) {
1016 // NOTE: The comment below is from a previous discarded implementation that
1017 // tracks mmap'd regions. For simplicity, we no longer do this; because we
1018 // "snapshot" the contents of the file in mmap(), and don't support
1019 // write-back or updating the mapped region when the file is written, holding
1020 // on to the KernelHandle is pointless.
1022 // If we ever do, these threading issues should be considered.
1025 // WARNING: this function may be called by free().
1027 // There is a potential deadlock scenario:
1028 // Thread 1: open() -> takes lock1 -> free() -> takes lock2
1029 // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1
1031 // Note that open() above could be any function that takes a lock that is
1032 // shared with munmap (this includes munmap!)
1034 // To prevent this, we avoid taking locks in munmap() that are used by other
1035 // nacl_io functions that may call free. Specifically, we only take the
1036 // mmap_lock, which is only shared with mmap() above. There is still a
1037 // possibility of deadlock if mmap() or munmap() calls free(), so this is not
1038 // allowed.
1040 // Unfortunately, munmap still needs to acquire other locks; see the call to
1041 // ReleaseHandle below which takes the process lock. This is safe as long as
1042 // this is never executed from free() -- we can be reasonably sure this is
1043 // true, because malloc only makes anonymous mmap() requests, and should only
1044 // be munmapping those allocations. We never add to mmap_info_list_ for
1045 // anonymous maps, so the unmap_list should always be empty when called from
1046 // free().
1047 return 0;
1050 int KernelProxy::tcflush(int fd, int queue_selector) {
1051 ScopedKernelHandle handle;
1052 Error error = AcquireHandle(fd, &handle);
1053 if (error) {
1054 errno = error;
1055 return -1;
1058 error = handle->node()->Tcflush(queue_selector);
1059 if (error) {
1060 errno = error;
1061 return -1;
1064 return 0;
1067 int KernelProxy::tcgetattr(int fd, struct termios* termios_p) {
1068 ScopedKernelHandle handle;
1069 Error error = AcquireHandle(fd, &handle);
1070 if (error) {
1071 errno = error;
1072 return -1;
1075 error = handle->node()->Tcgetattr(termios_p);
1076 if (error) {
1077 errno = error;
1078 return -1;
1081 return 0;
1084 int KernelProxy::tcsetattr(int fd,
1085 int optional_actions,
1086 const struct termios* termios_p) {
1087 ScopedKernelHandle handle;
1088 Error error = AcquireHandle(fd, &handle);
1089 if (error) {
1090 errno = error;
1091 return -1;
1094 error = handle->node()->Tcsetattr(optional_actions, termios_p);
1095 if (error) {
1096 errno = error;
1097 return -1;
1100 return 0;
1103 int KernelProxy::kill(pid_t pid, int sig) {
1104 // Currently we don't even pretend that other processes exist
1105 // so we can only send a signal to outselves. For kill(2)
1106 // pid 0 means the current process group and -1 means all the
1107 // processes we have permission to send signals to.
1108 if (pid != getpid() && pid != -1 && pid != 0) {
1109 errno = ESRCH;
1110 return -1;
1113 // Raise an event so that select/poll get interrupted.
1114 AUTO_LOCK(signal_emitter_->GetLock())
1115 signal_emitter_->RaiseEvents_Locked(POLLERR);
1116 switch (sig) {
1117 case SIGWINCH:
1118 if (sigwinch_handler_.sa_handler != SIG_IGN &&
1119 sigwinch_handler_.sa_handler != SIG_DFL) {
1120 sigwinch_handler_.sa_handler(SIGWINCH);
1122 break;
1124 case SIGUSR1:
1125 case SIGUSR2:
1126 break;
1128 default:
1129 LOG_TRACE("Unsupported signal: %d", sig);
1130 errno = EINVAL;
1131 return -1;
1133 return 0;
1136 int KernelProxy::sigaction(int signum,
1137 const struct sigaction* action,
1138 struct sigaction* oaction) {
1139 if (action && action->sa_flags & SA_SIGINFO) {
1140 // We don't support SA_SIGINFO (sa_sigaction field) yet
1141 errno = EINVAL;
1142 return -1;
1145 switch (signum) {
1146 // Handled signals.
1147 case SIGWINCH: {
1148 if (oaction)
1149 *oaction = sigwinch_handler_;
1150 if (action) {
1151 sigwinch_handler_ = *action;
1153 return 0;
1156 // Known signals
1157 case SIGHUP:
1158 case SIGINT:
1159 case SIGPIPE:
1160 #if defined(SIGPOLL)
1161 case SIGPOLL:
1162 #endif
1163 case SIGPROF:
1164 case SIGTERM:
1165 case SIGCHLD:
1166 case SIGURG:
1167 case SIGFPE:
1168 case SIGILL:
1169 case SIGQUIT:
1170 case SIGSEGV:
1171 case SIGTRAP:
1172 if (action && action->sa_handler != SIG_DFL) {
1173 // Trying to set this action to anything other than SIG_DFL
1174 // is not yet supported.
1175 LOG_TRACE("sigaction on signal %d != SIG_DFL not supported.", signum);
1176 errno = EINVAL;
1177 return -1;
1180 if (oaction) {
1181 memset(oaction, 0, sizeof(*oaction));
1182 oaction->sa_handler = SIG_DFL;
1184 return 0;
1186 // KILL and STOP cannot be handled
1187 case SIGKILL:
1188 case SIGSTOP:
1189 LOG_TRACE("sigaction on SIGKILL/SIGSTOP not supported.");
1190 errno = EINVAL;
1191 return -1;
1194 // Unknown signum
1195 errno = EINVAL;
1196 return -1;
1199 mode_t KernelProxy::umask(mode_t mask) {
1200 return SetUmask(mask & S_MODEBITS);
1203 #ifdef PROVIDES_SOCKET_API
1205 int KernelProxy::select(int nfds,
1206 fd_set* readfds,
1207 fd_set* writefds,
1208 fd_set* exceptfds,
1209 struct timeval* timeout) {
1210 std::vector<pollfd> pollfds;
1212 for (int fd = 0; fd < nfds; fd++) {
1213 int events = 0;
1214 if (readfds && FD_ISSET(fd, readfds)) {
1215 events |= POLLIN;
1216 FD_CLR(fd, readfds);
1219 if (writefds && FD_ISSET(fd, writefds)) {
1220 events |= POLLOUT;
1221 FD_CLR(fd, writefds);
1224 if (exceptfds && FD_ISSET(fd, exceptfds)) {
1225 events |= POLLERR | POLLHUP;
1226 FD_CLR(fd, exceptfds);
1229 if (events) {
1230 pollfd info;
1231 info.fd = fd;
1232 info.events = events;
1233 pollfds.push_back(info);
1237 // NULL timeout signals wait forever.
1238 int ms_timeout = -1;
1239 if (timeout != NULL) {
1240 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000);
1242 // If the timeout is invalid or too long (larger than signed 32 bit).
1243 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) ||
1244 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || (ms < 0) ||
1245 (ms >= INT_MAX)) {
1246 LOG_TRACE("Invalid timeout: tv_sec=%" PRIi64 " tv_usec=%ld.",
1247 timeout->tv_sec,
1248 timeout->tv_usec);
1249 errno = EINVAL;
1250 return -1;
1253 ms_timeout = static_cast<int>(ms);
1256 int result = poll(&pollfds[0], pollfds.size(), ms_timeout);
1257 if (result == -1)
1258 return -1;
1260 int event_cnt = 0;
1261 for (size_t index = 0; index < pollfds.size(); index++) {
1262 pollfd* info = &pollfds[index];
1263 if (info->revents & POLLIN) {
1264 FD_SET(info->fd, readfds);
1265 event_cnt++;
1267 if (info->revents & POLLOUT) {
1268 FD_SET(info->fd, writefds);
1269 event_cnt++;
1271 if (info->revents & (POLLHUP | POLLERR)) {
1272 FD_SET(info->fd, exceptfds);
1273 event_cnt++;
1277 return event_cnt;
1280 struct PollInfo {
1281 PollInfo() : index(-1) {};
1283 std::vector<struct pollfd*> fds;
1284 int index;
1287 typedef std::map<EventEmitter*, PollInfo> EventPollMap_t;
1289 int KernelProxy::poll(struct pollfd* fds, nfds_t nfds, int timeout) {
1290 EventPollMap_t event_map;
1292 std::vector<EventRequest> requests;
1293 size_t event_cnt = 0;
1295 for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) {
1296 ScopedKernelHandle handle;
1297 struct pollfd* fd_info = &fds[index];
1298 Error err = AcquireHandle(fd_info->fd, &handle);
1300 fd_info->revents = 0;
1302 // If the node isn't open, or somehow invalid, mark it so.
1303 if (err != 0) {
1304 fd_info->revents = POLLNVAL;
1305 event_cnt++;
1306 continue;
1309 // If it's already signaled, then just capture the event
1310 ScopedEventEmitter emitter(handle->node()->GetEventEmitter());
1311 int events = POLLIN | POLLOUT;
1312 if (emitter)
1313 events = emitter->GetEventStatus();
1315 if (events & fd_info->events) {
1316 fd_info->revents = events & fd_info->events;
1317 event_cnt++;
1318 continue;
1321 if (NULL == emitter) {
1322 fd_info->revents = POLLNVAL;
1323 event_cnt++;
1324 continue;
1327 // Otherwise try to track it.
1328 PollInfo* info = &event_map[emitter.get()];
1329 if (info->index == -1) {
1330 EventRequest request;
1331 request.emitter = emitter;
1332 request.filter = fd_info->events;
1333 request.events = 0;
1335 info->index = requests.size();
1336 requests.push_back(request);
1338 info->fds.push_back(fd_info);
1339 requests[info->index].filter |= fd_info->events;
1342 // If nothing is signaled, then we must wait on the event map
1343 if (0 == event_cnt) {
1344 EventListenerPoll wait;
1345 Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout);
1346 if ((err != 0) && (err != ETIMEDOUT)) {
1347 errno = err;
1348 return -1;
1351 for (size_t rindex = 0; rindex < requests.size(); rindex++) {
1352 EventRequest* request = &requests[rindex];
1353 if (request->events) {
1354 PollInfo* poll_info = &event_map[request->emitter.get()];
1355 for (size_t findex = 0; findex < poll_info->fds.size(); findex++) {
1356 struct pollfd* fd_info = poll_info->fds[findex];
1357 uint32_t events = fd_info->events & request->events;
1358 if (events) {
1359 fd_info->revents = events;
1360 event_cnt++;
1367 return event_cnt;
1370 // Socket Functions
1371 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
1372 ScopedKernelHandle handle;
1373 Error error = AcquireHandle(fd, &handle);
1374 if (error) {
1375 errno = error;
1376 return -1;
1379 PP_Resource new_sock = 0;
1380 error = handle->Accept(&new_sock, addr, len);
1381 if (error != 0) {
1382 errno = error;
1383 return -1;
1386 SocketNode* sock = new TcpNode(stream_fs_.get(), new_sock);
1388 // The SocketNode now holds a reference to the new socket
1389 // so we release ours.
1390 ppapi_->ReleaseResource(new_sock);
1391 error = sock->Init(O_RDWR);
1392 if (error != 0) {
1393 errno = error;
1394 return -1;
1397 ScopedNode node(sock);
1398 ScopedKernelHandle new_handle(new KernelHandle(stream_fs_, node));
1399 error = new_handle->Init(O_RDWR);
1400 if (error != 0) {
1401 errno = error;
1402 return -1;
1405 return AllocateFD(new_handle);
1408 int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) {
1409 if (NULL == addr) {
1410 errno = EFAULT;
1411 return -1;
1414 ScopedKernelHandle handle;
1415 if (AcquireSocketHandle(fd, &handle) == -1)
1416 return -1;
1418 Error err = handle->socket_node()->Bind(addr, len);
1419 if (err != 0) {
1420 errno = err;
1421 return -1;
1424 return 0;
1427 int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) {
1428 if (NULL == addr) {
1429 errno = EFAULT;
1430 return -1;
1433 ScopedKernelHandle handle;
1434 Error error = AcquireHandle(fd, &handle);
1435 if (error) {
1436 errno = error;
1437 return -1;
1440 error = handle->Connect(addr, len);
1441 if (error != 0) {
1442 errno = error;
1443 return -1;
1446 return 0;
1449 void KernelProxy::freeaddrinfo(struct addrinfo* res) {
1450 return host_resolver_.freeaddrinfo(res);
1453 int KernelProxy::getaddrinfo(const char* node,
1454 const char* service,
1455 const struct addrinfo* hints,
1456 struct addrinfo** res) {
1457 return host_resolver_.getaddrinfo(node, service, hints, res);
1460 int KernelProxy::getnameinfo(const struct sockaddr *sa,
1461 socklen_t salen,
1462 char *host,
1463 size_t hostlen,
1464 char *serv,
1465 size_t servlen,
1466 int flags) {
1467 return host_resolver_.getnameinfo(sa, salen, host, hostlen, serv, servlen,
1468 flags);
1471 struct hostent* KernelProxy::gethostbyname(const char* name) {
1472 return host_resolver_.gethostbyname(name);
1475 int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
1476 if (NULL == addr || NULL == len) {
1477 errno = EFAULT;
1478 return -1;
1481 ScopedKernelHandle handle;
1482 if (AcquireSocketHandle(fd, &handle) == -1)
1483 return -1;
1485 Error err = handle->socket_node()->GetPeerName(addr, len);
1486 if (err != 0) {
1487 errno = err;
1488 return -1;
1491 return 0;
1494 int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
1495 if (NULL == addr || NULL == len) {
1496 errno = EFAULT;
1497 return -1;
1500 ScopedKernelHandle handle;
1501 if (AcquireSocketHandle(fd, &handle) == -1)
1502 return -1;
1504 Error err = handle->socket_node()->GetSockName(addr, len);
1505 if (err != 0) {
1506 errno = err;
1507 return -1;
1510 return 0;
1513 int KernelProxy::getsockopt(int fd,
1514 int lvl,
1515 int optname,
1516 void* optval,
1517 socklen_t* len) {
1518 if (NULL == optval || NULL == len) {
1519 errno = EFAULT;
1520 return -1;
1523 ScopedKernelHandle handle;
1524 if (AcquireSocketHandle(fd, &handle) == -1)
1525 return -1;
1527 Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len);
1528 if (err != 0) {
1529 errno = err;
1530 return -1;
1533 return 0;
1536 int KernelProxy::listen(int fd, int backlog) {
1537 ScopedKernelHandle handle;
1538 if (AcquireSocketHandle(fd, &handle) == -1)
1539 return -1;
1541 Error err = handle->socket_node()->Listen(backlog);
1542 if (err != 0) {
1543 errno = err;
1544 return -1;
1547 return 0;
1550 ssize_t KernelProxy::recv(int fd, void* buf, size_t len, int flags) {
1551 if (NULL == buf) {
1552 errno = EFAULT;
1553 return -1;
1556 ScopedKernelHandle handle;
1557 Error error = AcquireHandle(fd, &handle);
1558 if (error) {
1559 errno = error;
1560 return -1;
1563 int out_len = 0;
1564 error = handle->Recv(buf, len, flags, &out_len);
1565 if (error != 0) {
1566 errno = error;
1567 return -1;
1570 return static_cast<ssize_t>(out_len);
1573 ssize_t KernelProxy::recvfrom(int fd,
1574 void* buf,
1575 size_t len,
1576 int flags,
1577 struct sockaddr* addr,
1578 socklen_t* addrlen) {
1579 // According to the manpage, recvfrom with a null addr is identical to recv.
1580 if (NULL == addr) {
1581 return recv(fd, buf, len, flags);
1584 if (NULL == buf || NULL == addrlen) {
1585 errno = EFAULT;
1586 return -1;
1589 ScopedKernelHandle handle;
1590 Error error = AcquireHandle(fd, &handle);
1591 if (error) {
1592 errno = error;
1593 return -1;
1596 int out_len = 0;
1597 error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len);
1598 if (error != 0) {
1599 errno = error;
1600 return -1;
1603 return static_cast<ssize_t>(out_len);
1606 ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) {
1607 if (NULL == msg) {
1608 errno = EFAULT;
1609 return -1;
1612 ScopedKernelHandle handle;
1613 if (AcquireSocketHandle(fd, &handle) == -1)
1614 return -1;
1616 errno = EOPNOTSUPP;
1617 return -1;
1620 ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) {
1621 if (NULL == buf) {
1622 errno = EFAULT;
1623 return -1;
1626 ScopedKernelHandle handle;
1627 Error error = AcquireHandle(fd, &handle);
1628 if (error) {
1629 errno = error;
1630 return -1;
1633 int out_len = 0;
1634 error = handle->Send(buf, len, flags, &out_len);
1635 if (error != 0) {
1636 errno = error;
1637 return -1;
1640 return static_cast<ssize_t>(out_len);
1643 ssize_t KernelProxy::sendto(int fd,
1644 const void* buf,
1645 size_t len,
1646 int flags,
1647 const struct sockaddr* addr,
1648 socklen_t addrlen) {
1649 // According to the manpage, sendto with a null addr is identical to send.
1650 if (NULL == addr) {
1651 return send(fd, buf, len, flags);
1654 if (NULL == buf) {
1655 errno = EFAULT;
1656 return -1;
1659 ScopedKernelHandle handle;
1660 Error error = AcquireHandle(fd, &handle);
1661 if (error) {
1662 errno = error;
1663 return -1;
1666 int out_len = 0;
1667 error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len);
1668 if (error != 0) {
1669 errno = error;
1670 return -1;
1673 return static_cast<ssize_t>(out_len);
1676 ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) {
1677 if (NULL == msg) {
1678 errno = EFAULT;
1679 return -1;
1682 ScopedKernelHandle handle;
1683 if (AcquireSocketHandle(fd, &handle) == -1)
1684 return -1;
1686 errno = EOPNOTSUPP;
1687 return -1;
1690 int KernelProxy::setsockopt(int fd,
1691 int lvl,
1692 int optname,
1693 const void* optval,
1694 socklen_t len) {
1695 if (NULL == optval) {
1696 errno = EFAULT;
1697 return -1;
1700 ScopedKernelHandle handle;
1701 if (AcquireSocketHandle(fd, &handle) == -1)
1702 return -1;
1704 Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len);
1705 if (err != 0) {
1706 errno = err;
1707 return -1;
1710 return 0;
1713 int KernelProxy::shutdown(int fd, int how) {
1714 ScopedKernelHandle handle;
1715 if (AcquireSocketHandle(fd, &handle) == -1)
1716 return -1;
1718 Error err = handle->socket_node()->Shutdown(how);
1719 if (err != 0) {
1720 errno = err;
1721 return -1;
1724 return 0;
1727 int KernelProxy::socket(int domain, int type, int protocol) {
1728 if (AF_INET != domain && AF_INET6 != domain) {
1729 errno = EAFNOSUPPORT;
1730 return -1;
1733 int open_flags = O_RDWR;
1735 #if defined(SOCK_CLOEXEC)
1736 if (type & SOCK_CLOEXEC) {
1737 #if defined(O_CLOEXEC)
1738 // The NaCl newlib version of fcntl.h doesn't currently define
1739 // O_CLOEXEC.
1740 // TODO(sbc): remove this guard once it gets added.
1741 open_flags |= O_CLOEXEC;
1742 #endif
1743 type &= ~SOCK_CLOEXEC;
1745 #endif
1747 #if defined(SOCK_NONBLOCK)
1748 if (type & SOCK_NONBLOCK) {
1749 open_flags |= O_NONBLOCK;
1750 type &= ~SOCK_NONBLOCK;
1752 #endif
1754 SocketNode* sock = NULL;
1755 switch (type) {
1756 case SOCK_DGRAM:
1757 sock = new UdpNode(stream_fs_.get());
1758 break;
1760 case SOCK_STREAM:
1761 sock = new TcpNode(stream_fs_.get());
1762 break;
1764 case SOCK_SEQPACKET:
1765 case SOCK_RDM:
1766 case SOCK_RAW:
1767 errno = EPROTONOSUPPORT;
1768 return -1;
1770 default:
1771 errno = EINVAL;
1772 return -1;
1775 ScopedNode node(sock);
1776 Error rtn = sock->Init(O_RDWR);
1777 if (rtn != 0) {
1778 errno = rtn;
1779 return -1;
1782 ScopedKernelHandle handle(new KernelHandle(stream_fs_, node));
1783 rtn = handle->Init(open_flags);
1784 if (rtn != 0) {
1785 errno = rtn;
1786 return -1;
1789 return AllocateFD(handle);
1792 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) {
1793 if (NULL == sv) {
1794 errno = EFAULT;
1795 return -1;
1798 // Catch-22: We don't support AF_UNIX, but any other AF doesn't support
1799 // socket pairs. Thus, this function always fails.
1800 if (AF_UNIX != domain) {
1801 errno = EPROTONOSUPPORT;
1802 return -1;
1805 if (AF_INET != domain && AF_INET6 != domain) {
1806 errno = EAFNOSUPPORT;
1807 return -1;
1810 // We cannot reach this point.
1811 errno = ENOSYS;
1812 return -1;
1815 int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) {
1816 Error error = AcquireHandle(fd, handle);
1818 if (error) {
1819 errno = error;
1820 return -1;
1823 if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) {
1824 errno = ENOTSOCK;
1825 return -1;
1828 return 0;
1831 #endif // PROVIDES_SOCKET_API
1833 } // namespace_nacl_io