On Mon, Apr 13 18:21, Kevin Wolf wrote: > + libc: POSIX: Socket-Funktionen > --- > src/include/errno.h | 12 +++ > src/modules/include/netinet/in.h | 10 ++ > src/modules/include/sys/socket.h | 99 +++++++++++++++++++ > src/modules/lib/posix/net.c | 3 + > src/modules/lib/posix/socket.c | 193 ++++++++++++++++++++++++++++++++++++++ > 5 files changed, 317 insertions(+), 0 deletions(-) > create mode 100644 src/modules/include/sys/socket.h > create mode 100644 src/modules/lib/posix/socket.c > > diff --git a/src/modules/include/sys/socket.h b/src/modules/include/sys/socket.h > new file mode 100644 > index 0000000..38d12f6 > --- /dev/null > +++ b/src/modules/include/sys/socket.h > @@ -0,0 +1,99 @@ > +/* > + * Copyright (c) 2009 The tyndur Project. All rights reserved. > + * > + * This code is derived from software contributed to the tyndur Project > + * by Kevin Wolf. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the tyndur Project > + * and its contributors. > + * 4. Neither the name of the tyndur Project nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. Hast du hier absichtlich 4 Klauseln drin? > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR > + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, > + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; > + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > +#ifndef _SYS_SOCKET_H_ > +#define _SYS_SOCKET_H_ > + > +#include <stdint.h> > +#include <sys/types.h> > + > +typedef int socklen_t; > +typedef unsigned int sa_family_t; > + > +struct sockaddr { > + sa_family_t sa_family; > + char sa_data[]; > +}; > + > +struct sockaddr_storage { > + sa_family_t ss_family; > +}; > + Zu diesen Strukturen wären ein paar Kommentare vielleich auch noch hilfreich... > +enum { > + SOCK_STREAM, > +}; > + > +enum { > + AF_INET, > +}; > + > +enum { > + IPPROTO_TCP, > + IPPROTO_UDP, > +}; > + > +/** > + * Erstellt einen Socket > + * > + * @param domain Protokollfamilie (AF_*, z.B. AF_INET fuer IPv4) > + * @param type Protokolltyp (SOCK_*, z.B. SOCK_STREAM fuer TCP) > + * @param protocol Wird ignoriert; tyndur benutzt immer das Default-Protokoll, > + * das zu domain und type passt > + * > + * @return Socketnummer. Im Fehlerfall -1 und errno wird gesetzt. > + */ > +int socket(int domain, int type, int protocol); > + > +/** > + * Verbindet einen Socket (als Client) mit einer Gegenstelle > + * > + * @param socket Socket, der verbunden werden soll > + * @param address Adresse der Gegenstelle (z.B. IP-Adresse/TCP-Port) > + * @param address_len Laenge der Adresse in Bytes > + * > + * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt. > + */ > +int connect(int socket, struct sockaddr* address, socklen_t address_len); > + > +/** > + * Liest eine Anzahl Bytes aus einem Socket > + */ > +ssize_t recv(int socket, const void *buffer, size_t length, int flags); > + > +/** > + * Sendet eine Nachricht ueber einen Socket > + */ > +ssize_t send(int socket, const void *buffer, size_t length, int flags); > + > +#endif > diff --git a/src/modules/lib/posix/net.c b/src/modules/lib/posix/net.c > index 738eae8..2a41daf 100644 > --- a/src/modules/lib/posix/net.c > +++ b/src/modules/lib/posix/net.c > @@ -29,6 +29,9 @@ > #include <netinet/in.h> > #include <network.h> > > +#include <stdlib.h> > +#include <string.h> > + > unsigned long int htonl(unsigned long int hostlong) > { > return big_endian_dword(hostlong); Hat eigentlich nichts mit der änderung zu tun, oder sehe ich das falsch? > diff --git a/src/modules/lib/posix/socket.c b/src/modules/lib/posix/socket.c > new file mode 100644 > index 0000000..61cd379 > --- /dev/null > +++ b/src/modules/lib/posix/socket.c > @@ -0,0 +1,193 @@ > +/* > + * Copyright (c) 2009 The tyndur Project. All rights reserved. > + * > + * This code is derived from software contributed to the tyndur Project > + * by Kevin Wolf. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the tyndur Project > + * and its contributors. > + * 4. Neither the name of the tyndur Project nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR > + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, > + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; > + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <sys/socket.h> > +#include <netinet/in.h> > +#include <unistd.h> > + > +#include <stdlib.h> > +#include <stdio.h> > +#include <errno.h> > + > +#include <network.h> > +#include <collections.h> > + > +struct socket { > + uint64_t id; > + struct tree_item tinfo; > + > + sa_family_t sa_family; > + FILE conn; > +}; > + > +static tree_t* sockets = NULL; > + > +/** > + * Ruft die Socketstruktur anhand des Filedeskriptors ab > + */ > +static struct socket* get_socket(int sock) > +{ > + if (sockets == NULL) { > + return NULL; > + } > + > + return tree_search(sockets, sock); > +} > + > +/** > + * Ruft die Socketstruktur anhand des Filedeskriptors ab > + */ > +static int create_socket(struct socket* socket) > +{ > + if (sockets == NULL) { > + sockets = tree_create(struct socket, tinfo, id); > + } > + > + socket->id = fileno(&socket->conn); > + tree_insert(sockets, socket); > + return socket->id; > +} > + > +/** > + * Erstellt einen Socket > + * > + * @param domain Protokollfamilie (AF_*, z.B. AF_INET fuer IPv4) > + * @param type Protokolltyp (SOCK_*, z.B. SOCK_STREAM fuer TCP) > + * @param protocol Wird ignoriert; tyndur benutzt immer das Default-Protokoll, > + * das zu domain und type passt > + * > + * @return Socketnummer. Im Fehlerfall -1 und errno wird gesetzt. > + * > + * FIXME protocol wird ignoriert > + */ > +int socket(int domain, int type, int protocol) > +{ > + int sock; > + struct socket* socket; > + > + if (domain != AF_INET) { > + errno = EAFNOSUPPORT; > + return -1; > + } > + > + if (type != SOCK_STREAM) { > + errno = EPROTOTYPE; > + return -1; > + } > + > + socket = calloc(1, sizeof(*socket)); > + socket->sa_family = domain; > + memset(&socket->conn, 0, sizeof(socket->conn)); > + > + sock = create_socket(socket); > + > + return sock; > +} > + > +/** > + * Verbindet einen Socket (als Client) mit einer Gegenstelle > + * > + * @param socket Socket, der verbunden werden soll > + * @param address Adresse der Gegenstelle (z.B. IP-Adresse/TCP-Port) > + * @param address_len Laenge der Adresse in Bytes > + * > + * @return 0 bei Erfolg. Im Fehlerfall -1 und errno wird gesetzt. > + */ > +int connect(int sock, struct sockaddr* address, socklen_t address_len) > +{ > + struct socket* socket = get_socket(sock); > + struct sockaddr_in* inet_addr = (struct sockaddr_in*) address; > + char* ip_string; > + uint16_t port; > + char* path; > + int ret = 0; > + FILE* conn; > + > + if (socket == NULL) { > + errno = EBADF; > + return -1; > + } > + > + if (address->sa_family != socket->sa_family) { > + errno = EAFNOSUPPORT; > + return -1; > + } > + > + ip_string = ip_to_string(inet_addr->sin_addr); > + port = big_endian_word(inet_addr->sin_port); > + if (asprintf(&path, "tcpip:/%s:%d", ip_string, port) < 0) > + { In dem fall ist aber das free(path) eher ungeschickt. > + errno = ENOMEM; > + ret = -1; > + goto out; > + } > + > + conn = fopen(path, "r+"); > + if (conn == NULL) { > + errno = ETIMEDOUT; > + ret = -1; > + goto out; > + } > + > + // FIXME Boeser Hack > + memcpy(&socket->conn, conn, sizeof(*conn)); > + free(conn); Uäh... ;-) > + > +out: > + free(ip_string); > + free(path); > + > + return 0; > +} > + > +/** > + * Liest eine Anzahl Bytes aus einem Socket > + * > + * TODO Mit den Flags was sinnvolles machen > + */ > +ssize_t recv(int socket, const void *buffer, size_t length, int flags) > +{ > + return read(socket, (void*) buffer, length); > +} > + > +/** > + * Sendet eine Anzahl Bytes ueber einen Socket > + * > + * TODO Mit den Flags was sinnvolles machen > + */ > +ssize_t send(int socket, const void *buffer, size_t length, int flags) > +{ > + return write(socket, buffer, length); > +} Was mache ich eigentlich mit so einen Socket wenn ich genug davon habe? Kann ich das dann irgendwie loswerden? -- Antoine Kaufmann <toni@xxxxxxxxxxxxxxxx>
Attachment:
pgpmVTr87g9tp.pgp
Description: PGP signature