/* 'open' operation of pipe stream. For each pipe stream, it is identified by a decimal number in URI. There could be two types: pipe and pipe.srv. They behave pretty much the same, except they are two ends of the pipe. */ static int pipe_open (PAL_HANDLE *handle, const char * type, const char * uri, int access, int share, int create, int options) { if (!memcmp(type, "pipe:", 5) && !*uri) return pipe_private(handle); char * endptr; PAL_NUM pipeid = strtol(uri, &endptr, 10); PAL_IDX connid = 0; if (*endptr == ':') { if (create & PAL_CREAT_TRY) return -PAL_ERROR_INVAL; connid = strtol(endptr + 1, &endptr, 10); } if (*endptr) return -PAL_ERROR_INVAL; if (!memcmp(type, "pipe.srv:", 9)) return pipe_listen(handle, pipeid, create); if (!memcmp(type, "pipe:", 5)) return pipe_connect(handle, pipeid, connid, create); return -PAL_ERROR_INVAL; }
/* * Callback which invokes pipe_listen(). * * When we are in pipe_read_cb(), we may try to call pipe_listen() * (after tearing down an old connection). This can cause an infinite * loop as they execute in the same helper thread, and pipe_listen() * will try to reschedule pipe_read_cb(). * Therefore, use QueueUserWorkItem() to make sure that pipe_listen() * is invoked after a context switch. */ void WINAPI pipe_relisten_cb(void *ctx) { pipe_instance_t *pp; pp = (pipe_instance_t *)ctx; EnterCriticalSection(&pp->rcs); TRACE1(ENTER, "Entering pipe_relisten_cb %p", ctx); pipe_disconnect(pp); pipe_listen(pp); TRACE0(ENTER, "Leaving pipe_relisten_cb"); LeaveCriticalSection(&pp->rcs); }
DWORD CE_Initialize ( PCONFIGURATION_ENTRY pce, HANDLE hMgrNotificationEvent, PSUPPORT_FUNCTIONS psfSupportFunctions, PXORPRTM_GLOBAL_CONFIG pigc) { DWORD dwErr = NO_ERROR; pipe_instance_t *pp; int i, pipefail; do { pce->ulActivityCount = 0; pce->hMprConfig = NULL; dwErr = MprConfigServerConnect(NULL, &pce->hMprConfig); if (dwErr != NO_ERROR) { TRACE0(CONFIGURATION, "could not obtain mpr config handle"); } /* Router Manager Information */ pce->hMgrNotificationEvent = hMgrNotificationEvent; if (psfSupportFunctions) pce->sfSupportFunctions = *psfSupportFunctions; pipefail = 0; for (i = 0; i < PIPE_INSTANCES; i++) { pp = pipe_new(); if (pp == NULL) { pipefail = 1; break; } else { pipe_listen(pp); pce->pipes[i] = pp; } } if (pipefail) { TRACE0(CONFIGURATION, "failed to allocate all pipes"); break; } TRACE0(ANY, "Listening on pipes ok."); pce->reiRtmEntity.RtmInstanceId = 0; #ifdef IPV6_DLL pce->reiRtmEntity.AddressFamily = AF_INET6; #else pce->reiRtmEntity.AddressFamily = AF_INET; #endif pce->reiRtmEntity.EntityId.EntityProtocolId = PROTO_IP_XORPRTM; pce->reiRtmEntity.EntityId.EntityInstanceId = 0; dwErr = RtmRegisterEntity( &pce->reiRtmEntity, NULL, RTM_CallbackEvent, TRUE, &pce->rrpRtmProfile, &pce->hRtmHandle); if (dwErr != NO_ERROR) { TRACE1(CONFIGURATION, "Error %u registering with RTM", dwErr); break; } TRACE0(ANY, "registered entity ok."); dwErr = RtmRegisterForChangeNotification( pce->hRtmHandle, RTM_VIEW_MASK_UCAST, RTM_CHANGE_TYPE_ALL, NULL, &pce->hRtmNotificationHandle); if (dwErr != NO_ERROR) { TRACE1(CONFIGURATION, "Error %u registering for change with RTM", dwErr); break; } TRACE0(ANY, "registered rtm changes ok."); pce->iscStatus = XORPRTM_STATUS_RUNNING; } while (FALSE); if (dwErr != NO_ERROR) { TRACE0(ANY, "init failed, cleaning up."); CE_Cleanup(pce); } else { TRACE0(ANY, "Leaving init ok "); } return dwErr; }