Пример #1
0
/**
   Connects to the fish socket and starts listening for connections
*/
static int get_socket()
{
	int s, len, doexit = 0;
	int exitcode = EXIT_FAILURE;
	struct sockaddr_un local;
	char *sock_name = get_socket_filename();

	/*
	   Start critical section protected by lock
	*/
	char *lockfile = acquire_socket_lock( sock_name );
	if( lockfile == NULL )
	{
		debug( 0, L"Unable to obtain lock on socket, exiting" );
		exit( EXIT_FAILURE );
	}
	debug( 4, L"Acquired lockfile: %s", lockfile );
	
	local.sun_family = AF_UNIX;
	strcpy( local.sun_path, sock_name );
	len = sizeof(local);
	
	debug(1, L"Connect to socket at %s", sock_name);
	
	if( ( s = socket( AF_UNIX, SOCK_STREAM, 0 ) ) == -1 )
	{
		wperror( L"socket" );
		doexit = 1;
		goto unlock;
	}

	/*
	   First check whether the socket has been opened by another fishd;
	   if so, exit with success status
	*/
	if( connect( s, (struct sockaddr *)&local, len ) == 0 )
	{
		debug( 1, L"Socket already exists, exiting" );
		doexit = 1;
		exitcode = 0;
		goto unlock;
	}
	
	unlink( local.sun_path );
	if( bind( s, (struct sockaddr *)&local, len ) == -1 )
	{
		wperror( L"bind" );
		doexit = 1;
		goto unlock;
	}

	if( fcntl( s, F_SETFL, O_NONBLOCK ) != 0 )
	{
		wperror( L"fcntl" );
		close( s );
		doexit = 1;
	} else if( listen( s, 64 ) == -1 )
	{
		wperror( L"listen" );
		doexit = 1;
	}

unlock:
	(void)unlink( lockfile );
	debug( 4, L"Released lockfile: %s", lockfile );
	/*
	   End critical section protected by lock
	*/
	
	free( lockfile );
	
	free( sock_name );

	if( doexit )
	{
		exit( exitcode );
	}

	return s;
}
Пример #2
0
/**
   Connects to the fish socket and starts listening for connections
*/
static int get_socket(void)
{
    // Cygwin has random problems involving sockets. When using Cygwin,
    // allow 20 attempts at making socket correctly.
#ifdef __CYGWIN__
    int attempts = 0;
repeat:
    attempts += 1;
#endif

    int s, len, doexit = 0;
    int exitcode = EXIT_FAILURE;
    struct sockaddr_un local;
    const std::string sock_name = get_socket_filename();

    /*
       Start critical section protected by lock
    */
    std::string lockfile;
    if (! acquire_socket_lock(sock_name, &lockfile))
    {
        debug(0, L"Unable to obtain lock on socket, exiting");
        exit(EXIT_FAILURE);
    }
    debug(4, L"Acquired lockfile: %s", lockfile.c_str());

    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, sock_name.c_str());
    len = sizeof(local);

    debug(1, L"Connect to socket at %s", sock_name.c_str());

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
    {
        wperror(L"socket");
        doexit = 1;
        goto unlock;
    }

    /*
       First check whether the socket has been opened by another fishd;
       if so, exit with success status
    */
    if (connect(s, (struct sockaddr *)&local, len) == 0)
    {
        debug(1, L"Socket already exists, exiting");
        doexit = 1;
        exitcode = 0;
        goto unlock;
    }

    unlink(local.sun_path);
    if (bind(s, (struct sockaddr *)&local, len) == -1)
    {
        wperror(L"bind");
        doexit = 1;
        goto unlock;
    }

    if (make_fd_nonblocking(s) != 0)
    {
        wperror(L"fcntl");
        close(s);
        doexit = 1;
    }
    else if (listen(s, 64) == -1)
    {
        wperror(L"listen");
        doexit = 1;
    }

unlock:
    (void)unlink(lockfile.c_str());
    debug(4, L"Released lockfile: %s", lockfile.c_str());
    /*
       End critical section protected by lock
    */

    if (doexit)
    {
        // If Cygwin, only allow normal quit when made lots of attempts.
#ifdef __CYGWIN__
        if (exitcode && attempts < 20) goto repeat;
#endif
        exit_without_destructors(exitcode);
    }

    return s;
}