Exemple #1
0
sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe,
                       const void* pBuffer,
                       sal_Int32 BytesToSend)
{
    int nRet=0;

    OSL_ASSERT(pPipe);

    if ( pPipe == 0 )
    {
        OSL_TRACE("osl_sendPipe : Invalid socket");
        errno=EINVAL;
        return -1;
    }

    nRet = send(pPipe->m_Socket,
                  (sal_Char*)pBuffer,
                  BytesToSend, 0);

    if ( nRet <= 0 )
    {
        OSL_TRACE("osl_sendPipe failed : %i '%s'",nRet,strerror(errno));
    }

     return nRet;
}
Exemple #2
0
void _imp_getProcessLocale( rtl_Locale ** ppLocale )
{
    static char *locale = NULL;

    /* basic thread safeness */
//    pthread_mutex_lock( &aLocalMutex );

    /* Only fetch the locale once and cache it */
    if ( NULL == locale )
    {

        locale = (char *)malloc( 128 );
        if ( locale )
            macosx_getLocale( locale, 128 );
        else
            fprintf( stderr, "nlsupport.c:  locale allocation returned NULL!\n" );
    }

    /* handle the case where OS specific method of finding locale fails */
    if ( NULL == locale )
    {
        /* simulate behavior of setlocale */
        locale = getenv( "LC_ALL" );

        if( NULL == locale )
            locale = getenv( "LC_CTYPE" );

        if( NULL == locale )
            locale = getenv( "LANG" );

        if( NULL == locale )
            locale = "C";
    }

    /* return the locale */
    *ppLocale = _parse_locale( locale );

    setenv( "LC_ALL", locale, 1);
    setenv("LC_CTYPE", locale, 1 );
    setenv("LANG", locale, 1 );

#if OSL_DEBUG_LEVEL > 1
    OSL_TRACE("_imp_getProcessLocale() returning %s as current locale.", locale );
#endif

//    pthread_mutex_unlock( &aLocalMutex );

}
Exemple #3
0
oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe)
{
    int     s, flags;
    oslPipe pAcceptedPipe;

    OSL_ASSERT(pPipe);
    if ( pPipe == 0 )
    {
        return NULL;
    }

    OSL_ASSERT(strlen(pPipe->m_Name) > 0);

#if defined(LINUX)
    pPipe->m_bIsAccepting = sal_True;
#endif

    s = accept(pPipe->m_Socket, NULL, NULL);

#if defined(LINUX)
    pPipe->m_bIsAccepting = sal_False;
#endif

    if (s < 0)
    {
        OSL_TRACE("osl_acceptPipe : accept error '%s'", strerror(errno));
        return NULL;
    }

#if defined(LINUX)
    if ( pPipe->m_bIsInShutdown  )
    {
        close(s);
        return NULL;
    }
#endif /* LINUX */
    else
    {
        /* alloc memory */
        pAcceptedPipe = __osl_createPipeImpl();

        OSL_ASSERT(pAcceptedPipe);
        if(pAcceptedPipe==NULL)
        {
            close(s);
            return NULL;
        }

        /* set close-on-exec flag */
        if (!((flags = fcntl(s, F_GETFD, 0)) < 0))
        {
            flags |= FD_CLOEXEC;
            if (fcntl(s, F_SETFD, flags) < 0)
            {
                OSL_TRACE("osl_acceptPipe: error changing socket flags. "
                          "Errno: %d; %s",errno,strerror(errno));
            }
        }

        pAcceptedPipe->m_Socket = s;
    }

    return pAcceptedPipe;
}
Exemple #4
0
void SAL_CALL osl_closePipe( oslPipe pPipe )
{
    int nRet;
#if defined(LINUX)
    size_t     len;
    struct sockaddr_un addr;
    int fd;
#endif
    int ConnFD;

    if( ! pPipe )
    {
        return;
    }

    if( pPipe->m_bClosed )
    {
        return;
    }

    ConnFD = pPipe->m_Socket;

    /*
      Thread does not return from accept on linux, so
      connect to the accepting pipe
     */
#if defined(LINUX)
    if ( pPipe->m_bIsAccepting )
    {
        pPipe->m_bIsInShutdown = sal_True;
        pPipe->m_Socket = -1;
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if ( fd < 0 )
        {
            OSL_TRACE("socket in osl_destroyPipe failed with error: %s", strerror(errno));
            return;
        }
        memset(&addr, 0, sizeof(addr));

        OSL_TRACE("osl_destroyPipe : Pipe Name '%s'",pPipe->m_Name);

        addr.sun_family = AF_UNIX;
        strncpy(addr.sun_path, pPipe->m_Name, sizeof(addr.sun_path) - 1);
        len = sizeof(addr);

        nRet = connect( fd, (struct sockaddr *)&addr, len);
        if ( nRet < 0 )
        {
            OSL_TRACE("connect in osl_destroyPipe failed with error: %s", strerror(errno));
        }
        close(fd);
    }
#endif /* LINUX */

    nRet = shutdown(ConnFD, 2);
    if ( nRet < 0 )
    {
        OSL_TRACE("shutdown in destroyPipe failed : '%s'",strerror(errno));
    }

    nRet = close(ConnFD);
    if ( nRet < 0 )
    {
        OSL_TRACE("close in destroyPipe failed : '%s'",strerror(errno));
    }
    /* remove filesystem entry */
    if ( strlen(pPipe->m_Name) > 0 )
    {
        unlink(pPipe->m_Name);
    }
    pPipe->m_bClosed = sal_True;

/*      OSL_TRACE("Out osl_destroyPipe");     */
}
Exemple #5
0
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;
    }
}
Exemple #6
0
static void ChildStatusProc(void *pData)
{
	pid_t pid = -1;
	int   status = 0;
	int   channel[2];
	ProcessData  data;
	ProcessData *pdata;
	int		stdOutput[2] = { -1, -1 }, stdInput[2] = { -1, -1 }, stdError[2] = { -1, -1 };

	pdata = (ProcessData *)pData;

	/* make a copy of our data, because forking will only copy
	   our local stack of the thread, so the process data will not be accessible
	   in our child process */
	memcpy(&data, pData, sizeof(data));

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, channel) == -1)
        status = errno;

    fcntl(channel[0], F_SETFD, FD_CLOEXEC);
    fcntl(channel[1], F_SETFD, FD_CLOEXEC);

	/* Create redirected IO pipes */
	if ( status == 0 && data.m_pInputWrite )
		if (pipe( stdInput ) == -1)
		    status = errno;

	if ( status == 0 && data.m_pOutputRead )
		if (pipe( stdOutput ) == -1)
		    status = errno;

	if ( status == 0 && data.m_pErrorRead )
		if (pipe( stdError ) == -1)
		    status = errno;

    if ( (status == 0) && ((pid = fork()) == 0) )
    {
		/* Child */
        int chstatus = 0;
        sal_Int32 nWrote;

	    if (channel[0] != -1) close(channel[0]);

		if ((data.m_uid != (uid_t)-1) && ((data.m_uid != getuid()) || (data.m_gid != getgid())))
		{
			OSL_ASSERT(geteuid() == 0);		/* must be root */

			if (! INIT_GROUPS(data.m_name, data.m_gid) || (setuid(data.m_uid) != 0))
				OSL_TRACE("Failed to change uid and guid, errno=%d (%s)\n", errno, strerror(errno));
#if defined(LINUX) || defined (FREEBSD)
			unsetenv("HOME");
#else
			putenv("HOME=");
#endif
		}

  		if (data.m_pszDir)
  			chstatus = chdir(data.m_pszDir);

   	    if (chstatus == 0 && ((data.m_uid == (uid_t)-1) || ((data.m_uid == getuid()) && (data.m_gid == getgid()))))
		{
            int i;
			for (i = 0; data.m_pszEnv[i] != NULL; i++)
            {
                if (strchr(data.m_pszEnv[i], '=') == NULL)
                {
                    unsetenv(data.m_pszEnv[i]); /*TODO: check error return*/
                }
                else
                {
                    putenv(data.m_pszEnv[i]); /*TODO: check error return*/
                }
            }

            OSL_TRACE("ChildStatusProc : starting '%s'",data.m_pszArgs[0]);
     
			/* Connect std IO to pipe ends */

			/* Write end of stdInput not used in child process */
			if (stdInput[1] != -1) close( stdInput[1] );

			/* Read end of stdOutput not used in child process */
			if (stdOutput[0] != -1) close( stdOutput[0] );

			/* Read end of stdError not used in child process */
			if (stdError[0] != -1) close( stdError[0] );

			/* Redirect pipe ends to std IO */

			if ( stdInput[0] != STDIN_FILENO )
			{
				dup2( stdInput[0], STDIN_FILENO );
				if (stdInput[0] != -1) close( stdInput[0] );
			}

			if ( stdOutput[1] != STDOUT_FILENO )
			{
				dup2( stdOutput[1], STDOUT_FILENO );
				if (stdOutput[1] != -1) close( stdOutput[1] );
			}

			if ( stdError[1] != STDERR_FILENO )
			{
				dup2( stdError[1], STDERR_FILENO );
				if (stdError[1] != -1) close( stdError[1] );
			}

	    	pid=execv(data.m_pszArgs[0], (sal_Char **)data.m_pszArgs);

		}

        OSL_TRACE("Failed to exec, errno=%d (%s)\n", errno, strerror(errno));

        OSL_TRACE("ChildStatusProc : starting '%s' failed",data.m_pszArgs[0]);
        
		/* if we reach here, something went wrong */
        nWrote = write(channel[1], &errno, sizeof(errno));
		if (nWrote != sizeof(errno))
            OSL_TRACE("sendFdPipe : sending failed (%s)",strerror(errno));

	    if (channel[1] != -1) close(channel[1]);

		_exit(255);
    }
    else
    {   /* Parent  */
        int i = -1;
		if (channel[1] != -1) close(channel[1]);

		/* Close unused pipe ends */
		if (stdInput[0] != -1) close( stdInput[0] );
		if (stdOutput[1] != -1) close( stdOutput[1] );
		if (stdError[1] != -1) close( stdError[1] );

		if (pid > 0)
		{
			while (((i = read(channel[0], &status, sizeof(status))) < 0))
			{
				if (errno != EINTR)
					break;
			}
		}

		if (channel[0] != -1) close(channel[0]);

		if ((pid > 0) && (i == 0))
		{
			pid_t	child_pid;
			osl_acquireMutex(ChildListMutex);

			pdata->m_pProcImpl->m_pid = pid;
			pdata->m_pProcImpl->m_pnext = ChildList;
			ChildList = pdata->m_pProcImpl;

			/* Store used pipe ends in data structure */

			if ( pdata->m_pInputWrite )
				*(pdata->m_pInputWrite) = osl_createFileHandleFromFD( stdInput[1] );
				
			if ( pdata->m_pOutputRead )
				*(pdata->m_pOutputRead) = osl_createFileHandleFromFD( stdOutput[0] );
				
			if ( pdata->m_pErrorRead )
				*(pdata->m_pErrorRead) = osl_createFileHandleFromFD( stdError[0] );

			osl_releaseMutex(ChildListMutex);

			osl_setCondition(pdata->m_started);
            
			do
			{
				child_pid = waitpid(pid, &status, 0);
			} while ( 0 > child_pid && EINTR == errno );

			if ( child_pid < 0)
			{
				OSL_TRACE("Failed to wait for child process, errno=%d (%s)\n", errno, strerror(errno));

				/* 
				We got an other error than EINTR. Anyway we have to wake up the
				waiting thread under any circumstances */

				child_pid = pid;
			}

			
			if ( child_pid > 0 )
			{
				oslProcessImpl* pChild;

				osl_acquireMutex(ChildListMutex);

				pChild = ChildList;

				/* check if it is one of our child processes */
				while (pChild != NULL)
				{
					if (pChild->m_pid == child_pid)
					{
						if (WIFEXITED(status))
							pChild->m_status = WEXITSTATUS(status);
						else
							pChild->m_status = -1;

						osl_setCondition(pChild->m_terminated);
					}

					pChild = pChild->m_pnext;
				}

				osl_releaseMutex(ChildListMutex);
			}
		}
		else
		{
            OSL_TRACE("ChildStatusProc : starting '%s' failed",data.m_pszArgs[0]);            
			OSL_TRACE("Failed to launch child process, child reports errno=%d (%s)\n", status, strerror(status));

			/* Close pipe ends */
			if ( pdata->m_pInputWrite )
				*pdata->m_pInputWrite = NULL;

			if ( pdata->m_pOutputRead )
				*pdata->m_pOutputRead = NULL;

			if ( pdata->m_pErrorRead )
				*pdata->m_pErrorRead = NULL;

			if (stdInput[1] != -1) close( stdInput[1] );
			if (stdOutput[0] != -1) close( stdOutput[0] );
			if (stdError[0] != -1) close( stdError[0] );

            //if pid > 0 then a process was created, even if it later failed
            //e.g. bash searching for a command to execute, and we still
            //need to clean it up to avoid "defunct" processes
            if (pid > 0)
            {
                pid_t child_pid;
                do
                {
                    child_pid = waitpid(pid, &status, 0);
                } while ( 0 > child_pid && EINTR == errno );
            }

			/* notify (and unblock) parent thread */
			osl_setCondition(pdata->m_started);
		}
	}
}
Exemple #7
0
static oslSocket receiveFdPipe(int PipeFD)
{
    oslSocket pSocket = 0;
    struct msghdr msghdr;
    struct iovec iov[1];
    char buffer[2];
    sal_Int32 nRead;
    int newfd=-1;
    int nRetCode=0;
/*      char *ptr; */

#if defined(IOCHANNEL_TRANSFER_BSD)
    
    OSL_TRACE("IOCHANNEL_TRANSFER_BSD receive\n");
    
    iov[0].iov_base = buffer;
    iov[0].iov_len = sizeof(buffer);
    msghdr.msg_name = NULL;
    msghdr.msg_namelen = 0;
    msghdr.msg_iov = iov;
    msghdr.msg_iovlen = 1;
    msghdr.msg_accrights = (caddr_t) &newfd; /* addr of descriptor   */
    msghdr.msg_accrightslen = sizeof(int);	 /* receive 1 descriptor */
    
#else
    struct cmsghdr* cmptr = (struct cmsghdr*)malloc(CONTROLLEN);

    OSL_TRACE(" !!!! IOCHANNEL_TRANSFER_BSD_RENO receive");
    
    iov[0].iov_base = buffer;
    iov[0].iov_len = sizeof(buffer);
    msghdr.msg_name = NULL;
    msghdr.msg_namelen = 0;
    msghdr.msg_iov = iov;
    msghdr.msg_iovlen = 1;

    msghdr.msg_control = (caddr_t) cmptr;
    msghdr.msg_controllen = CONTROLLEN;

#endif
    

#if defined(IOCHANNEL_TRANSFER_BSD)
    
    if ( ( nRead = recvmsg(PipeFD, &msghdr, 0) ) > 0 )
    {
        OSL_TRACE("receiveFdPipe : received '%i' bytes\n",nRead);
    }
#else

    if ( ( ( nRead = recvmsg(PipeFD, &msghdr, 0) ) > 0 ) &&
         ( msghdr.msg_controllen == CONTROLLEN ) )
    {
        OSL_TRACE("receiveFdPipe : received '%i' bytes\n",nRead);
        memcpy(&newfd, CMSG_DATA(cmptr), sizeof(int));
    }
#endif
    else
    {
        OSL_TRACE("receiveFdPipe : receiving failed (%s)",strerror(errno));
    }
    
    if ( newfd >= 0 )
    {
        pSocket = __osl_createSocketImpl(newfd);
        nRetCode=1;        
        OSL_TRACE("received fd %i\n",newfd);
    }

    OSL_TRACE("receiveFdPipe : writing back %i",nRetCode);
    nRead=write(PipeFD,&nRetCode,sizeof(nRetCode));

#if defined(IOCHANNEL_TRANSFER_BSD_RENO)
    free(cmptr);
#endif

    return pSocket;
}
Exemple #8
0
static sal_Bool sendFdPipe(int PipeFD, int SocketFD)
{
    sal_Bool bRet = sal_False;

    struct iovec	iov[1];
    struct msghdr	msg;
    char			buf[2];	/* send_fd()/recv_fd() 2-byte protocol */
    int nSend;
    int RetCode=0;
    
#if defined(IOCHANNEL_TRANSFER_BSD)

    OSL_TRACE("IOCHANNEL_TRANSFER_BSD send");
/*      OSL_TRACE("sending fd %i\n",SocketFD); */
    
    iov[0].iov_base = buf;
    iov[0].iov_len  = sizeof(buf);
    msg.msg_iov     = iov;
    msg.msg_iovlen  = 1;
    msg.msg_name    = NULL;
    msg.msg_namelen = 0;

    msg.msg_accrights    = (caddr_t) &SocketFD;	/* addr of descriptor */
    msg.msg_accrightslen = sizeof(int);		/* pass 1 descriptor */
    buf[1] = 0;								/* zero status means OK */
    buf[0] = 0;								/* null byte flag to recv_fd() */
        
#else
    
    struct cmsghdr* cmptr = (struct cmsghdr*)malloc(CONTROLLEN);

    OSL_TRACE("!!!!!! IOCHANNEL_TRANSFER_BSD_RENO send");
/*      OSL_TRACE("sending fd %i\n",SocketFD); */

    iov[0].iov_base = buf;
    iov[0].iov_len = sizeof(buf);
    msg.msg_iov = iov;
    msg.msg_iovlen = 1;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_control = (caddr_t) cmptr;
    msg.msg_controllen = CONTROLLEN;

    cmptr->cmsg_level = SOL_SOCKET;
    cmptr->cmsg_type = SCM_RIGHTS;
    cmptr->cmsg_len = CONTROLLEN;
    memcpy(CMSG_DATA(cmptr), &SocketFD, sizeof(int));

#endif
    
    if ( ( nSend = sendmsg(PipeFD, &msg, 0) ) > 0 )
    {
        bRet = sal_True;
        OSL_TRACE("sendFdPipe : send '%i' bytes\n",nSend);

    }
    else
    {
        OSL_TRACE("sendFdPipe : sending failed (%s)",strerror(errno));
    }

    nSend=read(PipeFD,&RetCode,sizeof(RetCode));

    if ( nSend > 0 && RetCode == 1 )
    {
        OSL_TRACE("sendFdPipe : resource was received\n");
    }
    else
    {
        OSL_TRACE("sendFdPipe : resource wasn't received\n");        
    }    
    
#if defined(IOCHANNEL_TRANSFER_BSD_RENO)
    free(cmptr);
#endif

    return bRet;
}