root/usr/src/test/libc-tests/tests/stdio/fmemopentest.c
/*
 * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

const char *
_umem_debug_init(void)
{
        return ("default,verbose");
}

const char *
_umem_logging_init(void)
{
        return ("fail,contents");
}

int
simpletest(void)
{
        FILE    *s1, *s2;
        char     string[] = "fmemopen test string!";
        char     buffer[1024], *buf = NULL;
        size_t   len;
        int      c, failures = 0;

        s1 = fmemopen(string, strlen(string) + 1, "r");
        if (s1 == NULL) {
                warn("unable to open a stream s1");
                return (1);
        }

        s2 = fmemopen(buf, 22, "w+");
        if (s2 == NULL) {
                warn("unable to create a stream s2");
                (void) fclose(s1);
                return (1);
        }

        while ((c = fgetc(s1)) != EOF)
                (void) fputc(c, s2);

        if (ftell(s2) != strlen(string) + 1) {
                warnx("failed copy test (1)");
                failures++;
        }
        (void) fclose(s1);

        (void) fseek(s2, 0, SEEK_SET);
        if (ftell(s2) != 0) {
                warnx("failed seek test (2)");
                failures++;
        }

        len = fread(buffer, 1, sizeof(buffer) - 1, s2);
        if (len != strlen(string) + 1) {
                warnx("failed read test (3) %zu != %zu",
                    len, strlen(string) + 1);
                failures++;
        }

        return (failures);
}

int
updatetest(void)
{
        FILE    *s1;
        char     string[] = "hello\0 test number 2";
        char     buffer[256];
        size_t   len;
        int      failures = 0;

        s1 = fmemopen(string, 19, "a+");
        if (s1 == NULL)
                return (1);

        len = fwrite(" world", 1, 6, s1);
        if (len != 6) {
                warnx("failed write test (4)");
                failures++;
        }

        (void) fseek(s1, 0, SEEK_SET);
        if (ftell(s1) != 0) {
                warnx("failed seek test (5)");
                failures++;
        }

        len = fread(buffer, 1, sizeof(buffer) - 1, s1);
        if (strncmp(string, buffer, len)) {
                warnx("failed compare test (6)");
                failures++;
        }

        if (strcmp(string, "hello world")) {
                warnx("failed compare test (7)");
                failures++;
        }

        if (strcmp(string + strlen(string) + 1, "number 2")) {
                warnx("failed compare test (8)");
                failures++;
        }

        return (failures);
}

int
writetest(void)
{
        FILE    *s1;
        char     string[] = "super test number 3";
        char     buffer[256];
        size_t   len, slen;
        int      failures = 0;

        slen = strlen(string) + 1;

        s1 = fmemopen(string, slen, "w");
        if (s1 == NULL)
                return (1);

        len = fwrite("short", 1, 5, s1);
        if (len != strlen("short")) {
                warnx("failed write test (9)");
                failures++;
        }
        (void) fclose(s1);

        s1 = fmemopen(string, slen, "r");
        if (s1 == NULL) {
                warnx("failed open test (10)");
                failures++;
        }

        len = fread(buffer, 1, sizeof(buffer) - 1, s1);
        if (strncmp(string, buffer, len)) {
                warnx("failed compare test (11)");
                failures++;
        }

        if (strcmp(string, "short")) {
                warnx("failed compare test (12)");
                failures++;
        }

        if (strcmp(string + strlen(string) + 1, "test number 3")) {
                warnx("failed compare test (13)");
                failures++;
        }

        return (failures);
}

int
seektest(void)
{
        FILE    *s1;
        char     string[] = "long string for testing seek";
        size_t   slen;
        int      failures = 0;

        slen = strlen(string) + 1;

        s1 = fmemopen(string, slen, "r");
        if (s1 == NULL)
                return (1);

        if (fseek(s1, 8, SEEK_SET) != 0) {
                warnx("failed to fseek. (14)");
                failures++;
        }

        if (ftell(s1) != 8) {
                warnx("failed seek test. (15)");
                failures++;
        }

        /* Try to seek backward */
        if (fseek(s1, -1, SEEK_CUR) != 0) {
                warnx("failed to fseek. (16)");
                failures++;
        }

        if (ftell(s1) != 7) {
                warnx("failed seeking backward. (17)");
                failures++;
        }

        return (failures);
}

int
main(void)
{
        int      failures = 0;

        failures += simpletest();
        failures += updatetest();
        failures += writetest();
        failures += seektest();

        return (failures);
}