Пример #1
0
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 ( 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_atomic_increment(&(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 );

        pPipe->m_NamedObject = CreateMutexW( NULL, FALSE, name->buffer );

        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);

                /* 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
            {
                CloseHandle( pPipe->m_NamedObject );
                pPipe->m_NamedObject = INVALID_HANDLE_VALUE;
            }
        }
    }
    else
    {
        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 );
    }

    /* if we reach here something went wrong */
    __osl_destroyPipeImpl(pPipe);

    return NULL;
}
Пример #2
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;
}
Пример #3
0
Файл: pipe.c Проект: cjapes/core
oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe)
{
    oslPipe  pAcceptedPipe = NULL;

    OVERLAPPED   os;

    DWORD nBytesTransfered;
    rtl_uString* path = NULL;
    rtl_uString* temp = NULL;

    OSL_ASSERT(pPipe);
    OSL_ASSERT(pPipe->m_File != INVALID_HANDLE_VALUE);

    memset(&os, 0, 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_atomic_increment(&(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 );

    return pAcceptedPipe;
}
Пример #4
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];
	oslPipe  pPipe;

	if (access(PIPEDEFAULTPATH, R_OK|W_OK) == 0)
    {
		strncpy(name, PIPEDEFAULTPATH, sizeof(name));
    }
	else
    {
		strncpy(name, PIPEALTERNATEPATH, sizeof(name));
    }


	strncat(name, "/", sizeof(name));

	if (Security)
	{
		sal_Char Ident[256];

        Ident[0] = '\0';

		OSL_VERIFY(osl_psz_getUserIdent(Security, Ident, sizeof(Ident)));

		snprintf(&name[strlen(name)], sizeof(name), SECPIPENAMEMASK, Ident, pszPipeName);
	}
	else
	{
		snprintf(&name[strlen(name)], sizeof(name), PIPENAMEMASK, pszPipeName);
	}


	/* alloc memory */
	pPipe= __osl_createPipeImpl();

	/* 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\n",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\n",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));
#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\n",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\n",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));

		if ( listen(pPipe->m_Socket, 5) < 0 )
		{
			OSL_TRACE("osl_createPipe failed to listen. Errno: %d; %s\n",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\n",errno,strerror(errno));
		}

		close (pPipe->m_Socket);
		__osl_destroyPipeImpl(pPipe);
		return NULL;
	}
}