static DWORD AsyncPipeOp (async_op_t op, HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events) { int i; BOOL success; HANDLE io_event; DWORD res, bytes = 0; OVERLAPPED overlapped; LPHANDLE handles = NULL; io_event = InitOverlapped (&overlapped); if (!io_event) goto out; handles = malloc ((count + 1) * sizeof (HANDLE)); if (!handles) goto out; if (op == write) success = WriteFile (pipe, buffer, size, NULL, &overlapped); else success = ReadFile (pipe, buffer, size, NULL, &overlapped); if (!success && GetLastError () != ERROR_IO_PENDING && GetLastError () != ERROR_MORE_DATA) goto out; handles[0] = io_event; for (i = 0; i < count; i++) handles[i + 1] = events[i]; res = WaitForMultipleObjects (count + 1, handles, FALSE, op == peek ? INFINITE : IO_TIMEOUT); if (res != WAIT_OBJECT_0) { CancelIo (pipe); goto out; } if (op == peek) PeekNamedPipe (pipe, NULL, 0, NULL, &bytes, NULL); else GetOverlappedResult (pipe, &overlapped, &bytes, TRUE); out: CloseHandleEx (&io_event); free (handles); return bytes; }
// // Begin accepting a connection to an existing port. Used by server. // For synchronous port, blocks until a connection is made (returns TRUE) // or an error occurs (returns FALSE). For asynchronous port, returns // immediately. Returns TRUE for success or FALSE if any error occurs. // Call IsAcceptComplete() to determine if it has completed, // and GetAcceptResult() to get result. // BOOL PortPipe::Accept() { if ( synchronous ) { #if PORT_DETAILS || _DETAILS cout << "Waiting to accept connection to " << name << "." << endl; #endif return ( ConnectNamedPipe( p, NULL ) ); } else { #if PORT_DETAILS || _DETAILS cout << "Starting to accept connection to " << name << "." << endl; #endif if ( !InitOverlapped( &accept_overlapped ) ) { return FALSE; } if ( ConnectNamedPipe( p, &accept_overlapped ) ) { #if PORT_DETAILS || _DETAILS cout << "Connection accepted." << endl; #endif return TRUE; } else { if ( GetLastError() == ERROR_IO_PENDING ) // Read started OK... { return TRUE; } else { *errmsg << "*** ConnectNamedPipe() failed in PortPipe::Accept()." << ends; OutputErrMsg(); return FALSE; } } } }
// // Call which sends data to a connected port. Blocking call for synchronous // port; non-blocking call for asynchronous port. Note that a process will // not send data to itself. // DWORDLONG PortPipe::Send( LPVOID msg, DWORD size ) { DWORD bytes_written; OVERLAPPED *olap; if ( synchronous ) { olap = NULL; } else { if ( !InitOverlapped( &send_overlapped ) ) { return PORT_ERROR; } olap = &send_overlapped; } if ( WriteFile( p, msg, size, &bytes_written, olap ) ) { #if PORT_DETAILS || _DETAILS cout << "Sent " << bytes_written << " of " << size << " bytes to port " << name << "." << endl; #endif return (DWORDLONG) bytes_written; } else { // Did asynchronous write started OK? if ( !synchronous && (GetLastError() == ERROR_IO_PENDING) ) { return 0; // not an error code, but no bytes read yet } *errmsg << "*** Error " << GetLastError() << " sending " << size << " bytes to port " << name << " in PortPipe::Send()." << ends; OutputErrMsg(); return PORT_ERROR; } }
// // Call which receives data from a connected port. Blocking call for // synchronous port; non-blocking call for asynchronous port. // Note that a receive call will not receive data from itself. // DWORDLONG PortPipe::Receive( LPVOID msg, DWORD size ) { DWORD bytes_read; OVERLAPPED *olap; if ( synchronous ) { olap = NULL; } else { if ( !InitOverlapped( &receive_overlapped ) ) { return PORT_ERROR; } olap = &receive_overlapped; } if ( ReadFile( p, msg, size, &bytes_read, olap ) ) { #if PORT_DETAILS || _DETAILS cout << "Received " << bytes_read << " of " << size << " bytes from port " << name << "." << endl; #endif return (DWORDLONG) bytes_read; } else { if ( !synchronous && (GetLastError() == ERROR_IO_PENDING) ) // Asynchronous read started OK... { return 0; // not an error code, but no bytes read yet } *errmsg << "*** Error receiving " << size << " bytes from port " << name << " in PortPipe::Receive()." << ends; OutputErrMsg(); return PORT_ERROR; } }
// // Begin accepting a connection to an existing port. Used by server. // For synchronous port, blocks until a connection is made (returns TRUE) or an error occurs (returns FALSE). // For asynchronous port, returns immediately. Returns TRUE for success or FALSE if any error occurs. // Call IsAcceptComplete() to determine if it has completed, and GetAcceptResult() to get result. // BOOL PortTCP::Accept() { // // Listen to socket. // #if PORT_DETAILS || _DETAILS cout << "Listening to socket " << name << "." << endl; WSASetLastError(0); #endif if (listen(server_socket, 0) != 0) // allow at most one connection at a time { *errmsg << "===> ERROR: Listening to socket " << name << " failed." << endl << " [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl << " errno = " << WSAGetLastError() << ends; OutputErrMsg(); return FALSE; } // // Accept connections to socket. // #if PORT_DETAILS || _DETAILS cout << "Accepting connections to socket " << name << "." << endl; WSASetLastError(0); #endif if (synchronous) { // don't need any info about who we're talking to client_socket = accept(server_socket, NULL, NULL); if (client_socket == (int)INVALID_SOCKET) { *errmsg << "===> ERROR: Accepting connection to socket " << name << " failed." << endl << " [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl << " errno = " << WSAGetLastError() << ends; OutputErrMsg(); return FALSE; } else { return TRUE; } } #if defined(IOMTR_OS_WIN32) || defined(IOMTR_OS_WIN64) else { DWORD bytes_received; if (!InitOverlapped(&accept_overlapped)) { *errmsg << "===> ERROR: Creating OVERLAPPED structure for socket " << name << " failed." << endl << " [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << ends; OutputErrMsg(); return FALSE; } // // Create client socket. // #if PORT_DETAILS || _DETAILS cout << "Creating client socket for " << name << "." << endl; WSASetLastError(0); #endif client_socket = WSASocket(AF_INET, SOCK_STREAM, PF_UNSPEC, NULL, 0, WSA_FLAG_OVERLAPPED); if (client_socket == INVALID_SOCKET) { *errmsg << "===> ERROR: Creating client socket for " << name << " failed." << endl << " [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl << " errno = " << WSAGetLastError() << ends; OutputErrMsg(); return FALSE; } // // Accept connections to socket. // if (AcceptEx(server_socket, client_socket, accept_ex_buffer, 0, // read no data, only the two addresses, into accept_ex_buffer sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16, &bytes_received, &accept_overlapped)) { #if PORT_DETAILS || _DETAILS cout << "Connection accepted." << endl; #endif return TRUE; } else { if (WSAGetLastError() == WSA_IO_PENDING) // Read started OK... { return TRUE; } else { *errmsg << "===> ERROR: AcceptEx() failed." << endl << " [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << ends; OutputErrMsg(); return FALSE; } } } #elif defined(IOMTR_OS_LINUX) || defined(IOMTR_OS_NETWARE) || defined(IOMTR_OS_OSX) || defined(IOMTR_OS_SOLARIS) else {