src/sock_tcp.c
changeset 10 9fe218576d13
parent 8 be88e543c8ff
child 11 14e79683c48c
equal deleted inserted replaced
9:4c4c906cc649 10:9fe218576d13
     4 #include <stdlib.h>
     4 #include <stdlib.h>
     5 #include <sys/types.h>
     5 #include <sys/types.h>
     6 #include <sys/socket.h>
     6 #include <sys/socket.h>
     7 #include <netdb.h>
     7 #include <netdb.h>
     8 #include <unistd.h>
     8 #include <unistd.h>
       
     9 #include <fcntl.h>
     9 #include <string.h>
    10 #include <string.h>
    10 #include <assert.h>
    11 #include <assert.h>
    11 
    12 
    12 /*
    13 /*
    13  * Our sock_stream_methods.read method
    14  * Our sock_stream_methods.read method
    14  */
    15  */
    15 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t len)
    16 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len)
    16 {
    17 {
    17     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    18     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    18     int ret;
    19     int ret;
    19     
    20     
    20     // map directly to read(2)
    21     // map directly to read(2)
    21     if ((ret = read(sock->fd, buf, len)) < 0)
    22     if ((ret = read(sock->fd, buf, *len)) < 0)
    22         // errno
    23         // errno
    23         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ);
    24         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ);
    24 
    25 
    25     else 
    26     // bytes read
    26         // bytes read
    27     *len = ret;
    27         return ret;
    28 
       
    29     return SUCCESS;
    28 }
    30 }
    29 
    31 
    30 /*
    32 /*
    31  * Our sock_stream_methods.write method
    33  * Our sock_stream_methods.write method
    32  */
    34  */
    33 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t len)
    35 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len)
    34 {
    36 {
    35     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    37     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    36     int ret;
    38     int ret;
    37     
    39     
    38     // map directly to write(2)
    40     // map directly to write(2)
    39     if ((ret = write(sock->fd, buf, len)) < 0)
    41     if ((ret = write(sock->fd, buf, *len)) < 0)
    40         // errno
    42         // errno
    41         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE);
    43         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE);
    42 
    44 
    43     else
    45     // bytes read
    44         // bytes read
    46     *len = ret;
    45         return ret;
    47 
       
    48     return SUCCESS;
       
    49 }
       
    50 
       
    51 static err_t sock_tcp_event_init (struct sock_stream *base_sock)
       
    52 {
       
    53     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
       
    54     
       
    55     return SUCCESS;
       
    56 }
       
    57 
       
    58 static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask)
       
    59 {
       
    60     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
       
    61     
       
    62     return SUCCESS;
    46 }
    63 }
    47 
    64 
    48 /*
    65 /*
    49  * Our sock_stream_type
    66  * Our sock_stream_type
    50  */
    67  */
    51 struct sock_stream_type sock_tcp_type = {
    68 struct sock_stream_type sock_tcp_type = {
    52     .methods.read   = &sock_tcp_read,
    69     .methods.read           = &sock_tcp_read,
    53     .methods.write  = &sock_tcp_write,
    70     .methods.write          = &sock_tcp_write,
       
    71     .methods.event_init     = &sock_tcp_event_init,
       
    72     .methods.event_enable   = &sock_tcp_event_enable,
    54 };
    73 };
       
    74 
       
    75 /*
       
    76  * Our basic socket event handler for driving our callbacks
       
    77  */
       
    78 static void sock_tcp_event (evutil_socket_t fd, short what, void *arg) 
       
    79 {
       
    80     struct sock_tcp *sock = arg;
       
    81 
       
    82     // invoke appropriate callback
       
    83     if (what & EV_READ && SOCK_TCP_BASE(sock)->cb_info->on_read)
       
    84         SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg);
       
    85 
       
    86     if (what & EV_WRITE && SOCK_TCP_BASE(sock)->cb_info->on_write)
       
    87         SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg);
       
    88 }
    55 
    89 
    56 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr)
    90 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr)
    57 {
    91 {
    58     // alloc
    92     // alloc
    59     if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL)
    93     if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL)
    73 
   107 
    74     // initialize
   108     // initialize
    75     sock->fd = fd;
   109     sock->fd = fd;
    76 
   110 
    77     // done
   111     // done
       
   112     return SUCCESS;
       
   113 }
       
   114 
       
   115 err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb)(evutil_socket_t, short, void *), void *cb_arg)
       
   116 {
       
   117     // require valid fd
       
   118     assert(sock->fd >= 0);
       
   119     
       
   120     // create new event
       
   121     if ((sock->ev = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL)
       
   122         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
       
   123 
       
   124     // ok
    78     return SUCCESS;
   125     return SUCCESS;
    79 }
   126 }
    80 
   127 
    81 err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service)
   128 err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service)
    82 {
   129 {
   135     
   182     
   136     // ok, done
   183     // ok, done
   137     return 0;    
   184     return 0;    
   138 }
   185 }
   139 
   186 
       
   187 err_t sock_tcp_set_nonblock (struct sock_tcp *sock, int nonblock)
       
   188 {
       
   189     // fcntl it
       
   190     // XXX: maintain old flags?
       
   191     if (fcntl(sock->fd, F_SETFL, nonblock ? O_NONBLOCK : 0) < 0)
       
   192         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_FCNTL);
       
   193 
       
   194     // ok
       
   195     return SUCCESS;
       
   196 }
       
   197 
       
   198 void sock_tcp_release (struct sock_tcp *sock)
       
   199 {
       
   200     // must not be connected
       
   201     assert(sock->fd < 0);
       
   202 
       
   203     // free
       
   204     free(sock);
       
   205 }
       
   206 
   140 err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err_info)
   207 err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err_info)
   141 {
   208 {
   142     struct sock_tcp *sock;
   209     struct sock_tcp *sock;
   143     err_t err;
   210     err_t err;
   144     
   211     
   162     *sock_ptr = SOCK_TCP_BASE(sock);
   229     *sock_ptr = SOCK_TCP_BASE(sock);
   163 
   230 
   164     return 0;
   231     return 0;
   165 }
   232 }
   166 
   233 
   167 void sock_tcp_release (struct sock_tcp *sock)
   234 
   168 {
       
   169     // must not be connected
       
   170     assert(sock->fd < 0);
       
   171 
       
   172     // free
       
   173     free(sock);
       
   174 }