| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "nacl_io/kernel_proxy.h" | 5 #include "nacl_io/kernel_proxy.h" |
| 6 | 6 |
| 7 | 7 |
| 8 #include <assert.h> | 8 #include <assert.h> |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| 11 #include <limits.h> | 11 #include <limits.h> |
| 12 #include <poll.h> | 12 #include <poll.h> |
| 13 #include <pthread.h> | 13 #include <pthread.h> |
| 14 #include <stdio.h> | 14 #include <stdio.h> |
| 15 #include <string.h> | 15 #include <string.h> |
| 16 #include <sys/time.h> | 16 #include <sys/time.h> |
| 17 #include <unistd.h> | 17 #include <unistd.h> |
| 18 | 18 |
| 19 #include <iterator> | 19 #include <iterator> |
| 20 #include <string> | 20 #include <string> |
| 21 | 21 |
| 22 #include "nacl_io/dbgprint.h" |
| 22 #include "nacl_io/host_resolver.h" | 23 #include "nacl_io/host_resolver.h" |
| 23 #include "nacl_io/kernel_handle.h" | 24 #include "nacl_io/kernel_handle.h" |
| 24 #include "nacl_io/kernel_wrap_real.h" | 25 #include "nacl_io/kernel_wrap_real.h" |
| 25 #include "nacl_io/mount.h" | 26 #include "nacl_io/mount.h" |
| 26 #include "nacl_io/mount_dev.h" | 27 #include "nacl_io/mount_dev.h" |
| 27 #include "nacl_io/mount_html5fs.h" | 28 #include "nacl_io/mount_html5fs.h" |
| 28 #include "nacl_io/mount_http.h" | 29 #include "nacl_io/mount_http.h" |
| 29 #include "nacl_io/mount_mem.h" | 30 #include "nacl_io/mount_mem.h" |
| 30 #include "nacl_io/mount_node.h" | 31 #include "nacl_io/mount_node.h" |
| 31 #include "nacl_io/mount_node_tcp.h" | 32 #include "nacl_io/mount_node_tcp.h" |
| 32 #include "nacl_io/mount_node_udp.h" | 33 #include "nacl_io/mount_node_udp.h" |
| 33 #include "nacl_io/mount_passthrough.h" | 34 #include "nacl_io/mount_passthrough.h" |
| 34 #include "nacl_io/osmman.h" | 35 #include "nacl_io/osmman.h" |
| 35 #include "nacl_io/ossocket.h" | 36 #include "nacl_io/ossocket.h" |
| 36 #include "nacl_io/osstat.h" | 37 #include "nacl_io/osstat.h" |
| 37 #include "nacl_io/path.h" | 38 #include "nacl_io/path.h" |
| 38 #include "nacl_io/pepper_interface.h" | 39 #include "nacl_io/pepper_interface.h" |
| 39 #include "nacl_io/typed_mount_factory.h" | 40 #include "nacl_io/typed_mount_factory.h" |
| 40 #include "sdk_util/auto_lock.h" | 41 #include "sdk_util/auto_lock.h" |
| 41 #include "sdk_util/ref_object.h" | 42 #include "sdk_util/ref_object.h" |
| 42 | 43 |
| 43 #ifndef MAXPATHLEN | 44 #ifndef MAXPATHLEN |
| 44 #define MAXPATHLEN 256 | 45 #define MAXPATHLEN 256 |
| 45 #endif | 46 #endif |
| 46 | 47 |
| 47 namespace nacl_io { | 48 namespace nacl_io { |
| 48 | 49 |
| 49 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) { | 50 class SignalEmitter : public EventEmitter { |
| 51 public: |
| 52 // From EventEmitter. The SignalEmitter exists in order |
| 53 // to inturrupt anything waiting in select()/poll() when kill() |
| 54 // is called. It is an edge trigger only and therefore has no |
| 55 // persistent readable/wriable/error state. |
| 56 uint32_t GetEventStatus() { |
| 57 return 0; |
| 58 } |
| 59 |
| 60 int GetType() { |
| 61 // For lack of a better type, report socket to signify it can be in an |
| 62 // used to signal. |
| 63 return S_IFSOCK; |
| 64 } |
| 65 |
| 66 void SignalOccurred() { |
| 67 RaiseEvent(POLLERR); |
| 68 } |
| 69 }; |
| 70 |
| 71 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), |
| 72 sigwinch_handler_(SIG_IGN), |
| 73 signal_emitter_(new SignalEmitter) { |
| 74 |
| 50 } | 75 } |
| 51 | 76 |
| 52 KernelProxy::~KernelProxy() { | 77 KernelProxy::~KernelProxy() { |
| 53 // Clean up the MountFactories. | 78 // Clean up the MountFactories. |
| 54 for (MountFactoryMap_t::iterator i = factories_.begin(); | 79 for (MountFactoryMap_t::iterator i = factories_.begin(); |
| 55 i != factories_.end(); | 80 i != factories_.end(); |
| 56 ++i) { | 81 ++i) { |
| 57 delete i->second; | 82 delete i->second; |
| 58 } | 83 } |
| 59 | 84 |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 error = handle->node()->Tcsetattr(optional_actions, termios_p); | 730 error = handle->node()->Tcsetattr(optional_actions, termios_p); |
| 706 if (error) { | 731 if (error) { |
| 707 errno = error; | 732 errno = error; |
| 708 return -1; | 733 return -1; |
| 709 } | 734 } |
| 710 | 735 |
| 711 return 0; | 736 return 0; |
| 712 } | 737 } |
| 713 | 738 |
| 714 int KernelProxy::kill(pid_t pid, int sig) { | 739 int KernelProxy::kill(pid_t pid, int sig) { |
| 715 errno = EINVAL; | 740 // Currently we don't even pretend that other processes exist |
| 716 return -1; | 741 // so we can only send a signal to outselves. For kill(2) |
| 742 // pid 0 means the current process group and -1 means all the |
| 743 // processes we have permission to send signals to. |
| 744 if (pid != getpid() && pid != -1 && pid != 0) { |
| 745 errno = ESRCH; |
| 746 return -1; |
| 747 } |
| 748 |
| 749 dbgprintf("raising event ...\n"); |
| 750 // Raise an event so that select/poll get interrupted. |
| 751 static_cast<SignalEmitter&>(*signal_emitter_).SignalOccurred(); |
| 752 switch (sig) { |
| 753 case SIGWINCH: |
| 754 if (sigwinch_handler_ != SIG_IGN) |
| 755 sigwinch_handler_(SIGWINCH); |
| 756 break; |
| 757 |
| 758 case SIGUSR1: |
| 759 case SIGUSR2: |
| 760 break; |
| 761 |
| 762 default: |
| 763 errno = EINVAL; |
| 764 return -1; |
| 765 } |
| 766 |
| 767 return 0; |
| 717 } | 768 } |
| 718 | 769 |
| 719 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { | 770 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { |
| 771 switch (signum) { |
| 772 // Handled signals. |
| 773 case SIGWINCH: { |
| 774 sighandler_t old_value = sigwinch_handler_; |
| 775 if (handler == SIG_DFL) |
| 776 handler = SIG_IGN; |
| 777 sigwinch_handler_ = handler; |
| 778 return old_value; |
| 779 } |
| 780 |
| 781 // Known signals |
| 782 case SIGHUP: |
| 783 case SIGINT: |
| 784 case SIGKILL: |
| 785 case SIGPIPE: |
| 786 case SIGPOLL: |
| 787 case SIGPROF: |
| 788 case SIGTERM: |
| 789 case SIGCHLD: |
| 790 case SIGURG: |
| 791 case SIGFPE: |
| 792 case SIGILL: |
| 793 case SIGQUIT: |
| 794 case SIGSEGV: |
| 795 case SIGTRAP: |
| 796 if (handler == SIG_DFL) |
| 797 return SIG_DFL; |
| 798 break; |
| 799 } |
| 800 |
| 720 errno = EINVAL; | 801 errno = EINVAL; |
| 721 return SIG_ERR; | 802 return SIG_ERR; |
| 722 } | 803 } |
| 723 | 804 |
| 724 #ifdef PROVIDES_SOCKET_API | 805 #ifdef PROVIDES_SOCKET_API |
| 725 | 806 |
| 726 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, | 807 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, |
| 727 fd_set* exceptfds, struct timeval* timeout) { | 808 fd_set* exceptfds, struct timeval* timeout) { |
| 728 ScopedEventListener listener(new EventListener); | 809 ScopedEventListener listener(new EventListener); |
| 810 |
| 729 std::vector<struct pollfd> fds; | 811 std::vector<struct pollfd> fds; |
| 730 | 812 |
| 731 fd_set readout, writeout, exceptout; | 813 fd_set readout, writeout, exceptout; |
| 732 | 814 |
| 733 FD_ZERO(&readout); | 815 FD_ZERO(&readout); |
| 734 FD_ZERO(&writeout); | 816 FD_ZERO(&writeout); |
| 735 FD_ZERO(&exceptout); | 817 FD_ZERO(&exceptout); |
| 736 | 818 |
| 737 int fd; | 819 int fd; |
| 738 size_t event_cnt = 0; | 820 size_t event_cnt = 0; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || | 886 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || |
| 805 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || | 887 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || |
| 806 (ms < 0) || (ms >= INT_MAX)) { | 888 (ms < 0) || (ms >= INT_MAX)) { |
| 807 errno = EINVAL; | 889 errno = EINVAL; |
| 808 return -1; | 890 return -1; |
| 809 } | 891 } |
| 810 | 892 |
| 811 ms_timeout = static_cast<int>(ms); | 893 ms_timeout = static_cast<int>(ms); |
| 812 } | 894 } |
| 813 | 895 |
| 896 // Add a special node to listen for events |
| 897 // coming from the KernelProxy itself (kill will |
| 898 // generated a SIGERR event). |
| 899 listener->Track(-1, signal_emitter_, POLLERR, -1); |
| 900 event_track += 1; |
| 901 |
| 814 events.resize(event_track); | 902 events.resize(event_track); |
| 903 |
| 904 bool interrupted = false; |
| 815 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt); | 905 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt); |
| 816 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) { | 906 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) { |
| 907 if (events[fd].user_data == static_cast<uint64_t>(-1)) { |
| 908 if (events[fd].events & POLLERR) { |
| 909 interrupted = true; |
| 910 } |
| 911 continue; |
| 912 } |
| 913 |
| 817 if (events[fd].events & POLLIN) { | 914 if (events[fd].events & POLLIN) { |
| 818 FD_SET(events[fd].user_data, &readout); | 915 FD_SET(events[fd].user_data, &readout); |
| 819 event_cnt++; | 916 event_cnt++; |
| 820 } | 917 } |
| 821 | 918 |
| 822 if (events[fd].events & POLLOUT) { | 919 if (events[fd].events & POLLOUT) { |
| 823 FD_SET(events[fd].user_data, &writeout); | 920 FD_SET(events[fd].user_data, &writeout); |
| 824 event_cnt++; | 921 event_cnt++; |
| 825 } | 922 } |
| 826 | 923 |
| 827 if (events[fd].events & (POLLERR | POLLHUP)) { | 924 if (events[fd].events & (POLLERR | POLLHUP)) { |
| 828 FD_SET(events[fd].user_data, &exceptout); | 925 FD_SET(events[fd].user_data, &exceptout); |
| 829 event_cnt++; | 926 event_cnt++; |
| 830 } | 927 } |
| 831 } | 928 } |
| 929 |
| 930 if (0 == event_cnt && interrupted) { |
| 931 errno = EINTR; |
| 932 return -1; |
| 933 } |
| 832 } | 934 } |
| 833 | 935 |
| 834 // Copy out the results | 936 // Copy out the results |
| 835 if (readfds != NULL) | 937 if (readfds != NULL) |
| 836 *readfds = readout; | 938 *readfds = readout; |
| 837 | 939 |
| 838 if (writefds != NULL) | 940 if (writefds != NULL) |
| 839 *writefds = writeout; | 941 *writefds = writeout; |
| 840 | 942 |
| 841 if (exceptfds != NULL) | 943 if (exceptfds != NULL) |
| 842 *exceptfds = exceptout; | 944 *exceptfds = exceptout; |
| 843 | 945 |
| 844 return event_cnt; | 946 return event_cnt; |
| 845 } | 947 } |
| 846 | 948 |
| 847 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { | 949 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { |
| 848 ScopedEventListener listener(new EventListener); | 950 ScopedEventListener listener(new EventListener); |
| 951 listener->Track(-1, signal_emitter_, POLLERR, 0); |
| 849 | 952 |
| 850 int index; | 953 int index; |
| 851 size_t event_cnt = 0; | 954 size_t event_cnt = 0; |
| 852 size_t event_track = 0; | 955 size_t event_track = 1; |
| 853 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { | 956 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { |
| 854 ScopedKernelHandle handle; | 957 ScopedKernelHandle handle; |
| 855 struct pollfd* info = &fds[index]; | 958 struct pollfd* info = &fds[index]; |
| 856 Error err = AcquireHandle(info->fd, &handle); | 959 Error err = AcquireHandle(info->fd, &handle); |
| 857 | 960 |
| 858 // If the node isn't open, or somehow invalid, mark it so. | 961 // If the node isn't open, or somehow invalid, mark it so. |
| 859 if (err != 0) { | 962 if (err != 0) { |
| 860 info->revents = POLLNVAL; | 963 info->revents = POLLNVAL; |
| 861 event_cnt++; | 964 event_cnt++; |
| 862 continue; | 965 continue; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 877 continue; | 980 continue; |
| 878 } | 981 } |
| 879 event_track++; | 982 event_track++; |
| 880 } | 983 } |
| 881 | 984 |
| 882 // If nothing is signaled, then we must wait. | 985 // If nothing is signaled, then we must wait. |
| 883 if (0 == event_cnt) { | 986 if (0 == event_cnt) { |
| 884 std::vector<EventData> events; | 987 std::vector<EventData> events; |
| 885 int ready_cnt; | 988 int ready_cnt; |
| 886 | 989 |
| 990 bool interrupted = false; |
| 887 events.resize(event_track); | 991 events.resize(event_track); |
| 888 listener->Wait(events.data(), event_track, timeout, &ready_cnt); | 992 listener->Wait(events.data(), event_track, timeout, &ready_cnt); |
| 889 for (index = 0; index < ready_cnt; index++) { | 993 for (index = 0; index < ready_cnt; index++) { |
| 890 struct pollfd* info = &fds[events[index].user_data]; | 994 struct pollfd* info = &fds[events[index].user_data]; |
| 995 if (!info) { |
| 996 interrupted = true; |
| 997 continue; |
| 998 } |
| 891 | 999 |
| 892 info->revents = events[index].events; | 1000 info->revents = events[index].events; |
| 893 event_cnt++; | 1001 event_cnt++; |
| 894 } | 1002 } |
| 1003 if (0 == event_cnt && interrupted) { |
| 1004 errno = EINTR; |
| 1005 return -1; |
| 1006 } |
| 895 } | 1007 } |
| 896 | 1008 |
| 897 return event_cnt; | 1009 return event_cnt; |
| 898 } | 1010 } |
| 899 | 1011 |
| 900 | 1012 |
| 901 | 1013 |
| 902 // Socket Functions | 1014 // Socket Functions |
| 903 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { | 1015 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { |
| 904 if (NULL == addr || NULL == len) { | 1016 if (NULL == addr || NULL == len) { |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 errno = ENOTSOCK; | 1369 errno = ENOTSOCK; |
| 1258 return -1; | 1370 return -1; |
| 1259 } | 1371 } |
| 1260 | 1372 |
| 1261 return 0; | 1373 return 0; |
| 1262 } | 1374 } |
| 1263 | 1375 |
| 1264 #endif // PROVIDES_SOCKET_API | 1376 #endif // PROVIDES_SOCKET_API |
| 1265 | 1377 |
| 1266 } // namespace_nacl_io | 1378 } // namespace_nacl_io |
| OLD | NEW |