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

Side by Side Diff: native_client_sdk/src/examples/demo/googledrivefs_demo/handlers.cc

Issue 2156503002: [NaCl SDK] Expose Google Drive to nacl_io. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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
OLDNEW
1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 /* Copyright (c) 2016 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 "handlers.h" 5 #include "handlers.h"
6 6
7 #include <arpa/inet.h> 7 #include <arpa/inet.h>
8 #include <assert.h> 8 #include <assert.h>
9 #include <errno.h> 9 #include <errno.h>
10 #include <limits.h> 10 #include <limits.h>
11 #include <netdb.h> 11 #include <netdb.h>
12 #include <netinet/in.h> 12 #include <netinet/in.h>
13 #include <stdio.h> 13 #include <stdio.h>
14 #include <stdlib.h> 14 #include <stdlib.h>
15 #include <string.h> 15 #include <string.h>
16 #include <unistd.h> 16 #include <unistd.h>
17 17
18 #include <sys/types.h> 18 #include <sys/types.h>
19 #include <sys/socket.h> 19 #include <sys/socket.h>
20 #include <sys/stat.h> 20 #include <sys/stat.h>
21 21
22 #include "nacl_io/osdirent.h" 22 #include "nacl_io/osdirent.h"
23 #include "nacl_io/osinttypes.h" 23 #include "nacl_io/osinttypes.h"
24 24
25 #include "nacl_io_demo.h" 25 #include "googledrivefs_demo.h"
26 26
27 #define MAX_OPEN_FILES 10 27 #define MAX_OPEN_FILES 10
28 #define MAX_OPEN_DIRS 10 28 #define MAX_OPEN_DIRS 10
29 #define MAX_PARAMS 4 29 #define MAX_PARAMS 4
30 30
31 #if defined(WIN32) 31 #if defined(WIN32)
32 #define stat _stat 32 #define stat _stat
33 #endif 33 #endif
34 34
35 /** 35 /**
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 memcpy(string, var_str, length); 164 memcpy(string, var_str, length);
165 string[length] = 0; 165 string[length] = 0;
166 166
167 /* Put the allocated string in g_ParamStrings. This keeps us from leaking 167 /* Put the allocated string in g_ParamStrings. This keeps us from leaking
168 * each parameter string, without having to do manual cleanup in every 168 * each parameter string, without having to do manual cleanup in every
169 * Handle* function below. 169 * Handle* function below.
170 */ 170 */
171 free(g_ParamStrings[index]); 171 free(g_ParamStrings[index]);
172 g_ParamStrings[index] = string; 172 g_ParamStrings[index] = string;
173 173
174
175 *out_string = string; 174 *out_string = string;
176 *out_string_len = length; 175 *out_string_len = length;
177 return 0; 176 return 0;
178 } 177 }
179 178
180 /** 179 /**
181 * Get a parameter at |index| as a FILE*. 180 * Get a parameter at |index| as a FILE*.
182 * @param[in] params The parameter array. 181 * @param[in] params The parameter array.
183 * @param[in] index The index in |params| to get. 182 * @param[in] index The index in |params| to get.
184 * @param[out] out_file The output FILE*. 183 * @param[out] out_file The output FILE*.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 if (dir_index < 0 || dir_index >= MAX_OPEN_DIRS) { 238 if (dir_index < 0 || dir_index >= MAX_OPEN_DIRS) {
240 *out_error = PrintfToNewString("Dir at index %d is out range", dir_index); 239 *out_error = PrintfToNewString("Dir at index %d is out range", dir_index);
241 return 1; 240 return 1;
242 } 241 }
243 242
244 if (g_OpenDirs[dir_index] == NULL) { 243 if (g_OpenDirs[dir_index] == NULL) {
245 *out_error = PrintfToNewString("Dir index %d is not open", dir_index); 244 *out_error = PrintfToNewString("Dir index %d is not open", dir_index);
246 return 1; 245 return 1;
247 } 246 }
248 247
249 *out_dir = g_OpenDirs[dir_index]; 248 *out_dir = (DIR *) g_OpenDirs[dir_index];
250 *out_dir_index = dir_index; 249 *out_dir_index = dir_index;
251 return 0; 250 return 0;
252 } 251 }
253 252
254 /** 253 /**
255 * Get a parameter at |index| as an int. 254 * Get a parameter at |index| as an int.
256 * @param[in] params The parameter array. 255 * @param[in] params The parameter array.
257 * @param[in] index The index in |params| to get. 256 * @param[in] index The index in |params| to get.
258 * @param[out] out_file The output int32_t. 257 * @param[out] out_file The output int32_t.
259 * @param[out] out_error An error message, if this operation failed. 258 * @param[out] out_error An error message, if this operation failed.
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 if (result == NULL) { 853 if (result == NULL) {
855 *out_error = PrintfToNewString("getcwd returned error: %d", errno); 854 *out_error = PrintfToNewString("getcwd returned error: %d", errno);
856 return 1; 855 return 1;
857 } 856 }
858 857
859 CREATE_RESPONSE(getcwd); 858 CREATE_RESPONSE(getcwd);
860 RESPONSE_STRING(cwd); 859 RESPONSE_STRING(cwd);
861 return 0; 860 return 0;
862 } 861 }
863 862
864 /**
865 * Handle a call to getaddrinfo() made by JavaScript.
866 *
867 * getaddrinfo expects 1 parameter:
868 * 0: The name of the host to look up.
869 * on success, getaddrinfo returns a result in |output|:
870 * 0: "getaddrinfo"
871 * 1: The canonical name
872 * 2*n+2: Host name
873 * 2*n+3: Address type (either "AF_INET" or "AF_INET6")
874 * on failure, getaddrinfo returns an error string in |out_error|.
875 */
876 int HandleGetaddrinfo(struct PP_Var params,
877 struct PP_Var* output,
878 const char** out_error) {
879 CHECK_PARAM_COUNT(getaddrinfo, 2);
880 PARAM_STRING(0, name);
881 PARAM_STRING(1, family);
882
883 struct addrinfo hints;
884 memset(&hints, 0, sizeof(hints));
885 hints.ai_flags = AI_CANONNAME;
886 if (!strcmp(family, "AF_INET"))
887 hints.ai_family = AF_INET;
888 else if (!strcmp(family, "AF_INET6"))
889 hints.ai_family = AF_INET6;
890 else if (!strcmp(family, "AF_UNSPEC"))
891 hints.ai_family = AF_UNSPEC;
892 else {
893 *out_error = PrintfToNewString("getaddrinfo uknown family: %s", family);
894 return 1;
895 }
896
897 struct addrinfo* ai;
898 int rtn = getaddrinfo(name, NULL, &hints, &ai);
899 if (rtn != 0) {
900 *out_error = PrintfToNewString("getaddrinfo failed, error is \"%s\"",
901 gai_strerror(rtn));
902 return 2;
903 }
904
905 CREATE_RESPONSE(getaddrinfo);
906 RESPONSE_STRING(ai->ai_canonname);
907 struct addrinfo* current = ai;
908 while (current) {
909 char addr_str[INET6_ADDRSTRLEN];
910 if (ai->ai_family == AF_INET6) {
911 struct sockaddr_in6* in6 = (struct sockaddr_in6*)current->ai_addr;
912 inet_ntop(
913 ai->ai_family, &in6->sin6_addr.s6_addr, addr_str, sizeof(addr_str));
914 } else if (ai->ai_family == AF_INET) {
915 struct sockaddr_in* in = (struct sockaddr_in*)current->ai_addr;
916 inet_ntop(ai->ai_family, &in->sin_addr, addr_str, sizeof(addr_str));
917 }
918
919 RESPONSE_STRING(addr_str);
920 RESPONSE_STRING(ai->ai_family == AF_INET ? "AF_INET" : "AF_INET6");
921
922 current = current->ai_next;
923 }
924
925 freeaddrinfo(ai);
926 return 0;
927 }
928
929 /**
930 * Handle a call to gethostbyname() made by JavaScript.
931 *
932 * gethostbyname expects 1 parameter:
933 * 0: The name of the host to look up.
934 * on success, gethostbyname returns a result in |output|:
935 * 0: "gethostbyname"
936 * 1: Host name
937 * 2: Address type (either "AF_INET" or "AF_INET6")
938 * 3: The first address.
939 * 4+ The second, third, etc. addresses.
940 * on failure, gethostbyname returns an error string in |out_error|.
941 */
942 int HandleGethostbyname(struct PP_Var params,
943 struct PP_Var* output,
944 const char** out_error) {
945 CHECK_PARAM_COUNT(gethostbyname, 1);
946 PARAM_STRING(0, name);
947
948 struct hostent* info = gethostbyname(name);
949 if (!info) {
950 *out_error = PrintfToNewString("gethostbyname failed, error is \"%s\"",
951 hstrerror(h_errno));
952 return 1;
953 }
954
955 CREATE_RESPONSE(gethostbyname);
956 RESPONSE_STRING(info->h_name);
957 RESPONSE_STRING(info->h_addrtype == AF_INET ? "AF_INET" : "AF_INET6");
958
959 struct in_addr** addr_list = (struct in_addr**)info->h_addr_list;
960 int i;
961 for (i = 0; addr_list[i] != NULL; i++) {
962 if (info->h_addrtype == AF_INET) {
963 RESPONSE_STRING(inet_ntoa(*addr_list[i]));
964 } else { // IPv6
965 char addr_str[INET6_ADDRSTRLEN];
966 inet_ntop(AF_INET6, addr_list[i], addr_str, sizeof(addr_str));
967 RESPONSE_STRING(addr_str);
968 }
969 }
970 return 0;
971 }
972
973 /**
974 * Handle a call to connect() made by JavaScript.
975 *
976 * connect expects 2 parameters:
977 * 0: The hostname to connect to.
978 * 1: The port number to connect to.
979 * on success, connect returns a result in |output|:
980 * 0: "connect"
981 * 1: The socket file descriptor.
982 * on failure, connect returns an error string in |out_error|.
983 */
984 int HandleConnect(struct PP_Var params,
985 struct PP_Var* output,
986 const char** out_error) {
987 CHECK_PARAM_COUNT(connect, 2);
988 PARAM_STRING(0, hostname);
989 PARAM_INT(1, port);
990
991 // Lookup host
992 struct hostent* hostent = gethostbyname(hostname);
993 if (hostent == NULL) {
994 *out_error = PrintfToNewString("gethostbyname() returned error: %d", errno);
995 return 1;
996 }
997
998 struct sockaddr_in addr;
999 socklen_t addrlen = sizeof(addr);
1000 addr.sin_family = AF_INET;
1001 addr.sin_port = htons(port);
1002 memcpy(&addr.sin_addr.s_addr, hostent->h_addr_list[0], hostent->h_length);
1003
1004 int sock = socket(AF_INET, SOCK_STREAM, 0);
1005 if (sock < 0) {
1006 *out_error = PrintfToNewString("socket() failed: %s", strerror(errno));
1007 return 1;
1008 }
1009
1010 int result = connect(sock, (struct sockaddr*)&addr, addrlen);
1011 if (result != 0) {
1012 *out_error = PrintfToNewString("connect() failed: %s", strerror(errno));
1013 close(sock);
1014 return 1;
1015 }
1016
1017 CREATE_RESPONSE(connect);
1018 RESPONSE_INT(sock);
1019 return 0;
1020 }
1021
1022 /**
1023 * Handle a call to send() made by JavaScript.
1024 *
1025 * send expects 2 parameters:
1026 * 0: The socket file descriptor to send using.
1027 * 1: The NULL terminated string to send.
1028 * on success, send returns a result in |output|:
1029 * 0: "send"
1030 * 1: The number of bytes sent.
1031 * on failure, send returns an error string in |out_error|.
1032 */
1033 int HandleSend(struct PP_Var params,
1034 struct PP_Var* output,
1035 const char** out_error) {
1036 CHECK_PARAM_COUNT(send, 2);
1037 PARAM_INT(0, sock);
1038 PARAM_STRING(1, buffer);
1039
1040 int result = send(sock, buffer, strlen(buffer), 0);
1041 if (result <= 0) {
1042 *out_error = PrintfToNewString("send failed: %s", strerror(errno));
1043 return 1;
1044 }
1045
1046 CREATE_RESPONSE(send);
1047 RESPONSE_INT(result);
1048 return 0;
1049 }
1050
1051 /**
1052 * Handle a call to recv() made by JavaScript.
1053 *
1054 * recv expects 2 parameters:
1055 * 0: The socket file descriptor to recv from.
1056 * 1: The size of the buffer to pass to recv.
1057 * on success, send returns a result in |output|:
1058 * 0: "recv"
1059 * 1: The number of bytes received.
1060 * 2: The data received.
1061 * on failure, recv returns an error string in |out_error|.
1062 */
1063 int HandleRecv(struct PP_Var params,
1064 struct PP_Var* output,
1065 const char** out_error) {
1066 CHECK_PARAM_COUNT(recv, 2);
1067 PARAM_INT(0, sock);
1068 PARAM_INT(1, buffersize);
1069
1070 if (buffersize < 0 || buffersize > 65 * 1024) {
1071 *out_error =
1072 PrintfToNewString("recv buffersize must be between 0 and 65k.");
1073 return 1;
1074 }
1075
1076 char* buffer = alloca(buffersize);
1077 memset(buffer, 0, buffersize);
1078 int result = recv(sock, buffer, buffersize, 0);
1079 if (result <= 0) {
1080 *out_error = PrintfToNewString("recv failed: %s", strerror(errno));
1081 return 1;
1082 }
1083
1084 CREATE_RESPONSE(recv);
1085 RESPONSE_INT(result);
1086 RESPONSE_STRING(buffer);
1087 return 0;
1088 }
1089
1090 /**
1091 * Handle a call to close() made by JavaScript.
1092 *
1093 * close expects 1 parameters:
1094 * 0: The socket file descriptor to close.
1095 * on success, close returns a result in |output|:
1096 * 0: "close"
1097 * 1: The socket file descriptor closed.
1098 * on failure, close returns an error string in |out_error|.
1099 */
1100 int HandleClose(struct PP_Var params,
1101 struct PP_Var* output,
1102 const char** out_error) {
1103 CHECK_PARAM_COUNT(close, 1);
1104 PARAM_INT(0, sock);
1105
1106 int result = close(sock);
1107 if (result != 0) {
1108 *out_error = PrintfToNewString("close returned error: %d", errno);
1109 return 1;
1110 }
1111
1112 CREATE_RESPONSE(close);
1113 RESPONSE_INT(sock);
1114 return 0;
1115 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698