void SAL_CALL osl_releasePipe( oslPipe pPipe ) { if( 0 == pPipe ) return; if( 0 == osl_atomic_decrement( &(pPipe->m_nRefCount) ) ) { if( ! pPipe->m_bClosed ) osl_closePipe( pPipe ); __osl_destroyPipeImpl( pPipe ); } }
void SAL_CALL osl_releasePipe( oslPipe pPipe ) { // OSL_ASSERT( pPipe ); if( 0 == pPipe ) return; if( 0 == osl_decrementInterlockedCount( &(pPipe->m_Reference) ) ) { if( ! pPipe->m_bClosed ) osl_closePipe( pPipe ); __osl_destroyPipeImpl( pPipe ); } }
oslPipe SAL_CALL osl_psz_createPipe(const sal_Char *pszPipeName, oslPipeOptions Options, oslSecurity Security) { int Flags; size_t len; struct sockaddr_un addr; sal_Char name[PATH_MAX + 1]; size_t nNameLength = 0; int bNameTooLong = 0; oslPipe pPipe; if (access(PIPEDEFAULTPATH, R_OK|W_OK) == 0) { strncpy(name, PIPEDEFAULTPATH, sizeof(name)); } else if (access(PIPEALTERNATEPATH, R_OK|W_OK) == 0) { strncpy(name, PIPEALTERNATEPATH, sizeof(name)); } else if (!cpyBootstrapSocketPath (name, sizeof (name))) { return NULL; } name[sizeof(name) - 1] = '\0'; // ensure the string is NULL-terminated nNameLength = strlen(name); bNameTooLong = nNameLength > sizeof(name) - 2; if (!bNameTooLong) { size_t nRealLength = 0; strcat(name, "/"); ++nNameLength; if (Security) { sal_Char Ident[256]; Ident[0] = '\0'; OSL_VERIFY(osl_psz_getUserIdent(Security, Ident, sizeof(Ident))); nRealLength = snprintf(&name[nNameLength], sizeof(name) - nNameLength, SECPIPENAMEMASK, Ident, pszPipeName); } else { nRealLength = snprintf(&name[nNameLength], sizeof(name) - nNameLength, PIPENAMEMASK, pszPipeName); } bNameTooLong = nRealLength > sizeof(name) - nNameLength - 1; } if (bNameTooLong) { OSL_TRACE("osl_createPipe: pipe name too long"); return NULL; } /* alloc memory */ pPipe = __osl_createPipeImpl(); if (pPipe == NULL) { OSL_TRACE("__osl_createPipe socket failed"); return NULL; } /* create socket */ pPipe->m_Socket = socket(AF_UNIX, SOCK_STREAM, 0); if ( pPipe->m_Socket < 0 ) { OSL_TRACE("osl_createPipe socket failed. Errno: %d; %s",errno, strerror(errno)); __osl_destroyPipeImpl(pPipe); return NULL; } /* OSL_TRACE("osl_createPipe : new Pipe on fd %i\n",pPipe->m_Socket);*/ /* set close-on-exec flag */ if ((Flags = fcntl(pPipe->m_Socket, F_GETFD, 0)) != -1) { Flags |= FD_CLOEXEC; if (fcntl(pPipe->m_Socket, F_SETFD, Flags) == -1) { OSL_TRACE("osl_createPipe failed changing socket flags. Errno: %d; %s",errno,strerror(errno)); } } memset(&addr, 0, sizeof(addr)); OSL_TRACE("osl_createPipe : Pipe Name '%s'",name); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, name, sizeof(addr.sun_path) - 1); #if defined(FREEBSD) len = SUN_LEN(&addr); #else len = sizeof(addr); #endif if ( Options & osl_Pipe_CREATE ) { struct stat status; /* check if there exists an orphan filesystem entry */ if ( ( stat(name, &status) == 0) && ( S_ISSOCK(status.st_mode) || S_ISFIFO(status.st_mode) ) ) { if ( connect(pPipe->m_Socket,(struct sockaddr *)&addr,len) >= 0 ) { OSL_TRACE("osl_createPipe : Pipe already in use. Errno: %d; %s",errno,strerror(errno)); close (pPipe->m_Socket); __osl_destroyPipeImpl(pPipe); return NULL; } unlink(name); } /* ok, fs clean */ if ( bind(pPipe->m_Socket, (struct sockaddr *)&addr, len) < 0 ) { OSL_TRACE("osl_createPipe : failed to bind socket. Errno: %d; %s",errno,strerror(errno)); close (pPipe->m_Socket); __osl_destroyPipeImpl(pPipe); return NULL; } /* Only give access to all if no security handle was specified, otherwise security depends on umask */ if ( !Security ) chmod(name,S_IRWXU | S_IRWXG |S_IRWXO); strncpy(pPipe->m_Name, name, sizeof(pPipe->m_Name) - 1); if ( listen(pPipe->m_Socket, 5) < 0 ) { OSL_TRACE("osl_createPipe failed to listen. Errno: %d; %s",errno,strerror(errno)); unlink(name); /* remove filesystem entry */ close (pPipe->m_Socket); __osl_destroyPipeImpl(pPipe); return NULL; } return (pPipe); } else { /* osl_pipe_OPEN */ if ( access(name, F_OK) != -1 ) { if ( connect( pPipe->m_Socket, (struct sockaddr *)&addr, len) >= 0 ) { return (pPipe); } OSL_TRACE("osl_createPipe failed to connect. Errno: %d; %s",errno,strerror(errno)); } close (pPipe->m_Socket); __osl_destroyPipeImpl(pPipe); return NULL; } }
oslPipe SAL_CALL osl_createPipe(rtl_uString *strPipeName, oslPipeOptions Options, oslSecurity Security) { rtl_uString* name = NULL; rtl_uString* path = NULL; rtl_uString* temp = NULL; oslPipe pPipe; PSECURITY_ATTRIBUTES pSecAttr = NULL; rtl_uString_newFromAscii(&path, PIPESYSTEM); rtl_uString_newFromAscii(&name, PIPEPREFIX); if ( /*IS_NT &&*/ Security) { rtl_uString *Ident = NULL; rtl_uString *Delim = NULL; OSL_VERIFY(osl_getUserIdent(Security, &Ident)); rtl_uString_newFromAscii(&Delim, "_"); rtl_uString_newConcat(&temp, name, Ident); rtl_uString_newConcat(&name, temp, Delim); rtl_uString_release(Ident); rtl_uString_release(Delim); } else { if (Options & osl_Pipe_CREATE) { PSECURITY_DESCRIPTOR pSecDesc; pSecDesc = (PSECURITY_DESCRIPTOR) rtl_allocateMemory(SECURITY_DESCRIPTOR_MIN_LENGTH); /* add a NULL disc. ACL to the security descriptor */ OSL_VERIFY(InitializeSecurityDescriptor(pSecDesc, SECURITY_DESCRIPTOR_REVISION)); OSL_VERIFY(SetSecurityDescriptorDacl(pSecDesc, TRUE, (PACL) NULL, FALSE)); pSecAttr = rtl_allocateMemory(sizeof(SECURITY_ATTRIBUTES)); pSecAttr->nLength = sizeof(SECURITY_ATTRIBUTES); pSecAttr->lpSecurityDescriptor = pSecDesc; pSecAttr->bInheritHandle = TRUE; } } rtl_uString_assign(&temp, name); rtl_uString_newConcat(&name, temp, strPipeName); /* alloc memory */ pPipe= __osl_createPipeImpl(); osl_incrementInterlockedCount(&(pPipe->m_Reference)); /* build system pipe name */ rtl_uString_assign(&temp, path); rtl_uString_newConcat(&path, temp, name); rtl_uString_release(temp); temp = NULL; if (Options & osl_Pipe_CREATE) { SetLastError( ERROR_SUCCESS ); if ( IS_NT ) pPipe->m_NamedObject = CreateMutexW( NULL, FALSE, name->buffer ); else { LPSTR pszTempBuffer = NULL; int nCharsNeeded; nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, name->buffer, name->length, NULL, 0, NULL, NULL ); pszTempBuffer = alloca( nCharsNeeded * sizeof(CHAR) ); nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, name->buffer, name->length, pszTempBuffer, nCharsNeeded, NULL, NULL ); pszTempBuffer[nCharsNeeded-1] = 0; pPipe->m_NamedObject = CreateMutexA( NULL, FALSE, pszTempBuffer ); } if ( pPipe->m_NamedObject != INVALID_HANDLE_VALUE && pPipe->m_NamedObject != NULL ) { if ( GetLastError() != ERROR_ALREADY_EXISTS ) { pPipe->m_Security = pSecAttr; rtl_uString_assign(&pPipe->m_Name, name); if (IS_NT) { /* try to open system pipe */ pPipe->m_File = CreateNamedPipeW( path->buffer, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_WAIT | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, 4096, 4096, NMPWAIT_WAIT_FOREVER, pPipe->m_Security); if (pPipe->m_File != INVALID_HANDLE_VALUE) { rtl_uString_release( name ); rtl_uString_release( path ); return pPipe; } } else /* Win 9x */ { LPSTR pszTempBuffer = NULL; int nCharsNeeded; nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, NULL, 0, NULL, NULL ); pszTempBuffer = alloca( nCharsNeeded * sizeof(CHAR) ); nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, pszTempBuffer, nCharsNeeded, NULL, NULL ); pszTempBuffer[nCharsNeeded-1] = 0; pPipe->m_File = CreateSimplePipe( pszTempBuffer ); if ( IsValidHandle(pPipe->m_File) ) { rtl_uString_release( name ); rtl_uString_release( path ); return pPipe; } } } else { CloseHandle( pPipe->m_NamedObject ); pPipe->m_NamedObject = INVALID_HANDLE_VALUE; } } } else { if (IS_NT) { BOOL fPipeAvailable; do { /* free instance should be available first */ fPipeAvailable = WaitNamedPipeW(path->buffer, NMPWAIT_WAIT_FOREVER); /* first try to open system pipe */ if ( fPipeAvailable ) { pPipe->m_File = CreateFileW( path->buffer, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if ( pPipe->m_File != INVALID_HANDLE_VALUE ) { // We got it ! rtl_uString_release( name ); rtl_uString_release( path ); return (pPipe); } else { // Pipe instance maybe catched by another client -> try again } } } while ( fPipeAvailable ); } else /* Win 9x */ { LPSTR pszTempBuffer = NULL; int nCharsNeeded; nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, NULL, 0, NULL, NULL ); pszTempBuffer = alloca( nCharsNeeded * sizeof(CHAR) ); nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, pszTempBuffer, nCharsNeeded, NULL, NULL ); pszTempBuffer[nCharsNeeded-1] = 0; pPipe->m_File = OpenSimplePipe( pszTempBuffer ); if ( IsValidHandle(pPipe->m_File) ) { // We got it ! rtl_uString_release( name ); rtl_uString_release( path ); return (pPipe); } } } /* if we reach here something went wrong */ __osl_destroyPipeImpl(pPipe); return NULL; }