diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-12-06 17:58:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-12-06 17:58:40 +0000 |
commit | d234059375e77fe46c57e98751dc8491dff46e85 (patch) | |
tree | f2c73e373b9e7a01af71b2fa1ba0d5feb41881cf /src/util/service.c | |
parent | afa1f268d5275e134566924a84e05ce631396cdb (diff) | |
download | gnunet-d234059375e77fe46c57e98751dc8491dff46e85.tar.gz gnunet-d234059375e77fe46c57e98751dc8491dff46e85.zip |
Implement passing sockets in IPC on W32 (#1975)
Diffstat (limited to 'src/util/service.c')
-rw-r--r-- | src/util/service.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/util/service.c b/src/util/service.c index 91fc460e2..d37fe87c2 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -1079,6 +1079,89 @@ GNUNET_SERVICE_get_server_addresses (const char *serviceName, | |||
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | 1081 | ||
1082 | #ifdef MINGW | ||
1083 | /** | ||
1084 | * @return GNUNET_YES if ok, GNUNET_NO if not ok (must bind yourself), | ||
1085 | * and GNUNET_SYSERR on error. | ||
1086 | */ | ||
1087 | static int | ||
1088 | receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) | ||
1089 | { | ||
1090 | const char *env_buf; | ||
1091 | int fail; | ||
1092 | uint64_t count, i; | ||
1093 | HANDLE lsocks_pipe; | ||
1094 | |||
1095 | env_buf = getenv ("GNUNET_OS_READ_LSOCKS"); | ||
1096 | if ((env_buf == NULL) || (strlen (env_buf) <= 0)) | ||
1097 | { | ||
1098 | return GNUNET_NO; | ||
1099 | } | ||
1100 | /* Using W32 API directly here, because this pipe will | ||
1101 | * never be used outside of this function, and it's just too much of a bother | ||
1102 | * to create a GNUnet API that boxes a HANDLE (the way it is done with socks) | ||
1103 | */ | ||
1104 | lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10); | ||
1105 | if (lsocks_pipe == 0 || lsocks_pipe == INVALID_HANDLE_VALUE) | ||
1106 | return GNUNET_NO; | ||
1107 | |||
1108 | fail = 1; | ||
1109 | do | ||
1110 | { | ||
1111 | int ret; | ||
1112 | int fail2; | ||
1113 | DWORD rd; | ||
1114 | |||
1115 | ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL); | ||
1116 | if (ret == 0 || rd != sizeof (count) || count == 0) | ||
1117 | break; | ||
1118 | sctx->lsocks = | ||
1119 | GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1)); | ||
1120 | |||
1121 | fail2 = 1; | ||
1122 | for (i = 0; i < count; i++) | ||
1123 | { | ||
1124 | WSAPROTOCOL_INFOA pi; | ||
1125 | uint64_t size; | ||
1126 | SOCKET s; | ||
1127 | ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL); | ||
1128 | if (ret == 0 || rd != sizeof (size) || size != sizeof (pi)) | ||
1129 | break; | ||
1130 | ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL); | ||
1131 | if (ret == 0 || rd != sizeof (pi)) | ||
1132 | break; | ||
1133 | s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED); | ||
1134 | sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s); | ||
1135 | if (sctx->lsocks[i] == NULL) | ||
1136 | break; | ||
1137 | else if (i == count - 1) | ||
1138 | fail2 = 0; | ||
1139 | } | ||
1140 | if (fail2) | ||
1141 | break; | ||
1142 | sctx->lsocks[count] = NULL; | ||
1143 | fail = 0; | ||
1144 | } | ||
1145 | while (fail); | ||
1146 | |||
1147 | CloseHandle (lsocks_pipe); | ||
1148 | |||
1149 | if (fail) | ||
1150 | { | ||
1151 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1152 | _("Could not access a pre-bound socket, will try to bind myself\n")); | ||
1153 | for (i = 0; sctx->lsocks[i] != NULL && i < count; i++) | ||
1154 | GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i])); | ||
1155 | GNUNET_free (sctx->lsocks); | ||
1156 | sctx->lsocks = NULL; | ||
1157 | return GNUNET_NO; | ||
1158 | } | ||
1159 | |||
1160 | return GNUNET_YES; | ||
1161 | } | ||
1162 | #endif | ||
1163 | |||
1164 | |||
1082 | /** | 1165 | /** |
1083 | * Setup addr, addrlen, idle_timeout | 1166 | * Setup addr, addrlen, idle_timeout |
1084 | * based on configuration! | 1167 | * based on configuration! |
@@ -1175,6 +1258,12 @@ setup_service (struct GNUNET_SERVICE_Context *sctx) | |||
1175 | unsetenv ("LISTEN_PID"); | 1258 | unsetenv ("LISTEN_PID"); |
1176 | unsetenv ("LISTEN_FDS"); | 1259 | unsetenv ("LISTEN_FDS"); |
1177 | } | 1260 | } |
1261 | #else | ||
1262 | if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL) | ||
1263 | { | ||
1264 | receive_sockets_from_parent (sctx); | ||
1265 | putenv ("GNUNET_OS_READ_LSOCKS="); | ||
1266 | } | ||
1178 | #endif | 1267 | #endif |
1179 | 1268 | ||
1180 | if ((sctx->lsocks == NULL) && | 1269 | if ((sctx->lsocks == NULL) && |