prog.cpp | fopencookie + tcp

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

ssize_t tcp_read(void *token, char *buf, size_t n);
ssize_t tcp_write(void *token, const char *buf, size_t n);
int tcp_close(void *token);
FILE* tcp_connect(const char *host, const char *port);

int main() {
    FILE* f;
    char buf[256];
    f = tcp_connect("www.google.com", "80");
    fputs("HEAD / HTTP/1.1\r\nHost: www.google.com\r\n\r\n", f);
    fflush(f);
    fgets(buf, 256, f);
    fclose(f);
    fputs(buf, stdout);
}

FILE* tcp_connect(const char *host, const char *port) {
    int *sock;
    struct addrinfo hints, *ai;
    FILE* stream;
    cookie_io_functions_t funcs;
    sock = (int*)malloc(sizeof(int));
    if (sock == 0) return 0;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    if (getaddrinfo(host, port, &hints, &ai))
        { free(sock); return 0; }
    if ((*sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1)
        { free(sock); freeaddrinfo(ai); return 0; }
    if (connect(*sock, ai->ai_addr, ai->ai_addrlen))
        { free(sock); freeaddrinfo(ai); return 0; }
    freeaddrinfo(ai);
    funcs.read = tcp_read;
    funcs.write = tcp_write;
    funcs.seek = 0;
    funcs.close = tcp_close;
    stream = fopencookie(sock, "r+", funcs);
    if (stream == 0) tcp_close(sock);
    return stream;
}

ssize_t tcp_read(void *token, char *buf, size_t n) {
    return recv(*(int*)token, buf, n, 0);
}

ssize_t tcp_write(void *token, const char *buf, size_t n) {
    return send(*(int*)token, buf, n, 0);
}

int tcp_close(void *token) {
    int ret = shutdown(*(int*)token, SHUT_RDWR);
    ret |= close(*(int*)token);
    free(token);
    return ret;
}
Comments