src/sock_tcp.c
changeset 2 a834f0559939
parent 1 cf0e1bb6bcab
child 3 cc94ae754e2a
equal deleted inserted replaced
1:cf0e1bb6bcab 2:a834f0559939
    28 
    28 
    29     return write(sock->fd, buf, len);
    29     return write(sock->fd, buf, len);
    30 }
    30 }
    31 
    31 
    32 /*
    32 /*
    33  * Define our sock_stream_Type
    33  * Our sock_stream_type
       
    34  *
       
    35  * XXX: move to sock_tcp.h
    34  */
    36  */
    35 struct sock_stream_type sock_tcp_type = {
    37 struct sock_stream_type sock_tcp_type = {
    36     .methods.read   = &sock_tcp_read,
    38     .methods.read   = &sock_tcp_read,
    37     .methods.write  = &sock_tcp_write,
    39     .methods.write  = &sock_tcp_write,
    38 };
    40 };
    39 
    41 
    40 struct sock_stream* sock_tcp_new (int fd) 
    42 struct sock_tcp* sock_tcp_alloc (void)
    41 {
    43 {
    42     struct sock_tcp *sock;
    44     struct sock_tcp *sock;
    43 
    45 
    44     // alloc
    46     // alloc
    45     if ((sock = calloc(1, sizeof(*sock))) == NULL)
    47     if ((sock = calloc(1, sizeof(*sock))) == NULL)
    46         errx(1, "calloc");
    48         errx(1, "calloc");
       
    49     
       
    50     // initialize base
       
    51     sock->base.type = &sock_tcp_type;
    47 
    52 
       
    53     // done
       
    54     return sock;
       
    55 }
       
    56 
       
    57 int sock_tcp_init_fd (struct sock_tcp *sock, int fd)
       
    58 {
    48     // initialize
    59     // initialize
    49     sock->base.type = &sock_tcp_type;
       
    50     sock->fd = fd;
    60     sock->fd = fd;
    51 
    61 
    52     // done
    62     // done
    53     return SOCK_TCP_BASE(sock);
    63     return 0;
    54 }
    64 }
    55 
    65 
    56 struct sock_stream* sock_tcp_connect (const char *host, const char *service) 
    66 int sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service)
    57 {
    67 {
    58     struct addrinfo hints, *res, *r;
    68     struct addrinfo hints, *res, *r;
    59     int _err, fd = -1;
    69     int _err;
    60     
    70     
    61     // hints
    71     // hints
    62     memset(&hints, 0, sizeof(hints));
    72     memset(&hints, 0, sizeof(hints));
    63     hints.ai_family = AF_UNSPEC;
    73     hints.ai_family = AF_UNSPEC;
    64     hints.ai_socktype = SOCK_STREAM;
    74     hints.ai_socktype = SOCK_STREAM;
    65 
    75 
    66     // resolve
    76     // resolve
    67     if ((_err = getaddrinfo(host, service, &hints, &res)))
    77     if ((_err = getaddrinfo(hostname, service, &hints, &res)))
    68         errx(1, "getaddrinfo: %s", gai_strerror(_err));
    78         errx(1, "getaddrinfo: %s", gai_strerror(_err));
    69 
    79 
    70     // use
    80     // use
    71     for (r = res; r; r = r->ai_next) {
    81     for (r = res; r; r = r->ai_next) {
    72         // XXX: wrong
    82         // XXX: wrong
    73         if ((fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) < 0)
    83         if ((sock->fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) < 0)
    74             err(1, "socket");
    84             err(1, "socket");
    75 
    85 
    76         if (connect(fd, r->ai_addr, r->ai_addrlen))
    86         if (connect(sock->fd, r->ai_addr, r->ai_addrlen))
    77             err(1, "connect");
    87             err(1, "connect");
    78 
    88 
    79         break;
    89         break;
    80     }
    90     }
    81     
    91     
    82     // ensure we got some valid socket
    92     // ensure we got some valid socket
    83     if (fd < 0)
    93     if (sock->fd < 0)
    84         errx(1, "no valid socket");
    94         errx(1, "no valid socket");
    85     
    95     
    86     // ok, return sock_stream
    96     // ok, done
    87     return sock_tcp_new(fd);
    97     return 0;    
    88 }
    98 }
    89 
    99 
       
   100 // XXX: error handling
       
   101 struct sock_stream* sock_tcp_connect (const char *host, const char *service) 
       
   102 {
       
   103     struct sock_tcp *sock;
       
   104     
       
   105     // allocate
       
   106     sock = sock_tcp_alloc();
       
   107 
       
   108     // connect
       
   109     sock_tcp_init_connect(sock, host, service);
       
   110 
       
   111     // done
       
   112     return SOCK_TCP_BASE(sock);
       
   113 }