src/sock_tcp.c
changeset 12 4147fae232d9
parent 11 14e79683c48c
child 21 0911d0b828d4
equal deleted inserted replaced
11:14e79683c48c 12:4147fae232d9
    16 static void sock_tcp_event_handler (evutil_socket_t fd, short what, void *arg) 
    16 static void sock_tcp_event_handler (evutil_socket_t fd, short what, void *arg) 
    17 {
    17 {
    18     struct sock_tcp *sock = arg;
    18     struct sock_tcp *sock = arg;
    19 
    19 
    20     // invoke appropriate callback
    20     // invoke appropriate callback
    21     if (what & EV_READ && SOCK_TCP_BASE(sock)->cb_info->on_read)
    21     sock_stream_invoke_callbacks(SOCK_TCP_BASE(sock), what);
    22         SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg);
       
    23 
       
    24     if (what & EV_WRITE && SOCK_TCP_BASE(sock)->cb_info->on_write)
       
    25         SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg);
       
    26 }
    22 }
    27 
    23 
    28 /*
    24 /*
    29  * Our sock_stream_methods.read method
    25  * Our sock_stream_methods.read method
    30  */
    26  */
    31 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len)
    27 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len)
    32 {
    28 {
    33     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    29     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    34     int ret;
    30     int ret;
    35     
    31     
    36     // map directly to read(2)
    32     // read(), and detect non-EAGAIN or EOF
    37     if ((ret = read(sock->fd, buf, *len)) < 0)
    33     if ((ret = read(sock->fd, buf, *len)) < 0 && errno != EAGAIN)
    38         // errno
    34         // unexpected error
    39         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ);
    35         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ);
    40 
    36     
    41     // bytes read
    37     else if (ret == 0)
    42     *len = ret;
    38         // EOF
    43 
    39         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_READ_EOF);
       
    40 
       
    41 
       
    42     if (ret < 0) {
       
    43         // EAGAIN -> zero bytes
       
    44         *len = 0;
       
    45 
       
    46     } else {
       
    47         // normal -> bytes read
       
    48         *len = ret;
       
    49     }
       
    50 
       
    51     // ok
    44     return SUCCESS;
    52     return SUCCESS;
    45 }
    53 }
    46 
    54 
    47 /*
    55 /*
    48  * Our sock_stream_methods.write method
    56  * Our sock_stream_methods.write method
    50 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len)
    58 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len)
    51 {
    59 {
    52     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    60     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    53     int ret;
    61     int ret;
    54     
    62     
    55     // map directly to write(2)
    63     // write(), and detect non-EAGAIN or EOF
    56     if ((ret = write(sock->fd, buf, *len)) < 0)
    64     if ((ret = write(sock->fd, buf, *len)) < 0 && errno != EAGAIN)
    57         // errno
    65         // unexpected error
    58         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE);
    66         RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE);
    59 
    67     
    60     // bytes read
    68     else if (ret == 0)
    61     *len = ret;
    69         // EOF
       
    70         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_WRITE_EOF);
       
    71 
       
    72 
       
    73     if (ret < 0) {
       
    74         // EAGAIN -> zero bytes
       
    75         *len = 0;
       
    76 
       
    77     } else {
       
    78         // normal -> bytes read
       
    79         *len = ret;
       
    80     }
    62 
    81 
    63     return SUCCESS;
    82     return SUCCESS;
    64 }
    83 }
    65 
    84 
    66 static err_t sock_tcp_event_init (struct sock_stream *base_sock)
    85 static err_t sock_tcp_event_init (struct sock_stream *base_sock)
    81 }
   100 }
    82 
   101 
    83 static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask)
   102 static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask)
    84 {
   103 {
    85     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
   104     struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
    86 
   105     
       
   106     // implemented in sock_tcp_add_event
       
   107     return sock_tcp_add_event(sock, mask);
       
   108 }
       
   109 
       
   110 /*
       
   111  * Our sock_stream_type
       
   112  */
       
   113 struct sock_stream_type sock_tcp_type = {
       
   114     .methods.read           = &sock_tcp_read,
       
   115     .methods.write          = &sock_tcp_write,
       
   116     .methods.event_init     = &sock_tcp_event_init,
       
   117     .methods.event_enable   = &sock_tcp_event_enable,
       
   118 };
       
   119 
       
   120 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr)
       
   121 {
       
   122     // alloc
       
   123     if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL)
       
   124         return ERR_CALLOC;
       
   125     
       
   126     // initialize base with sock_tcp_type
       
   127     sock_stream_init(SOCK_TCP_BASE(*sock_ptr), &sock_tcp_type);
       
   128 
       
   129     // done
       
   130     return SUCCESS;
       
   131 }
       
   132 
       
   133 err_t sock_tcp_init_fd (struct sock_tcp *sock, int fd)
       
   134 {
       
   135     // valid fd -XXX: err instead?
       
   136     assert(fd >= 0);
       
   137 
       
   138     // initialize
       
   139     sock->fd = fd;
       
   140 
       
   141     // done
       
   142     return SUCCESS;
       
   143 }
       
   144 
       
   145 err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb)(evutil_socket_t, short, void *), void *cb_arg)
       
   146 {
       
   147     // require valid fd
       
   148     assert(sock->fd >= 0);
       
   149 
       
   150     // this is initialization
       
   151     assert(sock->ev_read == NULL && sock->ev_write == NULL);
       
   152     
       
   153     // create new event
       
   154     if ((sock->ev_read = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL)
       
   155         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
       
   156 
       
   157     if ((sock->ev_write = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_WRITE, ev_cb, cb_arg)) == NULL)
       
   158         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
       
   159 
       
   160     // ok
       
   161     return SUCCESS;
       
   162 }
       
   163 
       
   164 err_t sock_tcp_add_event (struct sock_tcp *sock, short mask)
       
   165 {
    87     // just add the appropraite events
   166     // just add the appropraite events
    88     if (mask & EV_READ && event_add(sock->ev_read, NULL))
   167     if (mask & EV_READ && event_add(sock->ev_read, NULL))
    89         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
   168         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
    90  
   169  
    91     if (mask & EV_WRITE && event_add(sock->ev_write, NULL))
   170     if (mask & EV_WRITE && event_add(sock->ev_write, NULL))
    92         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
   171         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
    93     
   172     
    94     // done
   173     // done
    95     return SUCCESS;
       
    96 }
       
    97 
       
    98 /*
       
    99  * Our sock_stream_type
       
   100  */
       
   101 struct sock_stream_type sock_tcp_type = {
       
   102     .methods.read           = &sock_tcp_read,
       
   103     .methods.write          = &sock_tcp_write,
       
   104     .methods.event_init     = &sock_tcp_event_init,
       
   105     .methods.event_enable   = &sock_tcp_event_enable,
       
   106 };
       
   107 
       
   108 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr)
       
   109 {
       
   110     // alloc
       
   111     if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL)
       
   112         return ERR_CALLOC;
       
   113     
       
   114     // initialize base with sock_tcp_type
       
   115     sock_stream_init(SOCK_TCP_BASE(*sock_ptr), &sock_tcp_type);
       
   116 
       
   117     // done
       
   118     return SUCCESS;
       
   119 }
       
   120 
       
   121 err_t sock_tcp_init_fd (struct sock_tcp *sock, int fd)
       
   122 {
       
   123     // valid fd -XXX: err instead?
       
   124     assert(fd >= 0);
       
   125 
       
   126     // initialize
       
   127     sock->fd = fd;
       
   128 
       
   129     // done
       
   130     return SUCCESS;
       
   131 }
       
   132 
       
   133 err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb)(evutil_socket_t, short, void *), void *cb_arg)
       
   134 {
       
   135     // require valid fd
       
   136     assert(sock->fd >= 0);
       
   137 
       
   138     // this is initialization
       
   139     assert(sock->ev_read == NULL && sock->ev_write == NULL);
       
   140     
       
   141     // create new event
       
   142     if ((sock->ev_read = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL)
       
   143         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
       
   144 
       
   145     if ((sock->ev_write = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_WRITE, ev_cb, cb_arg)) == NULL)
       
   146         return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
       
   147 
       
   148     // ok
       
   149     return SUCCESS;
   174     return SUCCESS;
   150 }
   175 }
   151 
   176 
   152 err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service)
   177 err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service)
   153 {
   178 {