Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / libraries / nacl_io / kernel_proxy.cc
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.
4
5 #include "nacl_io/kernel_proxy.h"
6
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>
17
18 #include <iterator>
19 #include <string>
20
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/osmman.h"
33 #include "nacl_io/ossocket.h"
34 #include "nacl_io/osstat.h"
35 #include "nacl_io/passthroughfs/passthrough_fs.h"
36 #include "nacl_io/path.h"
37 #include "nacl_io/pepper_interface.h"
38 #include "nacl_io/pipe/pipe_node.h"
39 #include "nacl_io/socket/tcp_node.h"
40 #include "nacl_io/socket/udp_node.h"
41 #include "nacl_io/stream/stream_fs.h"
42 #include "nacl_io/typed_fs_factory.h"
43 #include "sdk_util/auto_lock.h"
44 #include "sdk_util/ref_object.h"
45 #include "sdk_util/string_util.h"
46
47 #ifndef MAXPATHLEN
48 #define MAXPATHLEN 256
49 #endif
50
51 namespace nacl_io {
52
53 KernelProxy::KernelProxy()
54     : dev_(0),
55       ppapi_(NULL),
56       exit_callback_(NULL),
57       exit_callback_user_data_(NULL),
58       mount_callback_(NULL),
59       mount_callback_user_data_(NULL),
60       signal_emitter_(new EventEmitter) {
61   memset(&sigwinch_handler_, 0, sizeof(sigwinch_handler_));
62   sigwinch_handler_.sa_handler = SIG_DFL;
63 }
64
65 KernelProxy::~KernelProxy() {
66   // Clean up the FsFactories.
67   for (FsFactoryMap_t::iterator i = factories_.begin(); i != factories_.end();
68        ++i) {
69     delete i->second;
70   }
71 }
72
73 Error KernelProxy::Init(PepperInterface* ppapi) {
74   Error rtn = 0;
75   ppapi_ = ppapi;
76   dev_ = 1;
77
78   factories_["memfs"] = new TypedFsFactory<MemFs>;
79   factories_["dev"] = new TypedFsFactory<DevFs>;
80   factories_["html5fs"] = new TypedFsFactory<Html5Fs>;
81   factories_["httpfs"] = new TypedFsFactory<HttpFs>;
82   factories_["passthroughfs"] = new TypedFsFactory<PassthroughFs>;
83
84   ScopedFilesystem root_fs;
85   rtn = MountInternal("", "/", "passthroughfs", 0, NULL, false, &root_fs);
86   if (rtn != 0)
87     assert(false);
88
89   ScopedFilesystem fs;
90   rtn = MountInternal("", "/dev", "dev", 0, NULL, false, &fs);
91   if (rtn != 0)
92     assert(false);
93   dev_fs_ = sdk_util::static_scoped_ref_cast<DevFs>(fs);
94
95   // Create the filesystem nodes for / and /dev afterward. They can't be
96   // created the normal way because the dev filesystem didn't exist yet.
97   rtn = CreateFsNode(root_fs);
98   if (rtn != 0)
99     assert(false);
100
101   rtn = CreateFsNode(dev_fs_);
102   if (rtn != 0)
103     assert(false);
104
105   // Open the first three in order to get STDIN, STDOUT, STDERR
106   int fd;
107   fd = open("/dev/stdin", O_RDONLY);
108   assert(fd == 0);
109   if (fd < 0)
110     rtn = errno;
111
112   fd = open("/dev/stdout", O_WRONLY);
113   assert(fd == 1);
114   if (fd < 0)
115     rtn = errno;
116
117   fd = open("/dev/stderr", O_WRONLY);
118   assert(fd == 2);
119   if (fd < 0)
120     rtn = errno;
121
122 #ifdef PROVIDES_SOCKET_API
123   host_resolver_.Init(ppapi_);
124 #endif
125
126   FsInitArgs args;
127   args.dev = dev_++;
128   args.ppapi = ppapi_;
129   stream_fs_.reset(new StreamFs());
130   int result = stream_fs_->Init(args);
131   if (result != 0) {
132     assert(false);
133     rtn = result;
134   }
135
136   return rtn;
137 }
138
139 bool KernelProxy::RegisterFsType(const char* fs_type,
140                                  fuse_operations* fuse_ops) {
141   FsFactoryMap_t::iterator iter = factories_.find(fs_type);
142   if (iter != factories_.end())
143     return false;
144
145   factories_[fs_type] = new FuseFsFactory(fuse_ops);
146   return true;
147 }
148
149 bool KernelProxy::UnregisterFsType(const char* fs_type) {
150   FsFactoryMap_t::iterator iter = factories_.find(fs_type);
151   if (iter == factories_.end())
152     return false;
153
154   delete iter->second;
155   factories_.erase(iter);
156   return true;
157 }
158
159 void KernelProxy::SetExitCallback(nacl_io_exit_callback_t exit_callback,
160                                   void* user_data) {
161   exit_callback_ = exit_callback;
162   exit_callback_user_data_ = user_data;
163 }
164
165 void KernelProxy::SetMountCallback(nacl_io_mount_callback_t mount_callback,
166                                    void* user_data) {
167   mount_callback_ = mount_callback;
168   mount_callback_user_data_ = user_data;
169 }
170
171 int KernelProxy::open_resource(const char* path) {
172   ScopedFilesystem fs;
173   Path rel;
174
175   Error error = AcquireFsAndRelPath(path, &fs, &rel);
176   if (error) {
177     errno = error;
178     return -1;
179   }
180
181   ScopedNode node;
182   error = fs->OpenResource(rel, &node);
183   if (error) {
184     // OpenResource failed, try Open().
185     error = fs->Open(rel, O_RDONLY, &node);
186     if (error) {
187       errno = error;
188       return -1;
189     }
190   }
191
192   ScopedKernelHandle handle(new KernelHandle(fs, node));
193   error = handle->Init(O_RDONLY);
194   if (error) {
195     errno = error;
196     return -1;
197   }
198
199   return AllocateFD(handle, path);
200 }
201
202 int KernelProxy::open(const char* path, int open_flags) {
203   ScopedFilesystem fs;
204   ScopedNode node;
205
206   Error error = AcquireFsAndNode(path, open_flags, &fs, &node);
207   if (error) {
208     errno = error;
209     return -1;
210   }
211
212   ScopedKernelHandle handle(new KernelHandle(fs, node));
213   error = handle->Init(open_flags);
214   if (error) {
215     errno = error;
216     return -1;
217   }
218
219   return AllocateFD(handle, path);
220 }
221
222 int KernelProxy::pipe(int pipefds[2]) {
223   PipeNode* pipe = new PipeNode(stream_fs_.get());
224   ScopedNode node(pipe);
225
226   if (pipe->Init(O_RDWR) == 0) {
227     ScopedKernelHandle handle0(new KernelHandle(stream_fs_, node));
228     ScopedKernelHandle handle1(new KernelHandle(stream_fs_, node));
229
230     // Should never fail, but...
231     if (handle0->Init(O_RDONLY) || handle1->Init(O_WRONLY)) {
232       errno = EACCES;
233       return -1;
234     }
235
236     pipefds[0] = AllocateFD(handle0);
237     pipefds[1] = AllocateFD(handle1);
238     return 0;
239   }
240
241   errno = ENOSYS;
242   return -1;
243 }
244
245 int KernelProxy::close(int fd) {
246   ScopedKernelHandle handle;
247   Error error = AcquireHandle(fd, &handle);
248   if (error) {
249     errno = error;
250     return -1;
251   }
252
253   // Remove the FD from the process open file descriptor map
254   FreeFD(fd);
255   return 0;
256 }
257
258 int KernelProxy::dup(int oldfd) {
259   ScopedKernelHandle handle;
260   std::string path;
261   Error error = AcquireHandleAndPath(oldfd, &handle, &path);
262   if (error) {
263     errno = error;
264     return -1;
265   }
266   return AllocateFD(handle, path);
267 }
268
269 int KernelProxy::dup2(int oldfd, int newfd) {
270   // If it's the same file handle, just return
271   if (oldfd == newfd)
272     return newfd;
273
274   ScopedKernelHandle old_handle;
275   std::string old_path;
276   Error error = AcquireHandleAndPath(oldfd, &old_handle, &old_path);
277   if (error) {
278     errno = error;
279     return -1;
280   }
281
282   FreeAndReassignFD(newfd, old_handle, old_path);
283   return newfd;
284 }
285
286 int KernelProxy::chdir(const char* path) {
287   Error error = SetCWD(path);
288   if (error) {
289     errno = error;
290     return -1;
291   }
292   return 0;
293 }
294
295 void KernelProxy::exit(int status) {
296   if (exit_callback_)
297     exit_callback_(status, exit_callback_user_data_);
298 }
299
300 char* KernelProxy::getcwd(char* buf, size_t size) {
301   if (NULL == buf) {
302     errno = EFAULT;
303     return NULL;
304   }
305
306   std::string cwd = GetCWD();
307
308   // Verify the buffer is large enough
309   if (size <= cwd.size()) {
310     errno = ERANGE;
311     return NULL;
312   }
313
314   strcpy(buf, cwd.c_str());
315   return buf;
316 }
317
318 char* KernelProxy::getwd(char* buf) {
319   if (NULL == buf) {
320     errno = EFAULT;
321     return NULL;
322   }
323   return getcwd(buf, MAXPATHLEN);
324 }
325
326 int KernelProxy::chmod(const char* path, mode_t mode) {
327   int fd = KernelProxy::open(path, O_RDONLY);
328   if (-1 == fd)
329     return -1;
330
331   int result = fchmod(fd, mode);
332   close(fd);
333   return result;
334 }
335
336 int KernelProxy::chown(const char* path, uid_t owner, gid_t group) {
337   return 0;
338 }
339
340 int KernelProxy::fchown(int fd, uid_t owner, gid_t group) {
341   return 0;
342 }
343
344 int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) {
345   return 0;
346 }
347
348 int KernelProxy::utime(const char* filename, const struct utimbuf* times) {
349   return 0;
350 }
351
352 int KernelProxy::mkdir(const char* path, mode_t mode) {
353   ScopedFilesystem fs;
354   Path rel;
355
356   Error error = AcquireFsAndRelPath(path, &fs, &rel);
357   if (error) {
358     errno = error;
359     return -1;
360   }
361
362   error = fs->Mkdir(rel, mode);
363   if (error) {
364     errno = error;
365     return -1;
366   }
367
368   return 0;
369 }
370
371 int KernelProxy::rmdir(const char* path) {
372   ScopedFilesystem fs;
373   Path rel;
374
375   Error error = AcquireFsAndRelPath(path, &fs, &rel);
376   if (error) {
377     errno = error;
378     return -1;
379   }
380
381   error = fs->Rmdir(rel);
382   if (error) {
383     errno = error;
384     return -1;
385   }
386
387   return 0;
388 }
389
390 int KernelProxy::stat(const char* path, struct stat* buf) {
391   int fd = open(path, O_RDONLY);
392   if (-1 == fd)
393     return -1;
394
395   int result = fstat(fd, buf);
396   close(fd);
397   return result;
398 }
399
400 int KernelProxy::mount(const char* source,
401                        const char* target,
402                        const char* filesystemtype,
403                        unsigned long mountflags,
404                        const void* data) {
405   ScopedFilesystem fs;
406   Error error = MountInternal(
407       source, target, filesystemtype, mountflags, data, true, &fs);
408   if (error) {
409     errno = error;
410     return -1;
411   }
412
413   return 0;
414 }
415
416 Error KernelProxy::MountInternal(const char* source,
417                                  const char* target,
418                                  const char* filesystemtype,
419                                  unsigned long mountflags,
420                                  const void* data,
421                                  bool create_fs_node,
422                                  ScopedFilesystem* out_filesystem) {
423   std::string abs_path = GetAbsParts(target).Join();
424
425   // Find a factory of that type
426   FsFactoryMap_t::iterator factory = factories_.find(filesystemtype);
427   if (factory == factories_.end()) {
428     LOG_ERROR("Unknown filesystem type: %s", filesystemtype);
429     return ENODEV;
430   }
431
432   // Create a map of settings
433   StringMap_t smap;
434   smap["SOURCE"] = source;
435
436   if (data) {
437     std::vector<std::string> elements;
438     sdk_util::SplitString(static_cast<const char*>(data), ',', &elements);
439
440     for (std::vector<std::string>::const_iterator it = elements.begin();
441          it != elements.end();
442          ++it) {
443       size_t location = it->find('=');
444       if (location != std::string::npos) {
445         std::string key = it->substr(0, location);
446         std::string val = it->substr(location + 1);
447         smap[key] = val;
448       } else {
449         smap[*it] = "TRUE";
450       }
451     }
452   }
453
454   FsInitArgs args;
455   args.dev = dev_++;
456   args.string_map = smap;
457   args.ppapi = ppapi_;
458
459   ScopedFilesystem fs;
460   Error error = factory->second->CreateFilesystem(args, &fs);
461   if (error)
462     return error;
463
464   error = AttachFsAtPath(fs, abs_path);
465   if (error)
466     return error;
467
468   if (create_fs_node) {
469     error = CreateFsNode(fs);
470     if (error) {
471       DetachFsAtPath(abs_path, &fs);
472       return error;
473     }
474   }
475
476   *out_filesystem = fs;
477
478   if (mount_callback_) {
479     mount_callback_(source,
480                     target,
481                     filesystemtype,
482                     mountflags,
483                     data,
484                     fs->dev(),
485                     mount_callback_user_data_);
486   }
487
488   return 0;
489 }
490
491 Error KernelProxy::CreateFsNode(const ScopedFilesystem& fs) {
492   assert(dev_fs_);
493
494   return dev_fs_->CreateFsNode(fs.get());
495 }
496
497 int KernelProxy::umount(const char* path) {
498   ScopedFilesystem fs;
499   Error error = DetachFsAtPath(path, &fs);
500   if (error) {
501     errno = error;
502     return -1;
503   }
504
505   error = dev_fs_->DestroyFsNode(fs.get());
506   if (error) {
507     // Ignore any errors here, just log.
508     LOG_ERROR("Unable to destroy FsNode: %s", strerror(error));
509   }
510   return 0;
511 }
512
513 ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) {
514   ScopedKernelHandle handle;
515   Error error = AcquireHandle(fd, &handle);
516   if (error) {
517     errno = error;
518     return -1;
519   }
520
521   int cnt = 0;
522   error = handle->Read(buf, nbytes, &cnt);
523   if (error) {
524     errno = error;
525     return -1;
526   }
527
528   return cnt;
529 }
530
531 ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) {
532   ScopedKernelHandle handle;
533   Error error = AcquireHandle(fd, &handle);
534   if (error) {
535     errno = error;
536     return -1;
537   }
538
539   int cnt = 0;
540   error = handle->Write(buf, nbytes, &cnt);
541   if (error) {
542     errno = error;
543     return -1;
544   }
545
546   return cnt;
547 }
548
549 int KernelProxy::fstat(int fd, struct stat* buf) {
550   ScopedKernelHandle handle;
551   Error error = AcquireHandle(fd, &handle);
552   if (error) {
553     errno = error;
554     return -1;
555   }
556
557   error = handle->node()->GetStat(buf);
558   if (error) {
559     errno = error;
560     return -1;
561   }
562
563   return 0;
564 }
565
566 int KernelProxy::getdents(int fd, void* buf, unsigned int count) {
567   ScopedKernelHandle handle;
568   Error error = AcquireHandle(fd, &handle);
569   if (error) {
570     errno = error;
571     return -1;
572   }
573
574   int cnt = 0;
575   error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt);
576   if (error)
577     errno = error;
578
579   return cnt;
580 }
581
582 int KernelProxy::fchdir(int fd) {
583   ScopedKernelHandle handle;
584   std::string path;
585   Error error = AcquireHandleAndPath(fd, &handle, &path);
586   if (error) {
587     errno = error;
588     return -1;
589   }
590
591   if (!handle->node()->IsaDir()) {
592     errno = ENOTDIR;
593     return -1;
594   }
595
596   if (path.empty()) {
597     errno = EBADF;
598     return -1;
599   }
600
601   error = SetCWD(path);
602   if (error) {
603     // errno is return value from SetCWD
604     errno = error;
605     return -1;
606   }
607   return 0;
608 }
609
610 int KernelProxy::ftruncate(int fd, off_t length) {
611   ScopedKernelHandle handle;
612   Error error = AcquireHandle(fd, &handle);
613   if (error) {
614     errno = error;
615     return -1;
616   }
617
618   error = handle->node()->FTruncate(length);
619   if (error) {
620     errno = error;
621     return -1;
622   }
623
624   return 0;
625 }
626
627 int KernelProxy::fsync(int fd) {
628   ScopedKernelHandle handle;
629   Error error = AcquireHandle(fd, &handle);
630   if (error) {
631     errno = error;
632     return -1;
633   }
634
635   error = handle->node()->FSync();
636   if (error) {
637     errno = error;
638     return -1;
639   }
640
641   return 0;
642 }
643
644 int KernelProxy::fdatasync(int fd) {
645   errno = ENOSYS;
646   return -1;
647 }
648
649 int KernelProxy::isatty(int fd) {
650   ScopedKernelHandle handle;
651   Error error = AcquireHandle(fd, &handle);
652   if (error) {
653     errno = error;
654     return 0;
655   }
656
657   error = handle->node()->Isatty();
658   if (error) {
659     errno = error;
660     return 0;
661   }
662
663   return 1;
664 }
665
666 int KernelProxy::ioctl(int fd, int request, va_list args) {
667   ScopedKernelHandle handle;
668   Error error = AcquireHandle(fd, &handle);
669   if (error) {
670     errno = error;
671     return -1;
672   }
673
674   error = handle->node()->VIoctl(request, args);
675   if (error) {
676     errno = error;
677     return -1;
678   }
679
680   return 0;
681 }
682
683 off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
684   ScopedKernelHandle handle;
685   Error error = AcquireHandle(fd, &handle);
686   if (error) {
687     errno = error;
688     return -1;
689   }
690
691   off_t new_offset;
692   error = handle->Seek(offset, whence, &new_offset);
693   if (error) {
694     errno = error;
695     return -1;
696   }
697
698   return new_offset;
699 }
700
701 int KernelProxy::unlink(const char* path) {
702   ScopedFilesystem fs;
703   Path rel;
704
705   Error error = AcquireFsAndRelPath(path, &fs, &rel);
706   if (error) {
707     errno = error;
708     return -1;
709   }
710
711   error = fs->Unlink(rel);
712   if (error) {
713     errno = error;
714     return -1;
715   }
716
717   return 0;
718 }
719
720 int KernelProxy::truncate(const char* path, off_t len) {
721   int fd = KernelProxy::open(path, O_WRONLY);
722   if (-1 == fd)
723     return -1;
724
725   int result = ftruncate(fd, len);
726   close(fd);
727   return result;
728 }
729
730 int KernelProxy::lstat(const char* path, struct stat* buf) {
731   return stat(path, buf);
732 }
733
734 int KernelProxy::rename(const char* path, const char* newpath) {
735   ScopedFilesystem fs;
736   Path rel;
737   Error error = AcquireFsAndRelPath(path, &fs, &rel);
738   if (error) {
739     errno = error;
740     return -1;
741   }
742
743   ScopedFilesystem newfs;
744   Path newrel;
745   error = AcquireFsAndRelPath(newpath, &newfs, &newrel);
746   if (error) {
747     errno = error;
748     return -1;
749   }
750
751   if (newfs.get() != fs.get()) {
752     // Renaming accross mountpoints is not allowed
753     errno = EXDEV;
754     return -1;
755   }
756
757   // They already point to the same path
758   if (rel == newrel)
759     return 0;
760
761   error = fs->Rename(rel, newrel);
762   if (error) {
763     errno = error;
764     return -1;
765   }
766
767   return 0;
768 }
769
770 int KernelProxy::remove(const char* path) {
771   ScopedFilesystem fs;
772   Path rel;
773
774   Error error = AcquireFsAndRelPath(path, &fs, &rel);
775   if (error) {
776     errno = error;
777     return -1;
778   }
779
780   error = fs->Remove(rel);
781   if (error) {
782     errno = error;
783     return -1;
784   }
785
786   return 0;
787 }
788
789 // TODO(noelallen): Needs implementation.
790 int KernelProxy::fchmod(int fd, int mode) {
791   ScopedKernelHandle handle;
792   Error error = AcquireHandle(fd, &handle);
793   if (error) {
794     errno = error;
795     return -1;
796   }
797
798   return 0;
799 }
800
801 int KernelProxy::fcntl(int fd, int request, va_list args) {
802   Error error = 0;
803
804   // F_GETFD and F_SETFD are descriptor specific flags that
805   // are stored in the KernelObject's decriptor map unlike
806   // F_GETFL and F_SETFL which are handle specific.
807   switch (request) {
808     case F_GETFD: {
809       int rtn = -1;
810       error = GetFDFlags(fd, &rtn);
811       if (error) {
812         errno = error;
813         return -1;
814       }
815       return rtn;
816     }
817     case F_SETFD: {
818       int flags = va_arg(args, int);
819       error = SetFDFlags(fd, flags);
820       if (error) {
821         errno = error;
822         return -1;
823       }
824       return 0;
825     }
826   }
827
828   ScopedKernelHandle handle;
829   error = AcquireHandle(fd, &handle);
830   if (error) {
831     errno = error;
832     return -1;
833   }
834
835   int rtn = 0;
836   error = handle->VFcntl(request, &rtn, args);
837   if (error) {
838     errno = error;
839     return -1;
840   }
841
842   return rtn;
843 }
844
845 int KernelProxy::access(const char* path, int amode) {
846   ScopedFilesystem fs;
847   Path rel;
848
849   Error error = AcquireFsAndRelPath(path, &fs, &rel);
850   if (error) {
851     errno = error;
852     return -1;
853   }
854
855   error = fs->Access(rel, amode);
856   if (error) {
857     errno = error;
858     return -1;
859   }
860   return 0;
861 }
862
863 int KernelProxy::readlink(const char* path, char* buf, size_t count) {
864   LOG_TRACE("readlink is not implemented.");
865   errno = EINVAL;
866   return -1;
867 }
868
869 int KernelProxy::utimes(const char* filename, const struct timeval times[2]) {
870   LOG_TRACE("utimes is not implemented.");
871   errno = EINVAL;
872   return -1;
873 }
874
875 // TODO(noelallen): Needs implementation.
876 int KernelProxy::link(const char* oldpath, const char* newpath) {
877   LOG_TRACE("link is not implemented.");
878   errno = EINVAL;
879   return -1;
880 }
881
882 int KernelProxy::symlink(const char* oldpath, const char* newpath) {
883   LOG_TRACE("symlink is not implemented.");
884   errno = EINVAL;
885   return -1;
886 }
887
888 void* KernelProxy::mmap(void* addr,
889                         size_t length,
890                         int prot,
891                         int flags,
892                         int fd,
893                         size_t offset) {
894   // We shouldn't be getting anonymous mmaps here.
895   assert((flags & MAP_ANONYMOUS) == 0);
896   assert(fd != -1);
897
898   ScopedKernelHandle handle;
899   Error error = AcquireHandle(fd, &handle);
900   if (error) {
901     errno = error;
902     return MAP_FAILED;
903   }
904
905   void* new_addr;
906   error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr);
907   if (error) {
908     errno = error;
909     return MAP_FAILED;
910   }
911
912   return new_addr;
913 }
914
915 int KernelProxy::munmap(void* addr, size_t length) {
916   // NOTE: The comment below is from a previous discarded implementation that
917   // tracks mmap'd regions. For simplicity, we no longer do this; because we
918   // "snapshot" the contents of the file in mmap(), and don't support
919   // write-back or updating the mapped region when the file is written, holding
920   // on to the KernelHandle is pointless.
921   //
922   // If we ever do, these threading issues should be considered.
923
924   //
925   // WARNING: this function may be called by free().
926   //
927   // There is a potential deadlock scenario:
928   // Thread 1: open() -> takes lock1 -> free() -> takes lock2
929   // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1
930   //
931   // Note that open() above could be any function that takes a lock that is
932   // shared with munmap (this includes munmap!)
933   //
934   // To prevent this, we avoid taking locks in munmap() that are used by other
935   // nacl_io functions that may call free. Specifically, we only take the
936   // mmap_lock, which is only shared with mmap() above. There is still a
937   // possibility of deadlock if mmap() or munmap() calls free(), so this is not
938   // allowed.
939   //
940   // Unfortunately, munmap still needs to acquire other locks; see the call to
941   // ReleaseHandle below which takes the process lock. This is safe as long as
942   // this is never executed from free() -- we can be reasonably sure this is
943   // true, because malloc only makes anonymous mmap() requests, and should only
944   // be munmapping those allocations. We never add to mmap_info_list_ for
945   // anonymous maps, so the unmap_list should always be empty when called from
946   // free().
947   return 0;
948 }
949
950 int KernelProxy::tcflush(int fd, int queue_selector) {
951   ScopedKernelHandle handle;
952   Error error = AcquireHandle(fd, &handle);
953   if (error) {
954     errno = error;
955     return -1;
956   }
957
958   error = handle->node()->Tcflush(queue_selector);
959   if (error) {
960     errno = error;
961     return -1;
962   }
963
964   return 0;
965 }
966
967 int KernelProxy::tcgetattr(int fd, struct termios* termios_p) {
968   ScopedKernelHandle handle;
969   Error error = AcquireHandle(fd, &handle);
970   if (error) {
971     errno = error;
972     return -1;
973   }
974
975   error = handle->node()->Tcgetattr(termios_p);
976   if (error) {
977     errno = error;
978     return -1;
979   }
980
981   return 0;
982 }
983
984 int KernelProxy::tcsetattr(int fd,
985                            int optional_actions,
986                            const struct termios* termios_p) {
987   ScopedKernelHandle handle;
988   Error error = AcquireHandle(fd, &handle);
989   if (error) {
990     errno = error;
991     return -1;
992   }
993
994   error = handle->node()->Tcsetattr(optional_actions, termios_p);
995   if (error) {
996     errno = error;
997     return -1;
998   }
999
1000   return 0;
1001 }
1002
1003 int KernelProxy::kill(pid_t pid, int sig) {
1004   // Currently we don't even pretend that other processes exist
1005   // so we can only send a signal to outselves.  For kill(2)
1006   // pid 0 means the current process group and -1 means all the
1007   // processes we have permission to send signals to.
1008   if (pid != getpid() && pid != -1 && pid != 0) {
1009     errno = ESRCH;
1010     return -1;
1011   }
1012
1013   // Raise an event so that select/poll get interrupted.
1014   AUTO_LOCK(signal_emitter_->GetLock())
1015   signal_emitter_->RaiseEvents_Locked(POLLERR);
1016   switch (sig) {
1017     case SIGWINCH:
1018       if (sigwinch_handler_.sa_handler != SIG_IGN &&
1019           sigwinch_handler_.sa_handler != SIG_DFL) {
1020         sigwinch_handler_.sa_handler(SIGWINCH);
1021       }
1022       break;
1023
1024     case SIGUSR1:
1025     case SIGUSR2:
1026       break;
1027
1028     default:
1029       LOG_TRACE("Unsupported signal: %d", sig);
1030       errno = EINVAL;
1031       return -1;
1032   }
1033   return 0;
1034 }
1035
1036 int KernelProxy::sigaction(int signum,
1037                            const struct sigaction* action,
1038                            struct sigaction* oaction) {
1039   if (action && action->sa_flags & SA_SIGINFO) {
1040     // We don't support SA_SIGINFO (sa_sigaction field) yet
1041     errno = EINVAL;
1042     return -1;
1043   }
1044
1045   switch (signum) {
1046     // Handled signals.
1047     case SIGWINCH: {
1048       if (oaction)
1049         *oaction = sigwinch_handler_;
1050       if (action) {
1051         sigwinch_handler_ = *action;
1052       }
1053       return 0;
1054     }
1055
1056     // Known signals
1057     case SIGHUP:
1058     case SIGINT:
1059     case SIGPIPE:
1060     case SIGPOLL:
1061     case SIGPROF:
1062     case SIGTERM:
1063     case SIGCHLD:
1064     case SIGURG:
1065     case SIGFPE:
1066     case SIGILL:
1067     case SIGQUIT:
1068     case SIGSEGV:
1069     case SIGTRAP:
1070       if (action && action->sa_handler != SIG_DFL) {
1071         // Trying to set this action to anything other than SIG_DFL
1072         // is not yet supported.
1073         LOG_TRACE("sigaction on signal %d != SIG_DFL not supported.", sig);
1074         errno = EINVAL;
1075         return -1;
1076       }
1077
1078       if (oaction) {
1079         memset(oaction, 0, sizeof(*oaction));
1080         oaction->sa_handler = SIG_DFL;
1081       }
1082       return 0;
1083
1084     // KILL and STOP cannot be handled
1085     case SIGKILL:
1086     case SIGSTOP:
1087       LOG_TRACE("sigaction on SIGKILL/SIGSTOP not supported.");
1088       errno = EINVAL;
1089       return -1;
1090   }
1091
1092   // Unknown signum
1093   errno = EINVAL;
1094   return -1;
1095 }
1096
1097 #ifdef PROVIDES_SOCKET_API
1098
1099 int KernelProxy::select(int nfds,
1100                         fd_set* readfds,
1101                         fd_set* writefds,
1102                         fd_set* exceptfds,
1103                         struct timeval* timeout) {
1104   std::vector<pollfd> pollfds;
1105
1106   for (int fd = 0; fd < nfds; fd++) {
1107     int events = 0;
1108     if (readfds && FD_ISSET(fd, readfds)) {
1109       events |= POLLIN;
1110       FD_CLR(fd, readfds);
1111     }
1112
1113     if (writefds && FD_ISSET(fd, writefds)) {
1114       events |= POLLOUT;
1115       FD_CLR(fd, writefds);
1116     }
1117
1118     if (exceptfds && FD_ISSET(fd, exceptfds)) {
1119       events |= POLLERR | POLLHUP;
1120       FD_CLR(fd, exceptfds);
1121     }
1122
1123     if (events) {
1124       pollfd info;
1125       info.fd = fd;
1126       info.events = events;
1127       pollfds.push_back(info);
1128     }
1129   }
1130
1131   // NULL timeout signals wait forever.
1132   int ms_timeout = -1;
1133   if (timeout != NULL) {
1134     int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000);
1135
1136     // If the timeout is invalid or too long (larger than signed 32 bit).
1137     if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) ||
1138         (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || (ms < 0) ||
1139         (ms >= INT_MAX)) {
1140       LOG_TRACE("Invalid timeout: tv_sec=%d tv_usec=%d.",
1141                 timeout->tv_sec,
1142                 timeout->tv_usec);
1143       errno = EINVAL;
1144       return -1;
1145     }
1146
1147     ms_timeout = static_cast<int>(ms);
1148   }
1149
1150   int result = poll(&pollfds[0], pollfds.size(), ms_timeout);
1151   if (result == -1)
1152     return -1;
1153
1154   int event_cnt = 0;
1155   for (size_t index = 0; index < pollfds.size(); index++) {
1156     pollfd* info = &pollfds[index];
1157     if (info->revents & POLLIN) {
1158       FD_SET(info->fd, readfds);
1159       event_cnt++;
1160     }
1161     if (info->revents & POLLOUT) {
1162       FD_SET(info->fd, writefds);
1163       event_cnt++;
1164     }
1165     if (info->revents & (POLLHUP | POLLERR)) {
1166       FD_SET(info->fd, exceptfds);
1167       event_cnt++;
1168     }
1169   }
1170
1171   return event_cnt;
1172 }
1173
1174 struct PollInfo {
1175   PollInfo() : index(-1) {};
1176
1177   std::vector<struct pollfd*> fds;
1178   int index;
1179 };
1180
1181 typedef std::map<EventEmitter*, PollInfo> EventPollMap_t;
1182
1183 int KernelProxy::poll(struct pollfd* fds, nfds_t nfds, int timeout) {
1184   EventPollMap_t event_map;
1185
1186   std::vector<EventRequest> requests;
1187   size_t event_cnt = 0;
1188
1189   for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) {
1190     ScopedKernelHandle handle;
1191     struct pollfd* fd_info = &fds[index];
1192     Error err = AcquireHandle(fd_info->fd, &handle);
1193
1194     fd_info->revents = 0;
1195
1196     // If the node isn't open, or somehow invalid, mark it so.
1197     if (err != 0) {
1198       fd_info->revents = POLLNVAL;
1199       event_cnt++;
1200       continue;
1201     }
1202
1203     // If it's already signaled, then just capture the event
1204     ScopedEventEmitter emitter(handle->node()->GetEventEmitter());
1205     int events = POLLIN | POLLOUT;
1206     if (emitter)
1207       events = emitter->GetEventStatus();
1208
1209     if (events & fd_info->events) {
1210       fd_info->revents = events & fd_info->events;
1211       event_cnt++;
1212       continue;
1213     }
1214
1215     if (NULL == emitter) {
1216       fd_info->revents = POLLNVAL;
1217       event_cnt++;
1218       continue;
1219     }
1220
1221     // Otherwise try to track it.
1222     PollInfo* info = &event_map[emitter.get()];
1223     if (info->index == -1) {
1224       EventRequest request;
1225       request.emitter = emitter;
1226       request.filter = fd_info->events;
1227       request.events = 0;
1228
1229       info->index = requests.size();
1230       requests.push_back(request);
1231     }
1232     info->fds.push_back(fd_info);
1233     requests[info->index].filter |= fd_info->events;
1234   }
1235
1236   // If nothing is signaled, then we must wait on the event map
1237   if (0 == event_cnt) {
1238     EventListenerPoll wait;
1239     Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout);
1240     if ((err != 0) && (err != ETIMEDOUT)) {
1241       errno = err;
1242       return -1;
1243     }
1244
1245     for (size_t rindex = 0; rindex < requests.size(); rindex++) {
1246       EventRequest* request = &requests[rindex];
1247       if (request->events) {
1248         PollInfo* poll_info = &event_map[request->emitter.get()];
1249         for (size_t findex = 0; findex < poll_info->fds.size(); findex++) {
1250           struct pollfd* fd_info = poll_info->fds[findex];
1251           uint32_t events = fd_info->events & request->events;
1252           if (events) {
1253             fd_info->revents = events;
1254             event_cnt++;
1255           }
1256         }
1257       }
1258     }
1259   }
1260
1261   return event_cnt;
1262 }
1263
1264 // Socket Functions
1265 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
1266   if (NULL == addr || NULL == len) {
1267     errno = EFAULT;
1268     return -1;
1269   }
1270
1271   ScopedKernelHandle handle;
1272   Error error = AcquireHandle(fd, &handle);
1273   if (error) {
1274     errno = error;
1275     return -1;
1276   }
1277
1278   PP_Resource new_sock = 0;
1279   error = handle->Accept(&new_sock, addr, len);
1280   if (error != 0) {
1281     errno = error;
1282     return -1;
1283   }
1284
1285   SocketNode* sock = new TcpNode(stream_fs_.get(), new_sock);
1286
1287   // The SocketNode now holds a reference to the new socket
1288   // so we release ours.
1289   ppapi_->ReleaseResource(new_sock);
1290   error = sock->Init(O_RDWR);
1291   if (error != 0) {
1292     errno = error;
1293     return -1;
1294   }
1295
1296   ScopedNode node(sock);
1297   ScopedKernelHandle new_handle(new KernelHandle(stream_fs_, node));
1298   error = new_handle->Init(O_RDWR);
1299   if (error != 0) {
1300     errno = error;
1301     return -1;
1302   }
1303
1304   return AllocateFD(new_handle);
1305 }
1306
1307 int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) {
1308   if (NULL == addr) {
1309     errno = EFAULT;
1310     return -1;
1311   }
1312
1313   ScopedKernelHandle handle;
1314   if (AcquireSocketHandle(fd, &handle) == -1)
1315     return -1;
1316
1317   Error err = handle->socket_node()->Bind(addr, len);
1318   if (err != 0) {
1319     errno = err;
1320     return -1;
1321   }
1322
1323   return 0;
1324 }
1325
1326 int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) {
1327   if (NULL == addr) {
1328     errno = EFAULT;
1329     return -1;
1330   }
1331
1332   ScopedKernelHandle handle;
1333   Error error = AcquireHandle(fd, &handle);
1334   if (error) {
1335     errno = error;
1336     return -1;
1337   }
1338
1339   error = handle->Connect(addr, len);
1340   if (error != 0) {
1341     errno = error;
1342     return -1;
1343   }
1344
1345   return 0;
1346 }
1347
1348 void KernelProxy::freeaddrinfo(struct addrinfo* res) {
1349   return host_resolver_.freeaddrinfo(res);
1350 }
1351
1352 int KernelProxy::getaddrinfo(const char* node,
1353                              const char* service,
1354                              const struct addrinfo* hints,
1355                              struct addrinfo** res) {
1356   return host_resolver_.getaddrinfo(node, service, hints, res);
1357 }
1358
1359 struct hostent* KernelProxy::gethostbyname(const char* name) {
1360   return host_resolver_.gethostbyname(name);
1361 }
1362
1363 int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
1364   if (NULL == addr || NULL == len) {
1365     errno = EFAULT;
1366     return -1;
1367   }
1368
1369   ScopedKernelHandle handle;
1370   if (AcquireSocketHandle(fd, &handle) == -1)
1371     return -1;
1372
1373   Error err = handle->socket_node()->GetPeerName(addr, len);
1374   if (err != 0) {
1375     errno = err;
1376     return -1;
1377   }
1378
1379   return 0;
1380 }
1381
1382 int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
1383   if (NULL == addr || NULL == len) {
1384     errno = EFAULT;
1385     return -1;
1386   }
1387
1388   ScopedKernelHandle handle;
1389   if (AcquireSocketHandle(fd, &handle) == -1)
1390     return -1;
1391
1392   Error err = handle->socket_node()->GetSockName(addr, len);
1393   if (err != 0) {
1394     errno = err;
1395     return -1;
1396   }
1397
1398   return 0;
1399 }
1400
1401 int KernelProxy::getsockopt(int fd,
1402                             int lvl,
1403                             int optname,
1404                             void* optval,
1405                             socklen_t* len) {
1406   if (NULL == optval || NULL == len) {
1407     errno = EFAULT;
1408     return -1;
1409   }
1410
1411   ScopedKernelHandle handle;
1412   if (AcquireSocketHandle(fd, &handle) == -1)
1413     return -1;
1414
1415   Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len);
1416   if (err != 0) {
1417     errno = err;
1418     return -1;
1419   }
1420
1421   return 0;
1422 }
1423
1424 int KernelProxy::listen(int fd, int backlog) {
1425   ScopedKernelHandle handle;
1426   if (AcquireSocketHandle(fd, &handle) == -1)
1427     return -1;
1428
1429   Error err = handle->socket_node()->Listen(backlog);
1430   if (err != 0) {
1431     errno = err;
1432     return -1;
1433   }
1434
1435   return 0;
1436 }
1437
1438 ssize_t KernelProxy::recv(int fd, void* buf, size_t len, int flags) {
1439   if (NULL == buf) {
1440     errno = EFAULT;
1441     return -1;
1442   }
1443
1444   ScopedKernelHandle handle;
1445   Error error = AcquireHandle(fd, &handle);
1446   if (error) {
1447     errno = error;
1448     return -1;
1449   }
1450
1451   int out_len = 0;
1452   error = handle->Recv(buf, len, flags, &out_len);
1453   if (error != 0) {
1454     errno = error;
1455     return -1;
1456   }
1457
1458   return static_cast<ssize_t>(out_len);
1459 }
1460
1461 ssize_t KernelProxy::recvfrom(int fd,
1462                               void* buf,
1463                               size_t len,
1464                               int flags,
1465                               struct sockaddr* addr,
1466                               socklen_t* addrlen) {
1467   // According to the manpage, recvfrom with a null addr is identical to recv.
1468   if (NULL == addr) {
1469     return recv(fd, buf, len, flags);
1470   }
1471
1472   if (NULL == buf || NULL == addrlen) {
1473     errno = EFAULT;
1474     return -1;
1475   }
1476
1477   ScopedKernelHandle handle;
1478   Error error = AcquireHandle(fd, &handle);
1479   if (error) {
1480     errno = error;
1481     return -1;
1482   }
1483
1484   int out_len = 0;
1485   error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len);
1486   if (error != 0) {
1487     errno = error;
1488     return -1;
1489   }
1490
1491   return static_cast<ssize_t>(out_len);
1492 }
1493
1494 ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) {
1495   if (NULL == msg) {
1496     errno = EFAULT;
1497     return -1;
1498   }
1499
1500   ScopedKernelHandle handle;
1501   if (AcquireSocketHandle(fd, &handle) == -1)
1502     return -1;
1503
1504   errno = EOPNOTSUPP;
1505   return -1;
1506 }
1507
1508 ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) {
1509   if (NULL == buf) {
1510     errno = EFAULT;
1511     return -1;
1512   }
1513
1514   ScopedKernelHandle handle;
1515   Error error = AcquireHandle(fd, &handle);
1516   if (error) {
1517     errno = error;
1518     return -1;
1519   }
1520
1521   int out_len = 0;
1522   error = handle->Send(buf, len, flags, &out_len);
1523   if (error != 0) {
1524     errno = error;
1525     return -1;
1526   }
1527
1528   return static_cast<ssize_t>(out_len);
1529 }
1530
1531 ssize_t KernelProxy::sendto(int fd,
1532                             const void* buf,
1533                             size_t len,
1534                             int flags,
1535                             const struct sockaddr* addr,
1536                             socklen_t addrlen) {
1537   // According to the manpage, sendto with a null addr is identical to send.
1538   if (NULL == addr) {
1539     return send(fd, buf, len, flags);
1540   }
1541
1542   if (NULL == buf) {
1543     errno = EFAULT;
1544     return -1;
1545   }
1546
1547   ScopedKernelHandle handle;
1548   Error error = AcquireHandle(fd, &handle);
1549   if (error) {
1550     errno = error;
1551     return -1;
1552   }
1553
1554   int out_len = 0;
1555   error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len);
1556   if (error != 0) {
1557     errno = error;
1558     return -1;
1559   }
1560
1561   return static_cast<ssize_t>(out_len);
1562 }
1563
1564 ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) {
1565   if (NULL == msg) {
1566     errno = EFAULT;
1567     return -1;
1568   }
1569
1570   ScopedKernelHandle handle;
1571   if (AcquireSocketHandle(fd, &handle) == -1)
1572     return -1;
1573
1574   errno = EOPNOTSUPP;
1575   return -1;
1576 }
1577
1578 int KernelProxy::setsockopt(int fd,
1579                             int lvl,
1580                             int optname,
1581                             const void* optval,
1582                             socklen_t len) {
1583   if (NULL == optval) {
1584     errno = EFAULT;
1585     return -1;
1586   }
1587
1588   ScopedKernelHandle handle;
1589   if (AcquireSocketHandle(fd, &handle) == -1)
1590     return -1;
1591
1592   Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len);
1593   if (err != 0) {
1594     errno = err;
1595     return -1;
1596   }
1597
1598   return 0;
1599 }
1600
1601 int KernelProxy::shutdown(int fd, int how) {
1602   ScopedKernelHandle handle;
1603   if (AcquireSocketHandle(fd, &handle) == -1)
1604     return -1;
1605
1606   Error err = handle->socket_node()->Shutdown(how);
1607   if (err != 0) {
1608     errno = err;
1609     return -1;
1610   }
1611
1612   return 0;
1613 }
1614
1615 int KernelProxy::socket(int domain, int type, int protocol) {
1616   if (AF_INET != domain && AF_INET6 != domain) {
1617     errno = EAFNOSUPPORT;
1618     return -1;
1619   }
1620
1621   int open_flags = O_RDWR;
1622
1623   if (type & SOCK_CLOEXEC) {
1624 #ifdef O_CLOEXEC
1625     // The NaCl newlib version of fcntl.h doesn't currently define
1626     // O_CLOEXEC.
1627     // TODO(sbc): remove this guard once it gets added.
1628     open_flags |= O_CLOEXEC;
1629 #endif
1630     type &= ~SOCK_CLOEXEC;
1631   }
1632
1633   if (type & SOCK_NONBLOCK) {
1634     open_flags |= O_NONBLOCK;
1635     type &= ~SOCK_NONBLOCK;
1636   }
1637
1638   SocketNode* sock = NULL;
1639   switch (type) {
1640     case SOCK_DGRAM:
1641       sock = new UdpNode(stream_fs_.get());
1642       break;
1643
1644     case SOCK_STREAM:
1645       sock = new TcpNode(stream_fs_.get());
1646       break;
1647
1648     case SOCK_SEQPACKET:
1649     case SOCK_RDM:
1650     case SOCK_RAW:
1651       errno = EPROTONOSUPPORT;
1652       return -1;
1653
1654     default:
1655       errno = EINVAL;
1656       return -1;
1657   }
1658
1659   ScopedNode node(sock);
1660   Error rtn = sock->Init(O_RDWR);
1661   if (rtn != 0) {
1662     errno = rtn;
1663     return -1;
1664   }
1665
1666   ScopedKernelHandle handle(new KernelHandle(stream_fs_, node));
1667   rtn = handle->Init(open_flags);
1668   if (rtn != 0) {
1669     errno = rtn;
1670     return -1;
1671   }
1672
1673   return AllocateFD(handle);
1674 }
1675
1676 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) {
1677   if (NULL == sv) {
1678     errno = EFAULT;
1679     return -1;
1680   }
1681
1682   // Catch-22: We don't support AF_UNIX, but any other AF doesn't support
1683   // socket pairs. Thus, this function always fails.
1684   if (AF_UNIX != domain) {
1685     errno = EPROTONOSUPPORT;
1686     return -1;
1687   }
1688
1689   if (AF_INET != domain && AF_INET6 != domain) {
1690     errno = EAFNOSUPPORT;
1691     return -1;
1692   }
1693
1694   // We cannot reach this point.
1695   errno = ENOSYS;
1696   return -1;
1697 }
1698
1699 int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) {
1700   Error error = AcquireHandle(fd, handle);
1701
1702   if (error) {
1703     errno = error;
1704     return -1;
1705   }
1706
1707   if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) {
1708     errno = ENOTSOCK;
1709     return -1;
1710   }
1711
1712   return 0;
1713 }
1714
1715 #endif  // PROVIDES_SOCKET_API
1716
1717 }  // namespace_nacl_io