- add sources.
[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/host_resolver.h"
22 #include "nacl_io/kernel_handle.h"
23 #include "nacl_io/kernel_wrap_real.h"
24 #include "nacl_io/mount.h"
25 #include "nacl_io/mount_dev.h"
26 #include "nacl_io/mount_html5fs.h"
27 #include "nacl_io/mount_http.h"
28 #include "nacl_io/mount_mem.h"
29 #include "nacl_io/mount_node.h"
30 #include "nacl_io/mount_node_pipe.h"
31 #include "nacl_io/mount_node_tcp.h"
32 #include "nacl_io/mount_node_udp.h"
33 #include "nacl_io/mount_passthrough.h"
34 #include "nacl_io/mount_stream.h"
35 #include "nacl_io/osmman.h"
36 #include "nacl_io/ossocket.h"
37 #include "nacl_io/osstat.h"
38 #include "nacl_io/path.h"
39 #include "nacl_io/pepper_interface.h"
40 #include "nacl_io/typed_mount_factory.h"
41 #include "sdk_util/auto_lock.h"
42 #include "sdk_util/ref_object.h"
43 #include "sdk_util/string_util.h"
44
45 #ifndef MAXPATHLEN
46 #define MAXPATHLEN 256
47 #endif
48
49 namespace nacl_io {
50
51
52 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL),
53                              sigwinch_handler_(SIG_IGN),
54                              signal_emitter_(new EventEmitter) {
55
56 }
57
58 KernelProxy::~KernelProxy() {
59   // Clean up the MountFactories.
60   for (MountFactoryMap_t::iterator i = factories_.begin();
61        i != factories_.end();
62        ++i) {
63     delete i->second;
64   }
65
66   delete ppapi_;
67 }
68
69 Error KernelProxy::Init(PepperInterface* ppapi) {
70   Error rtn = 0;
71   ppapi_ = ppapi;
72   dev_ = 1;
73
74   factories_["memfs"] = new TypedMountFactory<MountMem>;
75   factories_["dev"] = new TypedMountFactory<MountDev>;
76   factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>;
77   factories_["httpfs"] = new TypedMountFactory<MountHttp>;
78   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
125 int 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
156 int 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
176 int 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
199 int 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
212 int 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
223 int 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
239 int 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
248 char* 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
276 char* KernelProxy::getwd(char* buf) {
277   if (NULL == buf) {
278     errno = EFAULT;
279     return NULL;
280   }
281   return getcwd(buf, MAXPATHLEN);
282 }
283
284 int 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
294 int KernelProxy::chown(const char* path, uid_t owner, gid_t group) {
295   return 0;
296 }
297
298 int KernelProxy::fchown(int fd, uid_t owner, gid_t group) {
299   return 0;
300 }
301
302 int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) {
303   return 0;
304 }
305
306 int KernelProxy::utime(const char* filename, const struct utimbuf* times) {
307   return 0;
308 }
309
310 int 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
329 int 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
348 int 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
359 int 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
411 int 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
420 ssize_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
438 ssize_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
456 int 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
473 int 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
489 int KernelProxy::fchdir(int fd) {
490   errno = ENOSYS;
491   return -1;
492 }
493
494 int 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
511 int 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
528 int KernelProxy::fdatasync(int fd) {
529   errno = ENOSYS;
530   return -1;
531 }
532
533 int 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
550 int 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
567 off_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
585 int 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
604 int KernelProxy::truncate(const char* path, off_t len) {
605   errno = ENOSYS;
606   return -1;
607 }
608
609 int KernelProxy::lstat(const char* path, struct stat* buf) {
610   errno = ENOSYS;
611   return -1;
612 }
613
614 int KernelProxy::rename(const char* path, const char* newpath) {
615   errno = ENOSYS;
616   return -1;
617 }
618
619 int 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.
639 int 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
650 int KernelProxy::fcntl(int fd, int request, va_list args) {
651   Error error = 0;
652
653   // F_GETFD and F_SETFD are descirptor specific flags that
654   // are stored in the KernelObject's decriptor map unlink
655   // F_GETFL and F_SETFL which are handle specific.
656   switch (request) {
657     case F_GETFD: {
658       int rtn = -1;
659       error = GetFDFlags(fd, &rtn);
660       if (error) {
661         errno = error;
662         return -1;
663       }
664       return rtn;
665     }
666     case F_SETFD: {
667       int flags = va_arg(args, int);
668       error = SetFDFlags(fd, flags);
669       if (error) {
670         errno = error;
671         return -1;
672       }
673       return 0;
674     }
675   }
676
677   ScopedKernelHandle handle;
678   error = AcquireHandle(fd, &handle);
679   if (error) {
680     errno = error;
681     return -1;
682   }
683
684   int rtn = 0;
685   error = handle->VFcntl(request, &rtn, args);
686   if (error) {
687     errno = error;
688     return -1;
689   }
690
691   return rtn;
692 }
693
694 int KernelProxy::access(const char* path, int amode) {
695   ScopedMount mnt;
696   Path rel;
697
698   Error error = AcquireMountAndRelPath(path, &mnt, &rel);
699   if (error) {
700     errno = error;
701     return -1;
702   }
703
704   error = mnt->Access(rel, amode);
705   if (error) {
706     errno = error;
707     return -1;
708   }
709   return 0;
710 }
711
712 int KernelProxy::readlink(const char *path, char *buf, size_t count) {
713   errno = EINVAL;
714   return -1;
715 }
716
717 int KernelProxy::utimes(const char *filename, const struct timeval times[2]) {
718   errno = EINVAL;
719   return -1;
720 }
721
722 // TODO(noelallen): Needs implementation.
723 int KernelProxy::link(const char* oldpath, const char* newpath) {
724   errno = EINVAL;
725   return -1;
726 }
727
728 int KernelProxy::symlink(const char* oldpath, const char* newpath) {
729   errno = EINVAL;
730   return -1;
731 }
732
733 void* KernelProxy::mmap(void* addr,
734                         size_t length,
735                         int prot,
736                         int flags,
737                         int fd,
738                         size_t offset) {
739   // We shouldn't be getting anonymous mmaps here.
740   assert((flags & MAP_ANONYMOUS) == 0);
741   assert(fd != -1);
742
743   ScopedKernelHandle handle;
744   Error error = AcquireHandle(fd, &handle);
745   if (error) {
746     errno = error;
747     return MAP_FAILED;
748   }
749
750   void* new_addr;
751   error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr);
752   if (error) {
753     errno = error;
754     return MAP_FAILED;
755   }
756
757   return new_addr;
758 }
759
760 int KernelProxy::munmap(void* addr, size_t length) {
761   // NOTE: The comment below is from a previous discarded implementation that
762   // tracks mmap'd regions. For simplicity, we no longer do this; because we
763   // "snapshot" the contents of the file in mmap(), and don't support
764   // write-back or updating the mapped region when the file is written, holding
765   // on to the KernelHandle is pointless.
766   //
767   // If we ever do, these threading issues should be considered.
768
769   //
770   // WARNING: this function may be called by free().
771   //
772   // There is a potential deadlock scenario:
773   // Thread 1: open() -> takes lock1 -> free() -> takes lock2
774   // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1
775   //
776   // Note that open() above could be any function that takes a lock that is
777   // shared with munmap (this includes munmap!)
778   //
779   // To prevent this, we avoid taking locks in munmap() that are used by other
780   // nacl_io functions that may call free. Specifically, we only take the
781   // mmap_lock, which is only shared with mmap() above. There is still a
782   // possibility of deadlock if mmap() or munmap() calls free(), so this is not
783   // allowed.
784   //
785   // Unfortunately, munmap still needs to acquire other locks; see the call to
786   // ReleaseHandle below which takes the process lock. This is safe as long as
787   // this is never executed from free() -- we can be reasonably sure this is
788   // true, because malloc only makes anonymous mmap() requests, and should only
789   // be munmapping those allocations. We never add to mmap_info_list_ for
790   // anonymous maps, so the unmap_list should always be empty when called from
791   // free().
792   return 0;
793 }
794
795 int KernelProxy::tcflush(int fd, int queue_selector) {
796   ScopedKernelHandle handle;
797   Error error = AcquireHandle(fd, &handle);
798   if (error) {
799     errno = error;
800     return -1;
801   }
802
803   error = handle->node()->Tcflush(queue_selector);
804   if (error) {
805     errno = error;
806     return -1;
807   }
808
809   return 0;
810 }
811
812 int KernelProxy::tcgetattr(int fd, struct termios* termios_p) {
813   ScopedKernelHandle handle;
814   Error error = AcquireHandle(fd, &handle);
815   if (error) {
816     errno = error;
817     return -1;
818   }
819
820   error = handle->node()->Tcgetattr(termios_p);
821   if (error) {
822     errno = error;
823     return -1;
824   }
825
826   return 0;
827 }
828
829 int KernelProxy::tcsetattr(int fd, int optional_actions,
830                            const struct termios *termios_p) {
831   ScopedKernelHandle handle;
832   Error error = AcquireHandle(fd, &handle);
833   if (error) {
834     errno = error;
835     return -1;
836   }
837
838   error = handle->node()->Tcsetattr(optional_actions, termios_p);
839   if (error) {
840     errno = error;
841     return -1;
842   }
843
844   return 0;
845 }
846
847 int KernelProxy::kill(pid_t pid, int sig) {
848   // Currently we don't even pretend that other processes exist
849   // so we can only send a signal to outselves.  For kill(2)
850   // pid 0 means the current process group and -1 means all the
851   // processes we have permission to send signals to.
852   if (pid != getpid() && pid != -1 && pid != 0) {
853     errno = ESRCH;
854     return -1;
855   }
856
857   // Raise an event so that select/poll get interrupted.
858   AUTO_LOCK(signal_emitter_->GetLock())
859   signal_emitter_->RaiseEvents_Locked(POLLERR);
860   switch (sig) {
861     case SIGWINCH:
862       if (sigwinch_handler_ != SIG_IGN)
863         sigwinch_handler_(SIGWINCH);
864       break;
865
866     case SIGUSR1:
867     case SIGUSR2:
868       break;
869
870     default:
871       errno = EINVAL;
872       return -1;
873   }
874   return 0;
875 }
876
877 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) {
878   switch (signum) {
879     // Handled signals.
880     case SIGWINCH: {
881       sighandler_t old_value = sigwinch_handler_;
882       if (handler == SIG_DFL)
883         handler = SIG_IGN;
884       sigwinch_handler_ = handler;
885       return old_value;
886     }
887
888     // Known signals
889     case SIGHUP:
890     case SIGINT:
891     case SIGKILL:
892     case SIGPIPE:
893     case SIGPOLL:
894     case SIGPROF:
895     case SIGTERM:
896     case SIGCHLD:
897     case SIGURG:
898     case SIGFPE:
899     case SIGILL:
900     case SIGQUIT:
901     case SIGSEGV:
902     case SIGTRAP:
903       if (handler == SIG_DFL)
904         return SIG_DFL;
905       break;
906   }
907
908   errno = EINVAL;
909   return SIG_ERR;
910 }
911
912 #ifdef PROVIDES_SOCKET_API
913
914 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds,
915                         fd_set* exceptfds, struct timeval* timeout) {
916   fd_set ignore;
917   std::vector<pollfd> pollfds;
918
919   // Simplify logic, by using an IGNORE set for any undefined set
920   FD_ZERO(&ignore);
921   if (NULL == readfds)
922     readfds = &ignore;
923   if (NULL == writefds)
924     writefds = &ignore;
925   if (NULL == exceptfds)
926     exceptfds = &ignore;
927
928   for (int fd = 0; fd < nfds; fd++) {
929     int events = 0;
930     if (FD_ISSET(fd, readfds))
931       events |= POLLIN;
932
933     if (FD_ISSET(fd, writefds))
934       events |= POLLOUT;
935
936     if (FD_ISSET(fd, exceptfds))
937       events |= POLLERR | POLLHUP;
938
939     if (events) {
940       pollfd info;
941       info.fd = fd;
942       info.events = events;
943       pollfds.push_back(info);
944     }
945   }
946
947   FD_ZERO(readfds);
948   FD_ZERO(writefds);
949   FD_ZERO(exceptfds);
950
951   // NULL timeout signals wait forever.
952   int ms_timeout = -1;
953   if (timeout != NULL) {
954     int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000);
955
956     // If the timeout is invalid or too long (larger than signed 32 bit).
957     if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) ||
958         (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) ||
959         (ms < 0) || (ms >= INT_MAX)) {
960       errno = EINVAL;
961       return -1;
962     }
963
964     ms_timeout = static_cast<int>(ms);
965   }
966
967   int result = poll(&pollfds[0], pollfds.size(), ms_timeout);
968   if (result == -1)
969     return -1;
970
971   int event_cnt = 0;
972   for (size_t index = 0; index < pollfds.size(); index++) {
973     pollfd* info = &pollfds[index];
974     if (info->revents & POLLIN) {
975       FD_SET(info->fd, readfds);
976       event_cnt++;
977     }
978     if (info->revents & POLLOUT) {
979       FD_SET(info->fd, writefds);
980       event_cnt++;
981     }
982     if (info->revents & (POLLHUP | POLLERR)) {
983       FD_SET(info->fd, exceptfds);
984       event_cnt++;
985     }
986   }
987
988   return event_cnt;
989 }
990
991 struct PollInfo {
992   PollInfo() : index(-1) {};
993
994   std::vector<struct pollfd*> fds;
995   int index;
996 };
997
998 typedef std::map<EventEmitter*, PollInfo> EventPollMap_t;
999
1000 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) {
1001   EventPollMap_t event_map;
1002
1003   std::vector<EventRequest> requests;
1004   size_t event_cnt = 0;
1005
1006   for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) {
1007     ScopedKernelHandle handle;
1008     struct pollfd* fd_info = &fds[index];
1009     Error err = AcquireHandle(fd_info->fd, &handle);
1010
1011     fd_info->revents = 0;
1012
1013     // If the node isn't open, or somehow invalid, mark it so.
1014     if (err != 0) {
1015       fd_info->revents = POLLNVAL;
1016       event_cnt++;
1017       continue;
1018     }
1019
1020     // If it's already signaled, then just capture the event
1021     ScopedEventEmitter emitter(handle->node()->GetEventEmitter());
1022     int events = POLLIN | POLLOUT;
1023     if (emitter)
1024       events = emitter->GetEventStatus();
1025
1026     if (events & fd_info->events) {
1027       fd_info->revents = events & fd_info->events;
1028       event_cnt++;
1029       continue;
1030     }
1031
1032     if (NULL == emitter) {
1033       fd_info->revents = POLLNVAL;
1034       event_cnt++;
1035       continue;
1036     }
1037
1038     // Otherwise try to track it.
1039     PollInfo* info = &event_map[emitter.get()];
1040     if (info->index == -1) {
1041       EventRequest request;
1042       request.emitter = emitter;
1043       request.filter = fd_info->events;
1044       request.events = 0;
1045
1046       info->index = requests.size();
1047       requests.push_back(request);
1048     }
1049     info->fds.push_back(fd_info);
1050     requests[info->index].filter |= fd_info->events;
1051   }
1052
1053   // If nothing is signaled, then we must wait on the event map
1054   if (0 == event_cnt) {
1055     EventListenerPoll wait;
1056     Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout);
1057     if ((err != 0) && (err != ETIMEDOUT)) {
1058       errno = err;
1059       return -1;
1060     }
1061
1062     for (size_t rindex = 0; rindex < requests.size(); rindex++) {
1063       EventRequest* request = &requests[rindex];
1064       if (request->events) {
1065         PollInfo* poll_info = &event_map[request->emitter.get()];
1066         for (size_t findex = 0; findex < poll_info->fds.size(); findex++) {
1067           struct pollfd* fd_info = poll_info->fds[findex];
1068           uint32_t events = fd_info->events & request->events;
1069           if (events) {
1070             fd_info->revents = events;
1071             event_cnt++;
1072           }
1073         }
1074       }
1075     }
1076   }
1077
1078   return event_cnt;
1079 }
1080
1081
1082 // Socket Functions
1083 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
1084   if (NULL == addr || NULL == len) {
1085     errno = EFAULT;
1086     return -1;
1087   }
1088
1089   ScopedKernelHandle handle;
1090   Error error = AcquireHandle(fd, &handle);
1091   if (error) {
1092     errno = error;
1093     return -1;
1094   }
1095
1096   PP_Resource new_sock = 0;
1097   error = handle->Accept(&new_sock, addr, len);
1098   if (error != 0) {
1099     errno = error;
1100     return -1;
1101   }
1102
1103   MountNodeSocket* sock = new MountNodeTCP(stream_mount_.get(), new_sock);
1104
1105   // The MountNodeSocket now holds a reference to the new socket
1106   // so we release ours.
1107   ppapi_->ReleaseResource(new_sock);
1108   error = sock->Init(S_IREAD | S_IWRITE);
1109   if (error != 0) {
1110     errno = error;
1111     return -1;
1112   }
1113
1114   ScopedMountNode node(sock);
1115   ScopedKernelHandle new_handle(new KernelHandle(stream_mount_, node));
1116   error = sock->Init(O_RDWR);
1117   if (error != 0) {
1118     errno = error;
1119     return -1;
1120   }
1121
1122   return AllocateFD(new_handle);
1123 }
1124
1125 int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) {
1126   if (NULL == addr) {
1127     errno = EFAULT;
1128     return -1;
1129   }
1130
1131   ScopedKernelHandle handle;
1132   if (AcquireSocketHandle(fd, &handle) == -1)
1133     return -1;
1134
1135   Error err = handle->socket_node()->Bind(addr, len);
1136   if (err != 0) {
1137     errno = err;
1138     return -1;
1139   }
1140
1141   return 0;
1142 }
1143
1144 int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) {
1145   if (NULL == addr) {
1146     errno = EFAULT;
1147     return -1;
1148   }
1149
1150   ScopedKernelHandle handle;
1151   Error error = AcquireHandle(fd, &handle);
1152   if (error) {
1153     errno = error;
1154     return -1;
1155   }
1156
1157   error = handle->Connect(addr, len);
1158   if (error != 0) {
1159     errno = error;
1160     return -1;
1161   }
1162
1163   return 0;
1164 }
1165
1166 struct hostent* KernelProxy::gethostbyname(const char* name) {
1167   return host_resolver_.gethostbyname(name);
1168 }
1169
1170 int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
1171   if (NULL == addr || NULL == len) {
1172     errno = EFAULT;
1173     return -1;
1174   }
1175
1176   ScopedKernelHandle handle;
1177   if (AcquireSocketHandle(fd, &handle) == -1)
1178     return -1;
1179
1180   Error err = handle->socket_node()->GetPeerName(addr, len);
1181   if (err != 0) {
1182     errno = err;
1183     return -1;
1184   }
1185
1186   return 0;
1187 }
1188
1189 int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
1190   if (NULL == addr || NULL == len) {
1191     errno = EFAULT;
1192     return -1;
1193   }
1194
1195   ScopedKernelHandle handle;
1196   if (AcquireSocketHandle(fd, &handle) == -1)
1197     return -1;
1198
1199   Error err = handle->socket_node()->GetSockName(addr, len);
1200   if (err != 0) {
1201     errno = err;
1202     return -1;
1203   }
1204
1205   return 0;
1206 }
1207
1208 int KernelProxy::getsockopt(int fd,
1209                             int lvl,
1210                             int optname,
1211                             void* optval,
1212                             socklen_t* len) {
1213   if (NULL == optval || NULL == len) {
1214     errno = EFAULT;
1215     return -1;
1216   }
1217
1218   ScopedKernelHandle handle;
1219   if (AcquireSocketHandle(fd, &handle) == -1)
1220     return -1;
1221
1222   Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len);
1223   if (err != 0) {
1224     errno = err;
1225     return -1;
1226   }
1227
1228   return 0;
1229 }
1230
1231 int KernelProxy::listen(int fd, int backlog) {
1232   ScopedKernelHandle handle;
1233   if (AcquireSocketHandle(fd, &handle) == -1)
1234     return -1;
1235
1236   Error err = handle->socket_node()->Listen(backlog);
1237   if (err != 0) {
1238     errno = err;
1239     return -1;
1240   }
1241
1242   return 0;
1243 }
1244
1245 ssize_t KernelProxy::recv(int fd,
1246                           void* buf,
1247                           size_t len,
1248                           int flags) {
1249   if (NULL == buf) {
1250     errno = EFAULT;
1251     return -1;
1252   }
1253
1254   ScopedKernelHandle handle;
1255   Error error = AcquireHandle(fd, &handle);
1256   if (error) {
1257     errno = error;
1258     return -1;
1259   }
1260
1261   int out_len = 0;
1262   error = handle->Recv(buf, len, flags, &out_len);
1263   if (error != 0) {
1264     errno = error;
1265     return -1;
1266   }
1267
1268   return static_cast<ssize_t>(out_len);
1269 }
1270
1271 ssize_t KernelProxy::recvfrom(int fd,
1272                               void* buf,
1273                               size_t len,
1274                               int flags,
1275                               struct sockaddr* addr,
1276                               socklen_t* addrlen) {
1277   // According to the manpage, recvfrom with a null addr is identical to recv.
1278   if (NULL == addr) {
1279     return recv(fd, buf, len, flags);
1280   }
1281
1282   if (NULL == buf || NULL == addrlen) {
1283     errno = EFAULT;
1284     return -1;
1285   }
1286
1287   ScopedKernelHandle handle;
1288   Error error = AcquireHandle(fd, &handle);
1289   if (error) {
1290     errno = error;
1291     return -1;
1292   }
1293
1294   int out_len = 0;
1295   error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len);
1296   if (error != 0) {
1297     errno = error;
1298     return -1;
1299   }
1300
1301   return static_cast<ssize_t>(out_len);
1302 }
1303
1304 ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) {
1305   if (NULL == msg ) {
1306     errno = EFAULT;
1307     return -1;
1308   }
1309
1310   ScopedKernelHandle handle;
1311   if (AcquireSocketHandle(fd, &handle) == -1)
1312     return -1;
1313
1314   errno = EOPNOTSUPP;
1315   return -1;
1316 }
1317
1318 ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) {
1319   if (NULL == buf) {
1320     errno = EFAULT;
1321     return -1;
1322   }
1323
1324   ScopedKernelHandle handle;
1325   Error error = AcquireHandle(fd, &handle);
1326   if (error) {
1327     errno = error;
1328     return -1;
1329   }
1330
1331   int out_len = 0;
1332   error = handle->Send(buf, len, flags, &out_len);
1333   if (error != 0) {
1334     errno = error;
1335     return -1;
1336   }
1337
1338   return static_cast<ssize_t>(out_len);
1339 }
1340
1341 ssize_t KernelProxy::sendto(int fd,
1342                             const void* buf,
1343                             size_t len,
1344                             int flags,
1345                             const struct sockaddr* addr,
1346                             socklen_t addrlen) {
1347   // According to the manpage, sendto with a null addr is identical to send.
1348   if (NULL == addr) {
1349     return send(fd, buf, len, flags);
1350   }
1351
1352   if (NULL == buf) {
1353     errno = EFAULT;
1354     return -1;
1355   }
1356
1357   ScopedKernelHandle handle;
1358   Error error = AcquireHandle(fd, &handle);
1359   if (error) {
1360     errno = error;
1361     return -1;
1362   }
1363
1364   int out_len = 0;
1365   error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len);
1366   if (error != 0) {
1367     errno = error;
1368     return -1;
1369   }
1370
1371   return static_cast<ssize_t>(out_len);
1372 }
1373
1374 ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) {
1375   if (NULL == msg) {
1376     errno = EFAULT;
1377     return -1;
1378   }
1379
1380   ScopedKernelHandle handle;
1381   if (AcquireSocketHandle(fd, &handle) == -1)
1382     return -1;
1383
1384   errno = EOPNOTSUPP;
1385   return -1;
1386 }
1387
1388 int KernelProxy::setsockopt(int fd,
1389                             int lvl,
1390                             int optname,
1391                             const void* optval,
1392                             socklen_t len) {
1393   if (NULL == optval) {
1394     errno = EFAULT;
1395     return -1;
1396   }
1397
1398   ScopedKernelHandle handle;
1399   if (AcquireSocketHandle(fd, &handle) == -1)
1400     return -1;
1401
1402   Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len);
1403   if (err != 0) {
1404     errno = err;
1405     return -1;
1406   }
1407
1408   return 0;
1409 }
1410
1411 int KernelProxy::shutdown(int fd, int how) {
1412   ScopedKernelHandle handle;
1413   if (AcquireSocketHandle(fd, &handle) == -1)
1414     return -1;
1415
1416   Error err = handle->socket_node()->Shutdown(how);
1417   if (err != 0) {
1418     errno = err;
1419     return -1;
1420   }
1421
1422   return 0;
1423 }
1424
1425 int KernelProxy::socket(int domain, int type, int protocol) {
1426   if (AF_INET != domain && AF_INET6 != domain) {
1427     errno = EAFNOSUPPORT;
1428     return -1;
1429   }
1430
1431   MountNodeSocket* sock = NULL;
1432   switch (type) {
1433     case SOCK_DGRAM:
1434       sock = new MountNodeUDP(stream_mount_.get());
1435       break;
1436
1437     case SOCK_STREAM:
1438       sock = new MountNodeTCP(stream_mount_.get());
1439       break;
1440
1441     default:
1442       errno = EPROTONOSUPPORT;
1443       return -1;
1444   }
1445
1446   ScopedMountNode node(sock);
1447   Error rtn = sock->Init(S_IREAD | S_IWRITE);
1448   if (rtn != 0) {
1449     errno = rtn;
1450     return -1;
1451   }
1452
1453   ScopedKernelHandle handle(new KernelHandle(stream_mount_, node));
1454   rtn = handle->Init(O_RDWR);
1455   if (rtn != 0) {
1456     errno = rtn;
1457     return -1;
1458   }
1459
1460   return AllocateFD(handle);
1461 }
1462
1463 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) {
1464   if (NULL == sv) {
1465     errno = EFAULT;
1466     return -1;
1467   }
1468
1469   // Catch-22: We don't support AF_UNIX, but any other AF doesn't support
1470   // socket pairs. Thus, this function always fails.
1471   if (AF_UNIX != domain) {
1472     errno = EPROTONOSUPPORT;
1473     return -1;
1474   }
1475
1476   if (AF_INET != domain && AF_INET6 != domain) {
1477     errno = EAFNOSUPPORT;
1478     return -1;
1479   }
1480
1481   // We cannot reach this point.
1482   errno = ENOSYS;
1483   return -1;
1484 }
1485
1486 int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) {
1487   Error error = AcquireHandle(fd, handle);
1488
1489   if (error) {
1490     errno = error;
1491     return -1;
1492   }
1493
1494   if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) {
1495     errno = ENOTSOCK;
1496     return -1;
1497   }
1498
1499   return 0;
1500 }
1501
1502 #endif  // PROVIDES_SOCKET_API
1503
1504 }  // namespace_nacl_io