static void extend_library_path (const char *new_element) { rtl_uString *pEnvName=NULL, *pOrigEnvVar=NULL, *pNewEnvVar=NULL; const char *pathname; #ifdef AIX pathname = "LIBPATH"; #else pathname = "LD_LIBRARY_PATH"; #endif rtl_uString_newFromAscii( &pEnvName, pathname ); rtl_uString_newFromAscii( &pNewEnvVar, new_element ); osl_getEnvironment( pEnvName, &pOrigEnvVar ); if (pOrigEnvVar && pOrigEnvVar->length) { rtl_uString *pDelim = NULL; rtl_uString_newFromAscii( &pDelim, ":" ); rtl_uString_newConcat( &pNewEnvVar, pNewEnvVar, pDelim ); rtl_uString_newConcat( &pNewEnvVar, pNewEnvVar, pOrigEnvVar ); rtl_uString_release( pDelim ); } osl_setEnvironment( pEnvName, pNewEnvVar ); if (pOrigEnvVar) rtl_uString_release( pOrigEnvVar ); rtl_uString_release( pNewEnvVar ); rtl_uString_release( pEnvName ); }
/* Path of the application, with trailing slash. */ static rtl_uString * get_app_path( const char *pAppExec ) { char pRealPath[PATH_MAX]; rtl_uString *pResult; sal_Int32 len; char* dummy; char *pOrigPath = strdup( pAppExec ); char *pPath = dirname( pOrigPath ); dummy = realpath( pPath, pRealPath ); (void)dummy; pResult = charp_to_ustr( pRealPath ); free( pOrigPath ); len = rtl_uString_getLength(pResult); if (len > 0 && rtl_uString_getStr(pResult)[len - 1] != '/') { rtl_uString *pSlash = NULL; rtl_uString_newFromAscii(&pSlash, "/"); rtl_uString_newConcat(&pResult, pResult, pSlash); rtl_uString_release(pSlash); } return pResult; }
static ChildInfo * child_spawn ( Args *args, sal_Bool bAllArgs, sal_Bool bWithStatus ) { rtl_uString *pApp = NULL, *pTmp = NULL; rtl_uString **ppArgs; sal_uInt32 nArgs, i; ChildInfo *info; int status_pipe[2]; oslProcessError nError; info = calloc (1, sizeof (ChildInfo)); /* create pipe */ if ( pipe( status_pipe ) < 0 ) { fprintf( stderr, "ERROR: no file handles\n"); exit( 1 ); } info->status_fd = status_pipe[0]; /* application name */ rtl_uString_newFromAscii( &pApp, "file://" ); rtl_uString_newConcat( &pApp, pApp, args->pAppPath ); rtl_uString_newFromAscii( &pTmp, "soffice.bin" ); rtl_uString_newConcat( &pApp, pApp, pTmp ); rtl_uString_release( pTmp ); pTmp = NULL; /* copy args */ nArgs = bAllArgs ? args->nArgsTotal : args->nArgsEnv; ppArgs = (rtl_uString **)calloc( nArgs + 1, sizeof( rtl_uString* ) ); for ( i = 0; i < nArgs; ++i ) ppArgs[i] = args->ppArgs[i]; if( bWithStatus ) { char buffer[64]; /* add the pipe arg */ snprintf (buffer, 63, "--splash-pipe=%d", status_pipe[1]); rtl_uString_newFromAscii( &pTmp, buffer ); ppArgs[nArgs] = pTmp; ++nArgs; } /* start the main process */ nError = osl_executeProcess( pApp, ppArgs, nArgs, osl_Process_NORMAL, NULL, NULL, NULL, 0, &info->child ); if (pTmp) rtl_uString_release( pTmp ); free (ppArgs); if ( nError != osl_Process_E_None ) { fprintf( stderr, "ERROR %d forking process\n", nError ); rtl_uString_release( pApp ); _exit (1); } rtl_uString_release( pApp ); close( status_pipe[1] ); return info; }
static void exec_javaldx (Args *args) { char newpath[4096]; sal_uInt32 nArgs; rtl_uString *pApp; rtl_uString **ppArgs; rtl_uString *pTmp, *pTmp2; oslProcess javaldx = NULL; oslFileHandle fileOut= NULL; oslProcessError err; ppArgs = (rtl_uString **)calloc( args->nArgsEnv + 2, sizeof( rtl_uString* ) ); for ( nArgs = 0; nArgs < args->nArgsEnv; ++nArgs ) ppArgs[nArgs] = args->ppArgs[nArgs]; /* Use absolute path to redirectrc */ pTmp = NULL; rtl_uString_newFromAscii( &pTmp, "-env:INIFILENAME=vnd.sun.star.pathname:" ); rtl_uString_newConcat( &pTmp, pTmp, args->pAppPath ); pTmp2 = NULL; rtl_uString_newFromAscii( &pTmp2, "redirectrc" ); rtl_uString_newConcat( &pTmp, pTmp, pTmp2 ); ppArgs[nArgs] = pTmp; rtl_uString_release (pTmp2); nArgs++; /* And also to javaldx */ pApp = NULL; rtl_uString_newFromAscii( &pApp, "file://" ); rtl_uString_newConcat( &pApp, pApp, args->pAppPath ); pTmp = NULL; rtl_uString_newFromAscii( &pTmp, "javaldx" ); rtl_uString_newConcat( &pApp, pApp, pTmp ); rtl_uString_release( pTmp ); err = osl_executeProcess_WithRedirectedIO( pApp, ppArgs, nArgs, osl_Process_NORMAL, NULL, // security NULL, // work dir NULL, 0, &javaldx, // process handle NULL, &fileOut, NULL); rtl_uString_release( ppArgs[nArgs-1] ); rtl_uString_release( pApp ); free( ppArgs ); if( err != osl_Process_E_None) { fprintf (stderr, "Warning: failed to launch javaldx - java may not function correctly\n"); if (javaldx) osl_freeProcessHandle(javaldx); if (fileOut) osl_closeFile(fileOut); return; } else { char *chomp; sal_uInt64 bytes_read; /* Magically osl_readLine doesn't work with pipes with E_SPIPE - so be this lame instead: */ while (osl_readFile (fileOut, newpath, SAL_N_ELEMENTS (newpath), &bytes_read) == osl_File_E_INTR); if (bytes_read <= 0) { fprintf (stderr, "Warning: failed to read path from javaldx\n"); if (javaldx) osl_freeProcessHandle(javaldx); if (fileOut) osl_closeFile(fileOut); return; } newpath[bytes_read] = '\0'; if ((chomp = strstr (newpath, "\n"))) *chomp = '\0'; } extend_library_path (newpath); if (javaldx) osl_freeProcessHandle(javaldx); if (fileOut) osl_closeFile(fileOut); }
/* Construct the pipe name */ static rtl_uString * get_pipe_path( rtl_uString *pAppPath ) { rtl_uString *pPath = NULL, *pTmp = NULL, *pUserInstallation = NULL; rtl_uString *pResult = NULL, *pBasePath = NULL, *pAbsUserInstallation = NULL; rtlBootstrapHandle handle; rtl_uString *pMd5hash = NULL; sal_Unicode pUnicode[RTL_USTR_MAX_VALUEOFINT32]; /* setup bootstrap filename */ rtl_uString_newFromAscii( &pPath, "file://" ); rtl_uString_newConcat( &pPath, pPath, pAppPath ); rtl_uString_newConcat( &pPath, pPath, pTmp ); rtl_uString_newFromAscii( &pTmp, SAL_CONFIGFILE( "bootstrap" ) ); rtl_uString_newConcat( &pPath, pPath, pTmp ); /* read userinstallation value */ handle = rtl_bootstrap_args_open( pPath ); rtl_uString_newFromAscii( &pTmp, "UserInstallation" ); rtl_bootstrap_get_from_handle( handle, pTmp, &pUserInstallation, NULL ); rtl_bootstrap_args_close( handle ); /* turn it into an absolute path - unwinding symlinks etc. */ if ( osl_getProcessWorkingDir (&pBasePath) || osl_getAbsoluteFileURL( pBasePath, pUserInstallation, &pAbsUserInstallation ) ) rtl_uString_newFromString (&pAbsUserInstallation, pUserInstallation); /* create the pipe name */ pMd5hash = get_md5hash( pAbsUserInstallation ); if ( !pMd5hash ) rtl_uString_new( &pMd5hash ); if ( access( PIPEDEFAULTPATH, W_OK ) == 0 ) rtl_uString_newFromAscii( &pResult, PIPEDEFAULTPATH ); else if ( access( PIPEALTERNATEPATH, W_OK ) == 0 ) rtl_uString_newFromAscii( &pResult, PIPEALTERNATEPATH ); else { fprintf( stderr, "ERROR: no valid pipe path found.\n" ); exit( 1 ); } rtl_uString_newFromAscii( &pTmp, "/OSL_PIPE_" ); rtl_uString_newConcat( &pResult, pResult, pTmp ); rtl_ustr_valueOfInt32( pUnicode, (int)getuid(), 10 ); rtl_uString_newFromStr( &pTmp, pUnicode ); rtl_uString_newConcat( &pResult, pResult, pTmp ); rtl_uString_newFromAscii( &pTmp, "_SingleOfficeIPC_" ); rtl_uString_newConcat( &pResult, pResult, pTmp ); rtl_uString_newConcat( &pResult, pResult, pMd5hash ); /* cleanup */ rtl_uString_release( pMd5hash ); rtl_uString_release( pPath ); rtl_uString_release( pTmp ); if ( pBasePath ) { rtl_uString_release( pBasePath ); } rtl_uString_release( pUserInstallation ); rtl_uString_release( pAbsUserInstallation ); return pResult; }
oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe) { oslPipe pAcceptedPipe = NULL; HANDLE Event; OVERLAPPED os; OSL_ASSERT(pPipe); if (IS_NT) { DWORD nBytesTransfered; rtl_uString* path = NULL; rtl_uString* temp = NULL; OSL_ASSERT (pPipe->m_File != INVALID_HANDLE_VALUE); Event = pPipe->m_AcceptEvent; rtl_zeroMemory(&os, sizeof(OVERLAPPED)); os.hEvent = pPipe->m_AcceptEvent; ResetEvent(pPipe->m_AcceptEvent); if ( !ConnectNamedPipe(pPipe->m_File, &os)) { switch ( GetLastError() ) { case ERROR_PIPE_CONNECTED: // Client already connected to pipe case ERROR_NO_DATA: // Client was connected but has already closed pipe end // should only appear in nonblocking mode but in fact does // in blocking asynchronous mode. break; case ERROR_PIPE_LISTENING: // Only for nonblocking mode but see ERROR_NO_DATA case ERROR_IO_PENDING: // This is normal if not client is connected yet case ERROR_MORE_DATA: // Should not happen // blocking call to accept if( !GetOverlappedResult( pPipe->m_File, &os, &nBytesTransfered, TRUE ) ) { // Possible error could be that between ConnectNamedPipe and GetOverlappedResult a connect // took place. switch ( GetLastError() ) { case ERROR_PIPE_CONNECTED: // Pipe was already connected case ERROR_NO_DATA: // Pipe was connected but client has already closed -> ver fast client ;-) break; // Everything's fine !!! default: // Something went wrong return 0; } } break; default: // All other error say that somethings going wrong. return 0; } } pAcceptedPipe = __osl_createPipeImpl(); OSL_ASSERT(pAcceptedPipe); osl_incrementInterlockedCount(&(pAcceptedPipe->m_Reference)); rtl_uString_assign(&pAcceptedPipe->m_Name, pPipe->m_Name); pAcceptedPipe->m_File = pPipe->m_File; rtl_uString_newFromAscii(&temp, PIPESYSTEM); rtl_uString_newConcat(&path, temp, pPipe->m_Name); rtl_uString_release(temp); // prepare for next accept 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, pAcceptedPipe->m_Security); rtl_uString_release( path ); } else /* Win9x */ { pAcceptedPipe = __osl_createPipeImpl(); OSL_ASSERT(pAcceptedPipe); osl_incrementInterlockedCount(&(pAcceptedPipe->m_Reference)); rtl_uString_assign(&pAcceptedPipe->m_Name, pPipe->m_Name); pAcceptedPipe->m_File = pPipe->m_File; pAcceptedPipe->m_File = AcceptSimplePipeConnection( pPipe->m_File ); } return pAcceptedPipe; }
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; }