[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH v2] libc: POSIX: Eine notduerftige sys/select.h



On Sat, May 02 22:48, Kevin Wolf wrote:
> + libc: POSIX: Ein select(), das fuer Lesen per fgetc()/ungetc()
>   zusammengehackt ist, beim Schreiben immer ja und bei Fehlern immer
>   nein sagt. Dazu ein fd_set als 32-Bit-Bitmaske und passende Makros.
> ---
>  src/modules/include/sys/select.h |   74 ++++++++++++++++++++++
>  src/modules/lib/posix/select.c   |  128 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 202 insertions(+), 0 deletions(-)
>  create mode 100644 src/modules/include/sys/select.h
>  create mode 100644 src/modules/lib/posix/select.c
> 
> diff --git a/src/modules/include/sys/select.h b/src/modules/include/sys/select.h
> new file mode 100644
> index 0000000..cc53b7d
> --- /dev/null
> +++ b/src/modules/include/sys/select.h
> @@ -0,0 +1,74 @@
> +/*
> + * 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.
> + *
> + * 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_SELECT_H_
> +#define _SYS_SELECT_H_
> +
> +#include <sys/time.h>
> +#include <stdint.h>
> +
> +#ifndef CONFIG_LIBC_NO_STUBS
> +
> +/**
> + * Menge von Dateideskriptoren
> + *
> + * FIXME Irgendwann will man da sicher mehr als 32 benutzen koennen
> + */
> +typedef struct {
> +    uint32_t bits;
> +} fd_set;
> +
> +#define FD_ZERO(fdset) do { (fdset).bits = 0; } while (0)
> +#define FD_SET(fd, fdset) do { (fdset).bits |= (1 << (fd)); } while (0)
> +#define FD_CLR(fd, fdset) do { (fdset).bits &= ~(1 << (fd)); } while (0)
> +#define FD_ISSET(fd, fdset) ((fdset).bits & (1 << (fd)))
> +
> +/**
> + * Prueft, welche der gegebenen Dateideskriptoren bereit zum Lesen oder
> + * Schreiben sind oder ein Fehler fuer sie aufgetreten ist. Dateideskriptoren
> + * die nicht bereit bzw. in einem Fehlerzustand sind, werden aus der Menge
> + * entfernt.
> + *
> + * @param number_fds Nummer des hoechsten Dateideskriptors in einem der
> + * uebergebenen Mengen.
> + * @param readfds Dateideskriptoren, bei denen ueberprueft werden soll, ob sie
> + * zum Lesen bereit sind.
> + * @param writefds Dateideskriptoren, bei denen ueberprueft werden soll, ob sie
> + * zum Schreiben bereit sind.
> + * @param errfds Dateideskriptoren, bei denen ueberprueft werden soll, ob sie
> + * in einem Fehlerzustand sind.
> + * @param timeout Maximales Timeout, das gewartet werden soll, falls kein
> + * Deskriptor bereit ist. NULL fuer dauerhaftes Blockieren.
> + *
> + * @return Anzahl der Dateideskriptoren, die bereit bzw. in einem Fehlerzustand
> + * sind
> + */
> +int select(int number_fds, fd_set* readfds, fd_set* writefds,
> +    fd_set* errfds, struct timeval* timeout);
> +#endif
> +
> +#endif
> diff --git a/src/modules/lib/posix/select.c b/src/modules/lib/posix/select.c
> new file mode 100644
> index 0000000..539f555
> --- /dev/null
> +++ b/src/modules/lib/posix/select.c
> @@ -0,0 +1,128 @@
> +/*
> + * 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.
> + *
> + * 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/select.h>
> +#include <sys/time.h>
> +#include <stdio.h>
> +#include <syscall.h>
> +
> +#ifndef CONFIG_LIBC_NO_STUBS
> +/**
> + * Prueft, welche der gegebenen Dateideskriptoren bereit zum Lesen oder
> + * Schreiben sind oder ein Fehler fuer sie aufgetreten ist. Dateideskriptoren
> + * die nicht bereit bzw. in einem Fehlerzustand sind, werden aus der Menge
> + * entfernt.
> + *
> + * @param number_fds Nummer des hoechsten Dateideskriptors in einem der
> + * uebergebenen Mengen.
> + * @param readfds Dateideskriptoren, bei denen ueberprueft werden soll, ob sie
> + * zum Lesen bereit sind.
> + * @param writefds Dateideskriptoren, bei denen ueberprueft werden soll, ob sie
> + * zum Schreiben bereit sind.
> + * @param errfds Dateideskriptoren, bei denen ueberprueft werden soll, ob sie
> + * in einem Fehlerzustand sind.
> + * @param timeout Maximales Timeout, das gewartet werden soll, falls kein
> + * Deskriptor bereit ist. NULL fuer dauerhaftes Blockieren.
> + *
> + * @return Anzahl der Dateideskriptoren, die bereit bzw. in einem Fehlerzustand
> + * sind
> + */
> +int select(int number_fds, fd_set* readfds, fd_set* writefds,
> +    fd_set* errfds, struct timeval* timeout)
> +{
> +    uint32_t* rd = (uint32_t*) readfds;
> +    uint32_t* wr = (uint32_t*) writefds;
> +    uint32_t* err = (uint32_t*) errfds;
> +    int c;
> +    FILE* f;
> +    int ret;
> +
> +    uint32_t orig_rd = rd ? *rd : 0;
> +    uint32_t orig_wr = wr ? *wr : 0;
> +
> +    uint64_t timeout_tick;
> +    if (timeout != NULL) {
> +        timeout_tick = get_tick_count() + timeout->tv_sec +
> +            1000ULL * 1000ULL * timeout->tv_usec;
> +    } else {
> +        timeout_tick = (uint64_t) -1;
> +    }
> +
> +    // tyndur ist so toll, bei uns gibt es keine Fehler
> +    if (err) {
> +        *err = 0;
> +    }
> +
> +    do {
> +        int i;
> +
> +        // Wieder alles zuruecksetzen
> +        ret = 0;
> +        if (rd) {
> +            *rd = orig_rd;
> +        }
> +        if (wr) {
> +            *wr = orig_wr;
> +        }
> +
> +
> +        for (i = 0; i < 32; i++) {
> +
> +            // Versuchsweise ein Zeichen auslesen. Wenn das funktioniert, als
> +            // lesbar werten und das Zeichen schnell wieder zurueckstecken
> +            // bevor das Programm was merkt.
> +            if (rd && (*rd & (1 << i))) {
> +                f = fdopen(i, NULL);
> +
> +                if (f != NULL) {
> +                    c = fgetc(f);
> +                    if (c == 0 || c == EOF) {
> +                        *rd &= ~(1 << i);
> +                    } else {
> +                        ungetc(c, f);
> +                        ret++;
> +                    }
> +                }

Könnte man hier für else nicht sogar an err denken? ;-) Keine Ahnung ob
das was bringt...

> +            }
> +
> +            // Schreiben geht immer
> +            if (wr && (*wr & (1 << i))) {
> +                ret++;
> +            }
> +        }
> +
> +        // Busy Wait waere irgendwie auch doof
> +        if (ret == 0) {
> +            yield();
> +        }
> +
> +    } while ((ret == 0) && (timeout_tick > get_tick_count()));
> +
> +    return ret;
> +}
> +#endif

Sonst sieht das gut aus, also rein damit.

-- 
Antoine Kaufmann
<toni@xxxxxxxxxxxxxxxx>

Attachment: pgptpikzjKVuC.pgp
Description: PGP signature