1*640235e2SEnji Cooper /* 2*640235e2SEnji Cooper * Based on the OpenBSD test 3*640235e2SEnji Cooper * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org> 4*640235e2SEnji Cooper * 5*640235e2SEnji Cooper * Permission to use, copy, modify, and distribute this software for any 6*640235e2SEnji Cooper * purpose with or without fee is hereby granted, provided that the above 7*640235e2SEnji Cooper * copyright notice and this permission notice appear in all copies. 8*640235e2SEnji Cooper * 9*640235e2SEnji Cooper * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*640235e2SEnji Cooper * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*640235e2SEnji Cooper * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*640235e2SEnji Cooper * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*640235e2SEnji Cooper * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*640235e2SEnji Cooper * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*640235e2SEnji Cooper * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*640235e2SEnji Cooper */ 17*640235e2SEnji Cooper 18*640235e2SEnji Cooper #include <sys/cdefs.h> 19*640235e2SEnji Cooper __RCSID("$NetBSD: t_open_memstream.c,v 1.2 2014/10/19 11:17:43 justin Exp $"); 20*640235e2SEnji Cooper 21*640235e2SEnji Cooper #include <atf-c.h> 22*640235e2SEnji Cooper #include <err.h> 23*640235e2SEnji Cooper #include <stdio.h> 24*640235e2SEnji Cooper #include <stdlib.h> 25*640235e2SEnji Cooper #include <string.h> 26*640235e2SEnji Cooper #include <unistd.h> 27*640235e2SEnji Cooper 28*640235e2SEnji Cooper ATF_TC(test_open_memstream); 29*640235e2SEnji Cooper ATF_TC_HEAD(test_open_memstream, tc) 30*640235e2SEnji Cooper { 31*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", "Test open_memstream functionality"); 32*640235e2SEnji Cooper } 33*640235e2SEnji Cooper 34*640235e2SEnji Cooper #define OFFSET 16384 35*640235e2SEnji Cooper 36*640235e2SEnji Cooper const char start[] = "start"; 37*640235e2SEnji Cooper const char hello[] = "hello"; 38*640235e2SEnji Cooper 39*640235e2SEnji Cooper ATF_TC_BODY(test_open_memstream, tc) 40*640235e2SEnji Cooper { 41*640235e2SEnji Cooper FILE *fp; 42*640235e2SEnji Cooper char *buf = (char *)0xff; 43*640235e2SEnji Cooper size_t size = 0; 44*640235e2SEnji Cooper off_t off; 45*640235e2SEnji Cooper int i; 46*640235e2SEnji Cooper 47*640235e2SEnji Cooper fp = open_memstream(&buf, &size); 48*640235e2SEnji Cooper ATF_REQUIRE(fp != NULL); 49*640235e2SEnji Cooper 50*640235e2SEnji Cooper off = ftello(fp); 51*640235e2SEnji Cooper ATF_CHECK(off == 0); 52*640235e2SEnji Cooper 53*640235e2SEnji Cooper ATF_CHECK(fflush(fp) == 0); 54*640235e2SEnji Cooper ATF_CHECK(size == 0); 55*640235e2SEnji Cooper ATF_CHECK(buf != (char *)0xff); 56*640235e2SEnji Cooper ATF_CHECK(fseek(fp, -6, SEEK_SET) == -1); 57*640235e2SEnji Cooper ATF_CHECK(fseek(fp, OFFSET, SEEK_SET) == 0); 58*640235e2SEnji Cooper ATF_CHECK(fprintf(fp, hello) != EOF); 59*640235e2SEnji Cooper ATF_CHECK(fflush(fp) != EOF); 60*640235e2SEnji Cooper ATF_CHECK(size == OFFSET + sizeof(hello)-1); 61*640235e2SEnji Cooper ATF_CHECK(fseek(fp, 0, SEEK_SET) == 0); 62*640235e2SEnji Cooper ATF_CHECK(fprintf(fp, start) != EOF); 63*640235e2SEnji Cooper ATF_CHECK(fflush(fp) != EOF); 64*640235e2SEnji Cooper ATF_CHECK(size == sizeof(start)-1); 65*640235e2SEnji Cooper 66*640235e2SEnji Cooper /* Needed for sparse files */ 67*640235e2SEnji Cooper ATF_CHECK(strncmp(buf, start, sizeof(start)-1) == 0); 68*640235e2SEnji Cooper for (i = sizeof(start)-1; i < OFFSET; i++) 69*640235e2SEnji Cooper ATF_CHECK(buf[i] == '\0'); 70*640235e2SEnji Cooper 71*640235e2SEnji Cooper ATF_CHECK(memcmp(buf + OFFSET, hello, sizeof(hello)-1) == 0); 72*640235e2SEnji Cooper 73*640235e2SEnji Cooper /* verify that simply seeking past the end doesn't increase the size */ 74*640235e2SEnji Cooper ATF_CHECK(fseek(fp, 100, SEEK_END) == 0); 75*640235e2SEnji Cooper ATF_CHECK(fflush(fp) != EOF); 76*640235e2SEnji Cooper ATF_CHECK(size == OFFSET + sizeof(hello)-1); 77*640235e2SEnji Cooper ATF_CHECK(fseek(fp, 8, SEEK_SET) == 0); 78*640235e2SEnji Cooper ATF_CHECK(ftell(fp) == 8); 79*640235e2SEnji Cooper 80*640235e2SEnji Cooper /* Try to seek backward */ 81*640235e2SEnji Cooper ATF_CHECK(fseek(fp, -1, SEEK_CUR) == 0); 82*640235e2SEnji Cooper ATF_CHECK(ftell(fp) == 7); 83*640235e2SEnji Cooper ATF_CHECK(fseek(fp, 5, SEEK_CUR) == 0); 84*640235e2SEnji Cooper ATF_CHECK(fclose(fp) != EOF); 85*640235e2SEnji Cooper ATF_CHECK(size == 12); 86*640235e2SEnji Cooper 87*640235e2SEnji Cooper free(buf); 88*640235e2SEnji Cooper } 89*640235e2SEnji Cooper 90*640235e2SEnji Cooper ATF_TP_ADD_TCS(tp) 91*640235e2SEnji Cooper { 92*640235e2SEnji Cooper 93*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, test_open_memstream); 94*640235e2SEnji Cooper 95*640235e2SEnji Cooper return atf_no_error(); 96*640235e2SEnji Cooper } 97