Changeset 314

Show
Ignore:
Timestamp:
04/28/07 09:52:16 (2 years ago)
Author:
blackhedd
Message:

supported connections to Unix-domain sockets. This will eventually need to be refactored,
as there is some namespace pollution between the TCP-support and the Unix-domain-support
method.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • version_0/ext/cmain.cpp

    r296 r314  
    9494} 
    9595 
     96/*************************** 
     97evma_connect_to_unix_server 
     98***************************/ 
     99 
     100extern "C" const char *evma_connect_to_unix_server (const char *server) 
     101{ 
     102        if (!EventMachine) 
     103                throw std::runtime_error ("not initialized"); 
     104        return EventMachine->ConnectToUnixServer (server); 
     105} 
     106 
    96107 
    97108/********************** 
  • version_0/ext/em.cpp

    r312 r314  
    647647} 
    648648 
     649/*********************************** 
     650EventMachine_t::ConnectToUnixServer 
     651***********************************/ 
     652 
     653const char *EventMachine_t::ConnectToUnixServer (const char *server) 
     654{ 
     655        /* Connect to a Unix-domain server, which by definition is running 
     656         * on the same host. 
     657         * There is no meaningful implementation on Windows. 
     658         * There's no need to do a nonblocking connect, since the connection 
     659         * is always local and can always be fulfilled immediately. 
     660         */ 
     661 
     662        #ifdef OS_WIN32 
     663        throw std::runtime_error ("unix-domain connection unavailable on this platform"); 
     664        return NULL; 
     665        #endif 
     666 
     667        // The whole rest of this function is only compiled on Unix systems. 
     668        #ifdef OS_UNIX 
     669 
     670        const char *out = NULL; 
     671 
     672        if (!server || !*server) 
     673                return NULL; 
     674 
     675        sockaddr_un pun; 
     676        memset (&pun, 0, sizeof(pun)); 
     677        pun.sun_family = AF_LOCAL; 
     678 
     679        // You ordinarily expect the server name field to be at least 1024 bytes long, 
     680        // but on Linux it can be MUCH shorter. 
     681        if (strlen(server) >= sizeof(pun.sun_path)) 
     682                throw std::runtime_error ("unix-domain server name is too long"); 
     683 
     684 
     685        strcpy (pun.sun_path, server); 
     686 
     687        int fd = socket (AF_LOCAL, SOCK_STREAM, 0); 
     688        if (fd == INVALID_SOCKET) 
     689                return NULL; 
     690 
     691        // From here on, ALL error returns must close the socket. 
     692        // NOTE: At this point, the socket is still a blocking socket. 
     693        if (connect (fd, (struct sockaddr*)&pun, sizeof(pun)) != 0) { 
     694                closesocket (fd); 
     695                return NULL; 
     696        } 
     697 
     698        // Set the newly-connected socket nonblocking. 
     699        if (!SetSocketNonblocking (fd)) { 
     700                closesocket (fd); 
     701                return NULL; 
     702        } 
     703 
     704        // Set up a connection descriptor and add it to the event-machine. 
     705        // Observe, even though we know the connection status is connect-success, 
     706        // we still set the "pending" flag, so some needed initializations take 
     707        // place. 
     708        ConnectionDescriptor *cd = new ConnectionDescriptor (fd); 
     709        if (!cd) 
     710                throw std::runtime_error ("no connection allocated"); 
     711        cd->SetConnectPending (true); 
     712        Add (cd); 
     713        out = cd->GetBinding().c_str(); 
     714 
     715        if (out == NULL) 
     716                closesocket (fd); 
     717 
     718        return out; 
     719        #endif 
     720} 
     721 
    649722 
    650723/******************************* 
  • version_0/ext/em.h

    r303 r314  
    7373                const char *InstallOneshotTimer (int); 
    7474                const char *ConnectToServer (const char *, int); 
     75                const char *ConnectToUnixServer (const char *); 
    7576                const char *CreateTcpServer (const char *, int); 
    7677                const char *OpenDatagramSocket (const char *, int); 
  • version_0/ext/eventmachine.h

    r296 r314  
    3737        const char *evma_install_oneshot_timer (int seconds); 
    3838        const char *evma_connect_to_server (const char *server, int port); 
     39        const char *evma_connect_to_unix_server (const char *server); 
    3940        const char *evma_create_tcp_server (const char *address, int port); 
    4041        const char *evma_create_unix_domain_server (const char *filename); 
  • version_0/ext/rubymain.cpp

    r307 r314  
    206206 
    207207        const char *f = evma_connect_to_server (StringValuePtr(server), NUM2INT(port)); 
     208        if (!f || !*f) 
     209                rb_raise (rb_eRuntimeError, "no connection"); 
     210        return rb_str_new2 (f); 
     211} 
     212 
     213/********************* 
     214t_connect_unix_server 
     215*********************/ 
     216 
     217static VALUE t_connect_unix_server (VALUE self, VALUE serversocket) 
     218{ 
     219        const char *f = evma_connect_to_unix_server (StringValuePtr(serversocket)); 
    208220        if (!f || !*f) 
    209221                rb_raise (rb_eRuntimeError, "no connection"); 
     
    323335        rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2); 
    324336        rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2); 
     337        rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1); 
    325338        rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2); 
    326339        rb_define_module_function (EmModule, "release_machine", (VALUE(*)(...))t_release_machine, 0); 
  • version_0/lib/eventmachine.rb

    r306 r314  
    606606 
    607607 
     608 
     609 
     610        # Make a connection to a Unix-domain socket. This is not implemented on Windows platforms. 
     611        # The parameter socketname is a String which identifies the Unix-domain socket you want 
     612        # to connect to. socketname is the name of a file on your local system, and in most cases 
     613        # is a fully-qualified path name. Make sure that your process has enough local permissions 
     614        # to open the Unix-domain socket. 
     615        # See also the documentation for #connect_server. This method behaves like #connect_server 
     616        # in all respects except for the fact that it makes a connection to a local Unix-domain 
     617        # socket rather than a TCP socket. 
     618        #-- 
     619        # For making connections to Unix-domain sockets. 
     620        # Eventually this has to get properly documented and unified with the TCP-connect methods. 
     621        # Note how nearly identical this is to EventMachine#connect 
     622        def EventMachine::connect_unix socketname, handler=nil 
     623                klass = if (handler and handler.is_a?(Class)) 
     624                        handler 
     625                else 
     626                        Class.new( Connection ) {handler and include handler} 
     627                end 
     628 
     629                s = connect_unix_server socketname 
     630                c = klass.new s 
     631                @conns[s] = c 
     632                block_given? and yield c 
     633                c 
     634        end 
     635 
     636 
    608637  # EventMachine#open_datagram_socket is for support of UDP-based 
    609638  # protocols. Its usage is similar to that of EventMachine#start_server.