1239160Sjilles/*- 2239160Sjilles * Copyright (c) 2012 Jilles Tjoelker 3239160Sjilles * All rights reserved. 4239160Sjilles * 5239160Sjilles * Redistribution and use in source and binary forms, with or without 6239160Sjilles * modification, are permitted provided that the following conditions 7239160Sjilles * are met: 8239160Sjilles * 1. Redistributions of source code must retain the above copyright 9239160Sjilles * notice, this list of conditions and the following disclaimer. 10239160Sjilles * 2. Redistributions in binary form must reproduce the above copyright 11239160Sjilles * notice, this list of conditions and the following disclaimer in the 12239160Sjilles * documentation and/or other materials provided with the distribution. 13239160Sjilles * 14239160Sjilles * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15239160Sjilles * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16239160Sjilles * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17239160Sjilles * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18239160Sjilles * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19239160Sjilles * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20239160Sjilles * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21239160Sjilles * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22239160Sjilles * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23239160Sjilles * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24239160Sjilles * SUCH DAMAGE. 25239160Sjilles */ 26239160Sjilles 27239160Sjilles/* 28239160Sjilles * Limited test program for nftw() as specified by IEEE Std. 1003.1-2008. 29239160Sjilles */ 30239160Sjilles 31239160Sjilles#include <sys/cdefs.h> 32239160Sjilles__FBSDID("$FreeBSD$"); 33239160Sjilles 34239160Sjilles#include <sys/wait.h> 35239160Sjilles 36239160Sjilles#include <assert.h> 37253403Skevlo#include <err.h> 38239160Sjilles#include <errno.h> 39239160Sjilles#include <fcntl.h> 40239160Sjilles#include <ftw.h> 41239160Sjilles#include <stdio.h> 42239160Sjilles#include <stdlib.h> 43239160Sjilles#include <string.h> 44239160Sjilles#include <spawn.h> 45253403Skevlo#include <unistd.h> 46239160Sjilles 47239160Sjillesextern char **environ; 48239160Sjilles 49239160Sjillesstatic char dir[] = "/tmp/testftw.XXXXXXXXXX"; 50239160Sjillesstatic int failures; 51239160Sjillesstatic int ftwflags; 52239160Sjilles 53239160Sjillesstatic void 54239160Sjillescleanup(int ustatus __unused) 55239160Sjilles{ 56239160Sjilles int error, status; 57239160Sjilles pid_t pid, waitres; 58239160Sjilles const char *myargs[5]; 59239160Sjilles 60239160Sjilles err_set_exit(NULL); 61239160Sjilles myargs[0] = "rm"; 62239160Sjilles myargs[1] = "-rf"; 63239160Sjilles myargs[2] = "--"; 64239160Sjilles myargs[3] = dir; 65239160Sjilles myargs[4] = NULL; 66239160Sjilles error = posix_spawnp(&pid, myargs[0], NULL, NULL, 67239160Sjilles __DECONST(char **, myargs), environ); 68239160Sjilles if (error != 0) 69239160Sjilles warn("posix_spawnp rm"); 70239160Sjilles else { 71239160Sjilles waitres = waitpid(pid, &status, 0); 72239160Sjilles if (waitres != pid) 73239160Sjilles warnx("waitpid rm failed"); 74239160Sjilles else if (status != 0) 75239160Sjilles warnx("rm failed"); 76239160Sjilles } 77239160Sjilles} 78239160Sjilles 79239160Sjillesstatic int 80239160Sjillescb(const char *path, const struct stat *st, int type, struct FTW *f) 81239160Sjilles{ 82239160Sjilles 83239160Sjilles switch (type) { 84239160Sjilles case FTW_D: 85239160Sjilles if ((ftwflags & FTW_DEPTH) == 0) 86239160Sjilles return (0); 87239160Sjilles break; 88239160Sjilles case FTW_DP: 89239160Sjilles if ((ftwflags & FTW_DEPTH) != 0) 90239160Sjilles return (0); 91239160Sjilles break; 92239160Sjilles case FTW_SL: 93239160Sjilles if ((ftwflags & FTW_PHYS) != 0) 94239160Sjilles return (0); 95239160Sjilles break; 96239160Sjilles } 97239160Sjilles warnx("unexpected path=%s type=%d f.level=%d\n", 98239160Sjilles path, type, f->level); 99239160Sjilles failures++; 100239160Sjilles return (0); 101239160Sjilles} 102239160Sjilles 103239160Sjillesint 104239160Sjillesmain(int argc, char *argv[]) 105239160Sjilles{ 106239160Sjilles int fd; 107239160Sjilles 108239160Sjilles if (!mkdtemp(dir)) 109239160Sjilles err(2, "mkdtemp"); 110239160Sjilles 111239160Sjilles err_set_exit(cleanup); 112239160Sjilles 113239160Sjilles fd = open(dir, O_DIRECTORY | O_RDONLY); 114239160Sjilles if (fd == -1) 115239160Sjilles err(2, "open %s", dir); 116239160Sjilles 117239160Sjilles if (mkdirat(fd, "d1", 0777) == -1) 118239160Sjilles err(2, "mkdirat d1"); 119239160Sjilles 120239160Sjilles if (symlinkat(dir, fd, "d1/looper") == -1) 121239160Sjilles err(2, "symlinkat looper"); 122239160Sjilles 123239160Sjilles ftwflags = FTW_PHYS; 124239160Sjilles if (nftw(dir, cb, 10, ftwflags) == -1) 125239160Sjilles err(2, "nftw FTW_PHYS"); 126239160Sjilles ftwflags = FTW_PHYS | FTW_DEPTH; 127239160Sjilles if (nftw(dir, cb, 10, ftwflags) == -1) 128239160Sjilles err(2, "nftw FTW_PHYS | FTW_DEPTH"); 129239160Sjilles ftwflags = 0; 130239160Sjilles if (nftw(dir, cb, 10, ftwflags) == -1) 131239160Sjilles err(2, "nftw 0"); 132239160Sjilles ftwflags = FTW_DEPTH; 133239160Sjilles if (nftw(dir, cb, 10, ftwflags) == -1) 134239160Sjilles err(2, "nftw FTW_DEPTH"); 135239160Sjilles 136239160Sjilles close(fd); 137239160Sjilles 138239160Sjilles printf("PASS nftw()\n"); 139239160Sjilles 140239160Sjilles cleanup(failures != 0); 141239160Sjilles 142239160Sjilles return (failures != 0); 143239160Sjilles} 144