1272343Sngie/* $NetBSD: t_dir.c,v 1.6 2013/10/19 17:45:00 christos Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 2010 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * Redistribution and use in source and binary forms, with or without 8272343Sngie * modification, are permitted provided that the following conditions 9272343Sngie * are met: 10272343Sngie * 1. Redistributions of source code must retain the above copyright 11272343Sngie * notice, this list of conditions and the following disclaimer. 12272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 13272343Sngie * notice, this list of conditions and the following disclaimer in the 14272343Sngie * documentation and/or other materials provided with the distribution. 15272343Sngie * 16272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26272343Sngie * POSSIBILITY OF SUCH DAMAGE. 27272343Sngie */ 28272343Sngie 29272343Sngie#include <atf-c.h> 30272343Sngie 31272343Sngie#include <assert.h> 32272343Sngie#include <dirent.h> 33272343Sngie#include <err.h> 34272343Sngie#include <fcntl.h> 35272343Sngie#include <stdio.h> 36272343Sngie#include <stdlib.h> 37272343Sngie#include <string.h> 38272343Sngie#include <unistd.h> 39272343Sngie 40272343Sngie#include <sys/stat.h> 41272343Sngie 42272343SngieATF_TC(seekdir_basic); 43272343SngieATF_TC_HEAD(seekdir_basic, tc) 44272343Sngie{ 45272343Sngie 46272343Sngie atf_tc_set_md_var(tc, "descr", "Check telldir(3) and seekdir(3) " 47272343Sngie "for correct behavior (PR lib/24324)"); 48272343Sngie} 49272343Sngie 50272343SngieATF_TC_BODY(seekdir_basic, tc) 51272343Sngie{ 52272343Sngie DIR *dp; 53272343Sngie char *wasname; 54272343Sngie struct dirent *entry; 55272343Sngie long here; 56272343Sngie 57272343Sngie mkdir("t", 0755); 58272343Sngie creat("t/a", 0600); 59272343Sngie creat("t/b", 0600); 60272343Sngie creat("t/c", 0600); 61272343Sngie 62272343Sngie dp = opendir("t"); 63272343Sngie if ( dp == NULL) 64272343Sngie atf_tc_fail("Could not open temp directory."); 65272343Sngie 66272343Sngie /* skip two for . and .. */ 67272343Sngie entry = readdir(dp); 68272343Sngie entry = readdir(dp); 69272343Sngie 70272343Sngie /* get first entry */ 71272343Sngie entry = readdir(dp); 72272343Sngie here = telldir(dp); 73272343Sngie 74272343Sngie /* get second entry */ 75272343Sngie entry = readdir(dp); 76272343Sngie wasname = strdup(entry->d_name); 77272343Sngie if (wasname == NULL) 78272343Sngie atf_tc_fail("cannot allocate memory"); 79272343Sngie 80272343Sngie /* get third entry */ 81272343Sngie entry = readdir(dp); 82272343Sngie 83272343Sngie /* try to return to the position after the first entry */ 84272343Sngie seekdir(dp, here); 85272343Sngie entry = readdir(dp); 86272343Sngie 87272343Sngie if (entry == NULL) 88272343Sngie atf_tc_fail("entry 1 not found"); 89272343Sngie if (strcmp(entry->d_name, wasname) != 0) 90272343Sngie atf_tc_fail("1st seekdir found wrong name"); 91272343Sngie 92272343Sngie /* try again, and throw in a telldir() for good measure */ 93272343Sngie seekdir(dp, here); 94272343Sngie here = telldir(dp); 95272343Sngie entry = readdir(dp); 96272343Sngie 97272343Sngie if (entry == NULL) 98272343Sngie atf_tc_fail("entry 2 not found"); 99272343Sngie if (strcmp(entry->d_name, wasname) != 0) 100272343Sngie atf_tc_fail("2nd seekdir found wrong name"); 101272343Sngie 102272343Sngie /* One more time, to make sure that telldir() doesn't affect result */ 103272343Sngie seekdir(dp, here); 104272343Sngie entry = readdir(dp); 105272343Sngie 106272343Sngie if (entry == NULL) 107272343Sngie atf_tc_fail("entry 3 not found"); 108272343Sngie if (strcmp(entry->d_name, wasname) != 0) 109272343Sngie atf_tc_fail("3rd seekdir found wrong name"); 110272343Sngie 111272343Sngie closedir(dp); 112272343Sngie} 113272343Sngie 114272343SngieATF_TC(telldir_leak); 115272343SngieATF_TC_HEAD(telldir_leak, tc) 116272343Sngie{ 117272343Sngie 118272343Sngie atf_tc_set_md_var(tc, "descr", 119272343Sngie "Check telldir(3) for memory leakage (PR lib/24324)"); 120272343Sngie} 121272343Sngie 122272343SngieATF_TC_BODY(telldir_leak, tc) 123272343Sngie{ 124272343Sngie DIR *dp; 125272343Sngie char *memused; 126272343Sngie int i; 127272343Sngie int oktouse = 4096; 128272343Sngie 129272343Sngie dp = opendir("."); 130272343Sngie if (dp == NULL) 131272343Sngie atf_tc_fail("Could not open current directory"); 132272343Sngie 133272343Sngie (void)telldir(dp); 134272343Sngie memused = sbrk(0); 135272343Sngie closedir(dp); 136272343Sngie 137272343Sngie for (i = 0; i < 1000; i++) { 138272343Sngie dp = opendir("."); 139272343Sngie if (dp == NULL) 140272343Sngie atf_tc_fail("Could not open current directory"); 141272343Sngie 142272343Sngie (void)telldir(dp); 143272343Sngie closedir(dp); 144272343Sngie 145272343Sngie if ((char *)sbrk(0) - memused > oktouse) { 146272343Sngie (void)printf("Used %td extra bytes for %d telldir " 147272343Sngie "calls", ((char *)sbrk(0) - memused), i); 148272343Sngie oktouse = (char *)sbrk(0) - memused; 149272343Sngie } 150272343Sngie } 151272343Sngie if (oktouse > 4096) { 152272343Sngie atf_tc_fail("Failure: leaked %d bytes", oktouse); 153272343Sngie } else { 154272343Sngie (void)printf("OK: used %td bytes\n", (char *)(sbrk(0))-memused); 155272343Sngie } 156272343Sngie} 157272343Sngie 158272343SngieATF_TP_ADD_TCS(tp) 159272343Sngie{ 160272343Sngie 161272343Sngie ATF_TP_ADD_TC(tp, seekdir_basic); 162272343Sngie ATF_TP_ADD_TC(tp, telldir_leak); 163272343Sngie 164272343Sngie return atf_no_error(); 165272343Sngie} 166