ftw.c revision 223215
1275970Scy/* $OpenBSD: ftw.c,v 1.5 2005/08/08 08:05:34 espie Exp $ */ 2275970Scy 3275970Scy/* 4275970Scy * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com> 5275970Scy * 6275970Scy * Permission to use, copy, modify, and distribute this software for any 7275970Scy * purpose with or without fee is hereby granted, provided that the above 8275970Scy * copyright notice and this permission notice appear in all copies. 9275970Scy * 10275970Scy * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11275970Scy * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12275970Scy * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13275970Scy * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14275970Scy * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15275970Scy * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16275970Scy * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17275970Scy * 18275970Scy * Sponsored in part by the Defense Advanced Research Projects 19275970Scy * Agency (DARPA) and Air Force Research Laboratory, Air Force 20275970Scy * Materiel Command, USAF, under agreement number F39502-99-1-0512. 21275970Scy */ 22275970Scy 23275970Scy#include <sys/cdefs.h> 24275970Scy__FBSDID("$FreeBSD: head/lib/libc/gen/ftw.c 223215 2011-06-18 00:29:10Z delphij $"); 25275970Scy 26275970Scy#include <sys/types.h> 27275970Scy#include <sys/stat.h> 28275970Scy#include <errno.h> 29275970Scy#include <fts.h> 30275970Scy#include <ftw.h> 31275970Scy#include <limits.h> 32275970Scy 33275970Scyint 34275970Scyftw(const char *path, int (*fn)(const char *, const struct stat *, int), 35275970Scy int nfds) 36275970Scy{ 37275970Scy char * const paths[2] = { (char *)path, NULL }; 38275970Scy FTSENT *cur; 39275970Scy FTS *ftsp; 40275970Scy int error = 0, fnflag, sverrno; 41275970Scy 42275970Scy /* XXX - nfds is currently unused */ 43275970Scy if (nfds < 1 || nfds > OPEN_MAX) { 44275970Scy errno = EINVAL; 45275970Scy return (-1); 46275970Scy } 47275970Scy 48275970Scy ftsp = fts_open(paths, FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL); 49275970Scy if (ftsp == NULL) 50275970Scy return (-1); 51275970Scy while ((cur = fts_read(ftsp)) != NULL) { 52275970Scy switch (cur->fts_info) { 53275970Scy case FTS_D: 54275970Scy fnflag = FTW_D; 55275970Scy break; 56275970Scy case FTS_DNR: 57275970Scy fnflag = FTW_DNR; 58275970Scy break; 59275970Scy case FTS_DP: 60275970Scy /* we only visit in preorder */ 61275970Scy continue; 62275970Scy case FTS_F: 63275970Scy case FTS_DEFAULT: 64275970Scy fnflag = FTW_F; 65275970Scy break; 66275970Scy case FTS_NS: 67275970Scy case FTS_NSOK: 68275970Scy case FTS_SLNONE: 69275970Scy fnflag = FTW_NS; 70275970Scy break; 71275970Scy case FTS_SL: 72275970Scy fnflag = FTW_SL; 73316722Sdelphij break; 74275970Scy case FTS_DC: 75275970Scy errno = ELOOP; 76275970Scy /* FALLTHROUGH */ 77275970Scy default: 78275970Scy error = -1; 79275970Scy goto done; 80275970Scy } 81275970Scy error = fn(cur->fts_path, cur->fts_statp, fnflag); 82275970Scy if (error != 0) 83275970Scy break; 84275970Scy } 85275970Scydone: 86275970Scy sverrno = errno; 87275970Scy if (fts_close(ftsp) != 0 && error == 0) 88275970Scy error = -1; 89275970Scy else 90275970Scy errno = sverrno; 91275970Scy return (error); 92275970Scy} 93275970Scy