On Sun, Jul 12 20:17, Kevin Wolf wrote: > + libc: POSIX: TCP-Server-Sockets > > Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx> > --- > src/modules/include/sys/socket.h | 25 ++++++++ > src/modules/lib/posix/socket.c | 116 +++++++++++++++++++++++++++++++++++++- > 2 files changed, 139 insertions(+), 2 deletions(-) > > diff --git a/src/modules/include/sys/socket.h b/src/modules/include/sys/socket.h > index b58c58c..1d19b5a 100644 > --- a/src/modules/include/sys/socket.h > +++ b/src/modules/include/sys/socket.h > @@ -119,4 +119,29 @@ ssize_t recvfrom(int socket, const void *buffer, size_t length, int flags, > ssize_t sendto(int socket, const void *buffer, size_t length, int flags, > const struct sockaddr* to, socklen_t to_len); > > +/** > + * Bindet einen Socket an einen bestimmten TCP-Port (bzw. allgemein an eine > + * Adresse) > + * > + * @param sock Socket, dem die Adresse zugewiesen werden soll > + * @param address Adresse fuer den Socket (Fuer IP: struct sockaddr_in) > + * @param address_len Groesse der Adressstruktur > + * > + * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt. > + */ > +int bind(int sock, const struct sockaddr* address, socklen_t address_len); > + > +/** > + * Benutzt einen Socket, um auf eingehende Verbindungen zu warten > + * > + * @param sock Socket, der auf Verbindungen warten soll > + * @param backlog Wird unter tyndur ignoriert > + */ > +int listen(int sock, int backlog); Hier wäre ein Kommentar zum Rückgabewert ganz nett. > + > +/** > + * Nimmt eine eingehende Verbindung an > + */ > +int accept(int sock, struct sockaddr* address, socklen_t* address_len); Dito > + > #endif > diff --git a/src/modules/lib/posix/socket.c b/src/modules/lib/posix/socket.c > index 9a4d0e4..65194de 100644 > --- a/src/modules/lib/posix/socket.c > +++ b/src/modules/lib/posix/socket.c > @@ -42,8 +42,10 @@ struct socket { > uint64_t id; > struct tree_item tinfo; > > - sa_family_t sa_family; > - struct lostio_internal_file conn; > + sa_family_t sa_family; > + struct lostio_internal_file conn; > + struct sockaddr* local_address; Hm ist da noch ein trailing space, oder habe ich den aus versehen reingemacht? ;-) > + FILE* listen_file; > }; > > static tree_t* sockets = NULL; > @@ -169,6 +171,116 @@ out_ip_string: > } > > /** > + * Bindet einen Socket an einen bestimmten TCP-Port (bzw. allgemein an eine > + * Adresse) > + * > + * @param sock Socket, dem die Adresse zugewiesen werden soll > + * @param address Adresse fuer den Socket (Fuer IP: struct sockaddr_in) > + * @param address_len Groesse der Adressstruktur > + * > + * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt. > + */ > +int bind(int sock, const struct sockaddr* address, socklen_t address_len) > +{ > + struct socket* socket = get_socket(sock); > + > + if (socket == NULL) { > + errno = EBADF; > + return -1; > + } > + > + // FIXME Das wird beim Schliessen geleakt > + socket->local_address = malloc(address_len); > + memcpy(socket->local_address, address, address_len); > + > + return 0; > +} > + > +/** > + * Benutzt einen Socket, um auf eingehende Verbindungen zu warten > + * > + * @param sock Socket, der auf Verbindungen warten soll > + * @param backlog Wird unter tyndur ignoriert > + */ > +int listen(int sock, int backlog) > +{ > + char* path; > + uint16_t port; > + struct socket* socket = get_socket(sock); > + struct sockaddr_in* inet_addr; > + > + if (socket == NULL) { > + errno = EBADF; > + return -1; > + } Hier müsste man doch prüfen, ob es wirklich tcpip ist in der sockaddr, oder wenigstens address_len prüfen (Das ja hier noch garnicht existiert, wie ich grad feststelle, bäh, alles d00f *g*). > + > + inet_addr = (struct sockaddr_in*) socket->local_address; > + port = big_endian_word(inet_addr->sin_port); > + if (asprintf(&path, "tcpip:/tcp-listen/:%d", port) < 1) { > + errno = ENOMEM; > + return -1; > + } > + > + socket->listen_file = fopen(path, "r"); Wäre da ein w+ nicht einleuchtender? r sollte doch keine Datei erstellen... > + free(path); > + if (socket->listen_file == NULL) { > + errno = EACCES; > + return -1; > + } > + > + return 0; > +} > + > +/** > + * Nimmt eine eingehende Verbindung an > + */ > +int accept(int sock, struct sockaddr* address, socklen_t* address_len) > +{ > + char buf[64]; > + int clientsock; > + struct socket* clientsocket; > + struct lostio_internal_file* conn; > + > + struct socket* socket = get_socket(sock); > + > + if (socket == NULL) { > + errno = EBADF; > + return -1; > + } > + > + if (socket->listen_file == NULL) { > + errno = EINVAL; > + return -1; > + } > + > + if (fgets(buf, sizeof(buf), socket->listen_file) == NULL) { > + errno = EAGAIN; > + return -1; > + } > + > + clientsocket = calloc(1, sizeof(*clientsocket)); > + clientsocket->sa_family = AF_INET; > + clientsock = create_socket(socket); > + > + conn = (struct lostio_internal_file*) fopen(buf, "r+"); > + if (conn == NULL) { > + free(socket); > + errno = EAGAIN; > + return -1; > + } > + setvbuf((FILE*)conn, NULL, _IONBF, 0); > + > + // FIXME Boeser Hack > + memcpy(&socket->conn, conn, sizeof(*conn)); > + free(conn); > + > + // TODO Adresse aus buf rausfummeln > + *address_len = 0; > + > + return clientsock; > +} > + > +/** > * Liest eine Anzahl Bytes aus einem Socket > * > * TODO Mit den Flags was sinnvolles machen -- Antoine Kaufmann <toni@xxxxxxxxxxxxxxxx>
Attachment:
pgp40ojJFLrfy.pgp
Description: PGP signature