You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/10/13 15:47:31 UTC
svn commit: r824758 -
/commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c
Author: mturk
Date: Tue Oct 13 13:47:31 2009
New Revision: 824758
URL: http://svn.apache.org/viewvc?rev=824758&view=rev
Log:
Port APR's socket pipe
Modified:
commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c?rev=824758&r1=824757&r2=824758&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c Tue Oct 13 13:47:31 2009
@@ -28,3 +28,136 @@
* Windows pipe functions
*
*/
+
+static volatile LONG pipe_id = 0;
+static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr)
+{
+ static int id = 0;
+ FD_SET rs;
+ SOCKET ls;
+ struct timeval socktm;
+ struct sockaddr_in pa;
+ struct sockaddr_in la;
+ struct sockaddr_in ca;
+ int nrd;
+ int rv = 0;
+ int ll = (int)sizeof(la);
+ int cl = (int)sizeof(ca);
+ int bm = 1;
+ int uid[2];
+ int iid[2];
+
+ *rd = INVALID_SOCKET;
+ *wr = INVALID_SOCKET;
+
+ /* Create the unique socket identifier
+ * so that we know the connection originated
+ * from us.
+ */
+ uid[0] = GetCurrentProcessId();
+ uid[1] = (int)InterlockedIncrement(&pipe_id);
+ if ((ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+ return ACR_GET_NETOS_ERROR();
+ }
+
+ pa.sin_family = AF_INET;
+ pa.sin_port = 0;
+ pa.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ if (bind(ls, (SOCKADDR *)&pa, sizeof(pa)) == SOCKET_ERROR) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ if (getsockname(ls, (SOCKADDR *)&la, &ll) == SOCKET_ERROR) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ if (listen(ls, 1) == SOCKET_ERROR) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ if ((*wr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ if (connect(*wr, (SOCKADDR *)&la, sizeof(la)) == SOCKET_ERROR) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ if (send(*wr, (char *)uid, sizeof(uid), 0) != sizeof(uid)) {
+ if ((rv = ACR_GET_NETOS_ERROR()) == 0) {
+ rv = ACR_EINCOMPLETE;
+ }
+ goto cleanup;
+ }
+ if (ioctlsocket(ls, FIONBIO, &bm) == SOCKET_ERROR) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ for (;;) {
+ int ns;
+ /* Listening socket is nonblocking by now.
+ * The accept should create the socket
+ * immediatelly because we are connected already.
+ * However on buys systems this can take a while
+ * until winsock gets a chance to handle the events.
+ */
+ FD_ZERO(&rs);
+ FD_SET(ls, &rs);
+
+ socktm.tv_sec = 1;
+ socktm.tv_usec = 0;
+ if ((ns = select(0, &rs, NULL, NULL, &socktm)) == SOCKET_ERROR) {
+ /* Accept still not signaled */
+ Sleep(100);
+ continue;
+ }
+ if (ns == 0) {
+ /* No connections in the last second */
+ continue;
+ }
+ if ((*rd = accept(ls, (SOCKADDR *)&ca, &cl)) == INVALID_SOCKET) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ /* Verify the connection by reading the send identification.
+ */
+ nrd = recv(*rd, (char *)iid, sizeof(iid), 0);
+ if (nrd == sizeof(iid)) {
+ if (memcmp(uid, iid, sizeof(uid)) == 0) {
+ /* Wow, we recived what we send.
+ * Put read side of the pipe to the blocking
+ * mode and return.
+ */
+ bm = 0;
+ if (ioctlsocket(*rd, FIONBIO, &bm) == SOCKET_ERROR) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ break;
+ }
+ }
+ else if (nrd == SOCKET_ERROR) {
+ rv = ACR_GET_NETOS_ERROR();
+ goto cleanup;
+ }
+ closesocket(*rd);
+ }
+ /* We don't need the listening socket any more
+ */
+ closesocket(ls);
+ return 0;
+
+cleanup:
+ /* Don't leak resources on failure
+ */
+ if (*rd != INVALID_SOCKET)
+ closesocket(*rd);
+ if (*wr != INVALID_SOCKET)
+ closesocket(*wr);
+
+ *rd = INVALID_SOCKET;
+ *wr = INVALID_SOCKET;
+ closesocket(ls);
+ return rv;
+}