Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc

Issue 23005005: [NaCl SDK] nacl_io: Add initial implementations of kill and signal (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 18
18 #include <iterator> 19 #include <iterator>
19 #include <string> 20 #include <string>
20 21
22 #include "nacl_io/dbgprint.h"
21 #include "nacl_io/host_resolver.h" 23 #include "nacl_io/host_resolver.h"
22 #include "nacl_io/kernel_handle.h" 24 #include "nacl_io/kernel_handle.h"
23 #include "nacl_io/kernel_wrap_real.h" 25 #include "nacl_io/kernel_wrap_real.h"
24 #include "nacl_io/mount.h" 26 #include "nacl_io/mount.h"
25 #include "nacl_io/mount_dev.h" 27 #include "nacl_io/mount_dev.h"
26 #include "nacl_io/mount_html5fs.h" 28 #include "nacl_io/mount_html5fs.h"
27 #include "nacl_io/mount_http.h" 29 #include "nacl_io/mount_http.h"
28 #include "nacl_io/mount_mem.h" 30 #include "nacl_io/mount_mem.h"
29 #include "nacl_io/mount_node.h" 31 #include "nacl_io/mount_node.h"
30 #include "nacl_io/mount_node_tcp.h" 32 #include "nacl_io/mount_node_tcp.h"
31 #include "nacl_io/mount_node_udp.h" 33 #include "nacl_io/mount_node_udp.h"
32 #include "nacl_io/mount_passthrough.h" 34 #include "nacl_io/mount_passthrough.h"
33 #include "nacl_io/osmman.h" 35 #include "nacl_io/osmman.h"
34 #include "nacl_io/ossocket.h" 36 #include "nacl_io/ossocket.h"
35 #include "nacl_io/osstat.h" 37 #include "nacl_io/osstat.h"
36 #include "nacl_io/path.h" 38 #include "nacl_io/path.h"
37 #include "nacl_io/pepper_interface.h" 39 #include "nacl_io/pepper_interface.h"
38 #include "nacl_io/typed_mount_factory.h" 40 #include "nacl_io/typed_mount_factory.h"
39 #include "sdk_util/auto_lock.h" 41 #include "sdk_util/auto_lock.h"
40 #include "sdk_util/ref_object.h" 42 #include "sdk_util/ref_object.h"
41 43
42 #ifndef MAXPATHLEN 44 #ifndef MAXPATHLEN
43 #define MAXPATHLEN 256 45 #define MAXPATHLEN 256
44 #endif 46 #endif
45 47
46 namespace nacl_io { 48 namespace nacl_io {
47 49
48 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) { 50 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL),
51 sigwinch_handler_(SIG_IGN) {
49 } 52 }
50 53
51 KernelProxy::~KernelProxy() { 54 KernelProxy::~KernelProxy() {
52 // Clean up the MountFactories. 55 // Clean up the MountFactories.
53 for (MountFactoryMap_t::iterator i = factories_.begin(); 56 for (MountFactoryMap_t::iterator i = factories_.begin();
54 i != factories_.end(); 57 i != factories_.end();
55 ++i) { 58 ++i) {
56 delete i->second; 59 delete i->second;
57 } 60 }
58 61
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 706
704 error = handle->node()->Tcsetattr(optional_actions, termios_p); 707 error = handle->node()->Tcsetattr(optional_actions, termios_p);
705 if (error) { 708 if (error) {
706 errno = error; 709 errno = error;
707 return -1; 710 return -1;
708 } 711 }
709 712
710 return 0; 713 return 0;
711 } 714 }
712 715
716 int KernelProxy::kill(pid_t pid, int sig) {
717 // Currently we don't even pretend that other processes exist
718 // so we can only send a signal to outselves. For kill(2)
719 // pid 0 means the current process group and -1 means all the
720 // processes we have permission to send signals to.
721 if (pid != getpid() && pid != -1 && pid != 0) {
722 errno = ESRCH;
723 return -1;
724 }
725
726 dbgprintf("raising event ...\n");
727 // Raise an event so that select/poll get interrupted.
728 RaiseEvent(POLLERR);
729 switch (sig) {
730 case SIGWINCH:
731 if (sigwinch_handler_ != SIG_IGN)
732 sigwinch_handler_(SIGWINCH);
733 break;
734
735 case SIGUSR1:
736 case SIGUSR2:
737 break;
738
739 default:
740 errno = EINVAL;
741 return -1;
742 }
743
744 return 0;
745 }
746
747 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) {
748 switch (signum) {
749 // Handled signals.
750 case SIGWINCH: {
751 sighandler_t old_value = sigwinch_handler_;
752 if (handler == SIG_DFL)
753 handler = SIG_IGN;
754 sigwinch_handler_ = handler;
755 return old_value;
756 }
757
758 // Known signals
759 case SIGHUP:
760 case SIGINT:
761 case SIGKILL:
762 case SIGPIPE:
763 case SIGPOLL:
764 case SIGPROF:
765 case SIGTERM:
766 case SIGCHLD:
767 case SIGURG:
768 case SIGFPE:
769 case SIGILL:
770 case SIGQUIT:
771 case SIGSEGV:
772 case SIGTRAP:
773 if (handler == SIG_DFL)
774 return SIG_DFL;
775 break;
776 }
777
778 errno = EINVAL;
779 return SIG_ERR;
780 }
781
713 #ifdef PROVIDES_SOCKET_API 782 #ifdef PROVIDES_SOCKET_API
714 783
715 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, 784 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds,
716 fd_set* exceptfds, struct timeval* timeout) { 785 fd_set* exceptfds, struct timeval* timeout) {
717 ScopedEventListener listener(new EventListener); 786 ScopedEventListener listener(new EventListener);
787
718 std::vector<struct pollfd> fds; 788 std::vector<struct pollfd> fds;
719 789
720 fd_set readout, writeout, exceptout; 790 fd_set readout, writeout, exceptout;
721 791
722 FD_ZERO(&readout); 792 FD_ZERO(&readout);
723 FD_ZERO(&writeout); 793 FD_ZERO(&writeout);
724 FD_ZERO(&exceptout); 794 FD_ZERO(&exceptout);
725 795
726 int fd; 796 int fd;
727 size_t event_cnt = 0; 797 size_t event_cnt = 0;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 863 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) ||
794 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || 864 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) ||
795 (ms < 0) || (ms >= INT_MAX)) { 865 (ms < 0) || (ms >= INT_MAX)) {
796 errno = EINVAL; 866 errno = EINVAL;
797 return -1; 867 return -1;
798 } 868 }
799 869
800 ms_timeout = static_cast<int>(ms); 870 ms_timeout = static_cast<int>(ms);
801 } 871 }
802 872
873 // Add a special node to listen for events
874 // coming from the KernelProxy itself (kill will
875 // generated a SIGERR event).
876 listener->Track(-1, ScopedKernelProxy(this), POLLERR, -1);
binji 2013/08/22 18:09:36 OK, I see why you want to use the kernel proxy for
Sam Clegg 2013/08/22 19:52:25 Done.
877 event_track += 1;
878
803 events.resize(event_track); 879 events.resize(event_track);
880
881 bool interrupted = false;
804 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt); 882 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt);
805 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) { 883 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) {
884 if (events[fd].user_data == static_cast<uint64_t>(-1)) {
885 if (events[fd].events & POLLERR) {
886 interrupted = true;
887 }
888 continue;
889 }
890
806 if (events[fd].events & POLLIN) { 891 if (events[fd].events & POLLIN) {
807 FD_SET(events[fd].user_data, &readout); 892 FD_SET(events[fd].user_data, &readout);
808 event_cnt++; 893 event_cnt++;
809 } 894 }
810 895
811 if (events[fd].events & POLLOUT) { 896 if (events[fd].events & POLLOUT) {
812 FD_SET(events[fd].user_data, &writeout); 897 FD_SET(events[fd].user_data, &writeout);
813 event_cnt++; 898 event_cnt++;
814 } 899 }
815 900
816 if (events[fd].events & (POLLERR | POLLHUP)) { 901 if (events[fd].events & (POLLERR | POLLHUP)) {
817 FD_SET(events[fd].user_data, &exceptout); 902 FD_SET(events[fd].user_data, &exceptout);
818 event_cnt++; 903 event_cnt++;
819 } 904 }
820 } 905 }
906
907 if (0 == event_cnt && interrupted) {
908 errno = EINTR;
909 return -1;
910 }
821 } 911 }
822 912
823 // Copy out the results 913 // Copy out the results
824 if (readfds != NULL) 914 if (readfds != NULL)
825 *readfds = readout; 915 *readfds = readout;
826 916
827 if (writefds != NULL) 917 if (writefds != NULL)
828 *writefds = writeout; 918 *writefds = writeout;
829 919
830 if (exceptfds != NULL) 920 if (exceptfds != NULL)
831 *exceptfds = exceptout; 921 *exceptfds = exceptout;
832 922
833 return event_cnt; 923 return event_cnt;
834 } 924 }
835 925
836 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { 926 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) {
837 ScopedEventListener listener(new EventListener); 927 ScopedEventListener listener(new EventListener);
928 listener->Track(-1, ScopedKernelProxy(this), POLLERR, 0);
838 929
839 int index; 930 int index;
840 size_t event_cnt = 0; 931 size_t event_cnt = 0;
841 size_t event_track = 0; 932 size_t event_track = 1;
842 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { 933 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) {
843 ScopedKernelHandle handle; 934 ScopedKernelHandle handle;
844 struct pollfd* info = &fds[index]; 935 struct pollfd* info = &fds[index];
845 Error err = AcquireHandle(info->fd, &handle); 936 Error err = AcquireHandle(info->fd, &handle);
846 937
847 // If the node isn't open, or somehow invalid, mark it so. 938 // If the node isn't open, or somehow invalid, mark it so.
848 if (err != 0) { 939 if (err != 0) {
849 info->revents = POLLNVAL; 940 info->revents = POLLNVAL;
850 event_cnt++; 941 event_cnt++;
851 continue; 942 continue;
(...skipping 14 matching lines...) Expand all
866 continue; 957 continue;
867 } 958 }
868 event_track++; 959 event_track++;
869 } 960 }
870 961
871 // If nothing is signaled, then we must wait. 962 // If nothing is signaled, then we must wait.
872 if (0 == event_cnt) { 963 if (0 == event_cnt) {
873 std::vector<EventData> events; 964 std::vector<EventData> events;
874 int ready_cnt; 965 int ready_cnt;
875 966
967 bool interrupted = false;
876 events.resize(event_track); 968 events.resize(event_track);
877 listener->Wait(events.data(), event_track, timeout, &ready_cnt); 969 listener->Wait(events.data(), event_track, timeout, &ready_cnt);
878 for (index = 0; index < ready_cnt; index++) { 970 for (index = 0; index < ready_cnt; index++) {
879 struct pollfd* info = &fds[events[index].user_data]; 971 struct pollfd* info = &fds[events[index].user_data];
972 if (!info) {
973 interrupted = true;
974 continue;
975 }
880 976
881 info->revents = events[index].events; 977 info->revents = events[index].events;
882 event_cnt++; 978 event_cnt++;
883 } 979 }
980 if (0 == event_cnt && interrupted) {
981 errno = EINTR;
982 return -1;
983 }
884 } 984 }
885 985
886 return event_cnt; 986 return event_cnt;
887 } 987 }
888 988
889 989
890 990
891 // Socket Functions 991 // Socket Functions
892 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 992 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
893 if (NULL == addr || NULL == len) { 993 if (NULL == addr || NULL == len) {
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 errno = ENOTSOCK; 1346 errno = ENOTSOCK;
1247 return -1; 1347 return -1;
1248 } 1348 }
1249 1349
1250 return 0; 1350 return 0;
1251 } 1351 }
1252 1352
1253 #endif // PROVIDES_SOCKET_API 1353 #endif // PROVIDES_SOCKET_API
1254 1354
1255 } // namespace_nacl_io 1355 } // namespace_nacl_io
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698