void ShellHandler::listDirectory(vector<StatInfo> &_return, const string& dir) { unique_lock<mutex> g(mutex_); validateState(); FdGuard fd(openat(cwd_, dir.c_str(), O_RDONLY)); if (fd < 0) { throwErrno("failed to open directory"); } DirGuard d(fdopendir(fd)); if (!d) { throwErrno("failed to open directory handle"); } fd.release(); while (true) { errno = 0; struct dirent* ent = readdir(d); if (ent == nullptr) { if (errno != 0) { throwErrno("readdir() failed"); } break; } StatInfo si; si.name = ent->d_name; _return.push_back(si); } }
/* * record_open_files -- make a list of open files (used at START() time) */ static void record_open_files() { int dirfd; DIR *dirp = NULL; struct dirent *dp; if ((dirfd = open("/proc/self/fd", O_RDONLY)) < 0 || (dirp = fdopendir(dirfd)) == NULL) FATAL("!/proc/self/fd"); while ((dp = readdir(dirp)) != NULL) { int fdnum; char fdfile[PATH_MAX]; ssize_t cc; if (*dp->d_name == '.') continue; if ((cc = readlinkat(dirfd, dp->d_name, fdfile, PATH_MAX)) < 0) FATAL("!readlinkat: /proc/self/fd/%s", dp->d_name); fdfile[cc] = '\0'; fdnum = atoi(dp->d_name); if (dirfd == fdnum) continue; Fd_lut = open_file_add(Fd_lut, fdnum, fdfile); } closedir(dirp); }
int main(int argc, char **argv) { DIR *dirp = NULL; char *filepath = NULL; struct dirent *entry = NULL; int fd; if (1 == argc) filepath = "."; else if (2 == argc) filepath = argv[1]; else ERROR("invalid argment"); #if 0 if (NULL == (dirp = opendir(filepath))) ERROR("opendir"); #else if (-1 == (fd = open(filepath, O_DIRECTORY))) ERROR("open"); if (NULL == (dirp = fdopendir(fd))) ERROR("fdopendir"); #endif while (NULL != (entry = readdir(dirp))) { printf("%-10ld %s\n", entry->d_ino, entry->d_name); } closedir(dirp); return 0; }
/* browser_vfs_opendir */ DIR * browser_vfs_opendir(char const * filename, struct stat * st) { DIR * dir; int fd; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\", %p)\n", __func__, filename, st); #endif if(st == NULL) return opendir(filename); #if defined(__sun) if((fd = open(filename, O_RDONLY)) < 0 || (dir = fdopendir(fd)) == NULL) { if(fd >= 0) close(fd); return NULL; } #else if((dir = opendir(filename)) == NULL) return NULL; fd = dirfd(dir); #endif if(fstat(fd, st) != 0) { browser_vfs_closedir(dir); return NULL; } return dir; }
int stream_opendir(const char *path, struct fuse_file_info *fi) { int rc = 0; char *p = fixpath(path); struct fh *fh = malloc(sizeof (struct fh)); if (!fh) return -ENOMEM; struct stream *sp = find_stream(path); if (!sp) { free(fh); return -ENOMEM; } fh->sp = sp; drop_privilege(); rc = ((fh->fd = open(p, O_RDWR, 0)) < 0) ? -errno : 0; if (rc) rc = ((fh->fd = open(p, O_RDONLY, 0)) < 0) ? -errno : 0; if (!rc) rc = ((fh->dirp = fdopendir(fh->fd)) == NULL) ? -errno : -0; regain_privilege(); if (!rc) { fi->fh = (uint64_t) fh; } else { if (fh->fd >= 0) close(fh->fd); put_stream(sp); free(fh); } return rc; }
void rm_r(int rootfd, const char *path, uid_t uid) { int dirfd; DIR *d; struct dirent *e; struct stat st; if (*path == '/') path++; dirfd = openat(rootfd, path, O_DIRECTORY); d = fdopendir(dirfd); while ((e = readdir(d)) != NULL) { if (strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0) continue; if (fstatat(dirfd, e->d_name, &st, AT_SYMLINK_NOFOLLOW) != 0) continue; if (S_ISDIR(st.st_mode)) rm_r(dirfd, e->d_name, uid); else if (S_ISLNK(st.st_mode) || st.st_uid == uid) unlinkat(dirfd, e->d_name, 0); } closedir(d); if (fstatat(rootfd, path, &st, AT_SYMLINK_NOFOLLOW) != 0) return; unlinkat(rootfd, path, S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0); }
DIR *opendir(const char *name) { int fd = open(name, O_DIRECTORY | O_RDONLY); if(fd == -1) return NULL; return fdopendir(fd); }
// ---- C.dirent ---- DIR *VMPI_fdopendir(int fd) { /* note: Macintosh does not define fdopendir() Linux does */ #ifdef AVMPLUS_MAC char fullpath[MAXPATHLEN]; DIR *d; if(fcntl(fd, F_GETPATH, fullpath) < 0) { //perror("fcntl"); //fprintf(stderr, "tup error: Unable to convert file descriptor back to pathname in fdopendir() compat library.\n"); //fcntl() set the errno if( errno == 0 ) { errno = EBADF; } return NULL; } if(close(fd) < 0) { //perror("close(fd) in tup's OSX fdopendir() wrapper:"); //close() set the errno return NULL; } d = opendir(fullpath); return d; #else return fdopendir(fd); #endif }
static int _delete_dir_contents(DIR *d, int (*exclusion_predicate)(const char *name, const int is_dir)) { int result = 0; struct dirent *de; int dfd; dfd = dirfd(d); if (dfd < 0) return -1; while ((de = readdir(d))) { const char *name = de->d_name; /* check using the exclusion predicate, if provided */ if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) { continue; } if (de->d_type == DT_DIR) { int r, subfd; DIR *subdir; /* always skip "." and ".." */ if (name[0] == '.') { if (name[1] == 0) continue; if ((name[1] == '.') && (name[2] == 0)) continue; } subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); if (subfd < 0) { ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); result = -1; continue; } subdir = fdopendir(subfd); if (subdir == NULL) { ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); close(subfd); result = -1; continue; } if (_delete_dir_contents(subdir, exclusion_predicate)) { result = -1; } closedir(subdir); if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) { ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); result = -1; } } else { if (unlinkat(dfd, name, 0) < 0) { ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); result = -1; } } } return result; }
static void do_coldboot(DIR *d, int lvl) { struct dirent *de; int dfd, fd; dfd = dirfd(d); fd = openat(dfd, "uevent", O_WRONLY); if(fd >= 0) { write(fd, "add\n", 4); close(fd); } while((de = readdir(d))) { DIR *d2; if (de->d_name[0] == '.') continue; if (de->d_type != DT_DIR && lvl > 0) continue; fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); if(fd < 0) continue; d2 = fdopendir(fd); if(d2 == 0) close(fd); else { do_coldboot(d2, lvl + 1); closedir(d2); } } }
/* * check_open_files -- verify open files match recorded open files */ static void check_open_files() { int dirfd; DIR *dirp = NULL; struct dirent *dp; if ((dirfd = open("/proc/self/fd", O_RDONLY)) < 0 || (dirp = fdopendir(dirfd)) == NULL) FATAL("!/proc/self/fd"); while ((dp = readdir(dirp)) != NULL) { int fdnum; char fdfile[PATH_MAX]; ssize_t cc; if (*dp->d_name == '.') continue; if ((cc = readlinkat(dirfd, dp->d_name, fdfile, PATH_MAX)) < 0) FATAL("!readlinkat: /proc/self/fd/%s", dp->d_name); fdfile[cc] = '\0'; fdnum = atoi(dp->d_name); if (dirfd == fdnum) continue; open_file_remove(Fd_lut, fdnum, fdfile); } closedir(dirp); open_file_walk(Fd_lut); if (Fd_errcount) FATAL("open file list changed between START() and DONE()"); open_file_free(Fd_lut); }
static int do_test (void) { char tmpl[] = "/tmp/tst-fdopendir2-XXXXXX"; int fd = mkstemp (tmpl); if (fd == -1) { puts ("cannot open temp file"); return 1; } errno = 0; DIR *d = fdopendir (fd); int e = errno; close (fd); unlink (tmpl); if (d != NULL) { puts ("fdopendir with normal file descriptor did not fail"); return 1; } if (e != ENOTDIR) { printf ("fdopendir set errno to %d, not %d as expected\n", e, ENOTDIR); return 1; } return 0; }
static DIR * open_directory (Lisp_Object dirname, int *fdp) { char *name = SSDATA (dirname); DIR *d; int fd, opendir_errno; #ifdef DOS_NT /* Directories cannot be opened. The emulation assumes that any file descriptor other than AT_FDCWD corresponds to the most recently opened directory. This hack is good enough for Emacs. */ fd = 0; d = opendir (name); opendir_errno = errno; #else fd = emacs_open (name, O_RDONLY | O_DIRECTORY, 0); if (fd < 0) { opendir_errno = errno; d = 0; } else { d = fdopendir (fd); opendir_errno = errno; if (! d) emacs_close (fd); } #endif if (!d) report_file_errno ("Opening directory", dirname, opendir_errno); *fdp = fd; return d; }
bool PosixDirAccess::dopen(string* path, FileAccess* f, bool doglob) { if (doglob) { if (glob(path->c_str(), GLOB_NOSORT, NULL, &globbuf)) { return false; } globbing = true; globindex = 0; return true; } if (f) { #ifdef HAVE_FDOPENDIR dp = fdopendir(((PosixFileAccess*)f)->fd); ((PosixFileAccess*)f)->fd = -1; #else dp = ((PosixFileAccess*)f)->dp; ((PosixFileAccess*)f)->dp = NULL; #endif } else { dp = opendir(path->c_str()); } return dp != NULL; }
static awk_bool_t dir_take_control_of(awk_input_buf_t *iobuf) { DIR *dp; open_directory_t *the_dir; size_t size; errno = 0; #ifdef HAVE_FDOPENDIR dp = fdopendir(iobuf->fd); #else dp = opendir(iobuf->name); if (dp != NULL) iobuf->fd = dirfd(dp); #endif if (dp == NULL) { warning(ext_id, _("dir_take_control_of: opendir/fdopendir failed: %s"), strerror(errno)); update_ERRNO_int(errno); return awk_false; } emalloc(the_dir, open_directory_t *, sizeof(open_directory_t), "dir_take_control_of"); the_dir->dp = dp; size = sizeof(struct dirent) + 21 /* max digits in inode */ + 2 /* slashes */; emalloc(the_dir->buf, char *, size, "dir_take_control_of"); iobuf->opaque = the_dir; iobuf->get_record = dir_get_record; iobuf->close_func = dir_close; return awk_true; }
static bool hasChildren(int proc_fd, int pid) { bool ret = false; // Open "/proc" int fd = dup(proc_fd); lseek(fd, SEEK_SET, 0); DIR *dir = fd >= 0 ? fdopendir(fd) : NULL; struct dirent de, *res; while (dir && !readdir_r(dir, &de, &res) && res) { // Find numerical entries. Those are processes. if (res->d_name[0] <= '0' || res->d_name[0] > '9') { continue; } // For each process, check the parent's pid int ppid = getProcessStatus(proc_fd, res->d_name, "PPid"); if (ppid == pid) { // We found a child process. We can stop searching, now ret = true; break; } } closedir(dir); return ret; }
/* Closes all open FDs except for stdin, stdout and stderr */ static void closeFDs(int errnofd) { DIR *dp; int dfd; struct dirent *ep; int fdNum = -1; dfd = open("/proc/self/fd/", O_RDONLY); dp = fdopendir(dfd); while ((ep = readdir(dp))) { if(sscanf(ep->d_name, "%d", &fdNum) < 1) { continue; } if (fdNum < 3) { continue; } if (fdNum == dfd) { continue; } if (fdNum == errnofd) { continue; } safeClose(fdNum); } closedir(dp); safeClose(dfd); }
static ssize_t xattr_xflistxattr(int xfd, char *namebuf, size_t size, int options) { int esize; DIR *dirp; struct dirent *entry; ssize_t nsize = 0; dirp = fdopendir(xfd); if (dirp == NULL) { return (-1); } while (entry = readdir(dirp)) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; esize = strlen(entry->d_name); if (nsize + esize + 1 <= size) { snprintf((char *)(namebuf + nsize), esize + 1, entry->d_name); } nsize += esize + 1; /* +1 for \0 */ } closedir(dirp); return nsize; }
static void lo_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { int error = ENOMEM; struct lo_dirp *d = calloc(1, sizeof(struct lo_dirp)); if (d == NULL) goto out_err; d->fd = openat(lo_fd(req, ino), ".", O_RDONLY); if (d->fd == -1) goto out_errno; d->dp = fdopendir(d->fd); if (d->dp == NULL) goto out_errno; d->offset = 0; d->entry = NULL; fi->fh = (uintptr_t) d; fuse_reply_open(req, fi); return; out_errno: error = errno; out_err: if (d) { if (d->fd != -1) close(d->fd); free(d); } fuse_reply_err(req, error); }
DIR *sysfs_opendir(struct sysfs_cxt *cxt, const char *attr) { DIR *dir; int fd = -1; if (attr) fd = sysfs_open(cxt, attr); else if (cxt->dir_fd >= 0) /* request to open root of device in sysfs (/sys/block/<dev>) * -- we cannot use cxt->sysfs_fd directly, because closedir() * will close this our persistent file descriptor. */ fd = dup(cxt->dir_fd); if (fd < 0) return NULL; dir = fdopendir(fd); if (!dir) { close(fd); return NULL; } if (!attr) rewinddir(dir); return dir; }
static int calculate_dir_size(int dfd) { int size = 0; struct stat s; DIR *d; struct dirent *de; d = fdopendir(dfd); if (d == NULL) { close(dfd); return 0; } while ((de = readdir(d))) { const char *name = de->d_name; if (de->d_type == DT_DIR) { int subfd; /* always skip "." and ".." */ if (name[0] == '.') { if (name[1] == 0) continue; if ((name[1] == '.') && (name[2] == 0)) continue; } subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); if (subfd >= 0) { size += calculate_dir_size(subfd); } } else { if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { size += stat_size(&s); } } } closedir(d); return size; }
static boolean_t dir_is_empty_readdir(const char *dirname) { DIR *dirp; struct dirent64 *dp; int dirfd; if ((dirfd = openat(AT_FDCWD, dirname, O_RDONLY | O_NDELAY | O_LARGEFILE | O_CLOEXEC, 0)) < 0) { return (B_TRUE); } if ((dirp = fdopendir(dirfd)) == NULL) { (void) close(dirfd); return (B_TRUE); } while ((dp = readdir64(dirp)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; (void) closedir(dirp); return (B_FALSE); } (void) closedir(dirp); return (B_TRUE); }
int main () { int i; DIR *dp; /* The dirent-safer module works without the use of fdopendir (which would also pull in fchdir and openat); but if those modules were also used, we ensure that they are safe. In particular, the gnulib version of fdopendir is unable to guarantee that dirfd(fdopendir(fd))==fd, but we can at least guarantee that if they are not equal, the fd returned by dirfd is safe. */ #if HAVE_FDOPENDIR || GNULIB_FDOPENDIR int dfd; #endif /* We close fd 2 later, so save it in fd 10. */ if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL) return 2; #if HAVE_FDOPENDIR || GNULIB_FDOPENDIR dfd = open (".", O_RDONLY); ASSERT (STDERR_FILENO < dfd); #endif /* Four iterations, with progressively more standard descriptors closed. */ for (i = -1; i <= STDERR_FILENO; i++) { if (0 <= i) ASSERT (close (i) == 0); dp = opendir ("."); ASSERT (dp); ASSERT (dirfd (dp) == -1 || STDERR_FILENO < dirfd (dp)); ASSERT (closedir (dp) == 0); #if HAVE_FDOPENDIR || GNULIB_FDOPENDIR { int fd = dup_safer (dfd); ASSERT (STDERR_FILENO < fd); dp = fdopendir (fd); ASSERT (dp); ASSERT (dirfd (dp) == -1 || STDERR_FILENO < dirfd (dp)); ASSERT (closedir (dp) == 0); errno = 0; ASSERT (close (fd) == -1); ASSERT (errno == EBADF); } #endif } #if HAVE_FDOPENDIR || GNULIB_FDOPENDIR ASSERT (close (dfd) == 0); #endif return 0; }
static void mcachefs_build_backing_files(struct mcachefs_backing_files *filelist, const char *prefix, int dirfd) { int fd; DIR *dp; struct dirent *de; struct stat st; char *path; Log("filelist %p, prefix=%s, dirfd=%d\n", filelist, prefix, dirfd); if (dirfd == -1) { Err("Invalid dirfd for prefix='%s'\n", prefix); return; } dp = fdopendir(dirfd); while ((de = readdir(dp)) != NULL) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; path = (char *) malloc(strlen(prefix) + strlen(de->d_name) + 2); strcpy(path, prefix); strcat(path, de->d_name); if (fstatat(dirfd, de->d_name, &st, AT_SYMLINK_NOFOLLOW)) { Err("Could not stat : '%s'\n", path); free(path); continue; } Log("Prefix=%s, file=%s => %s, type=%u\n", prefix, de->d_name, path, st.st_mode); if (S_ISDIR(st.st_mode)) { strcat(path, "/"); fd = openat(dirfd, de->d_name, O_RDONLY); mcachefs_build_backing_files(filelist, path, fd); close(fd); free(path); } else if (S_ISREG(st.st_mode)) { mcachefs_backing_append_file(filelist, path, &st); } else { } } closedir(dp); }
static int cmd_setcheck_core(uint8_t check_algo, const char *path_str, struct stat *st) { hammer2_ioc_inode_t inode; int fd; int res; fd = hammer2_ioctl_handle(path_str); if (fd < 0) { res = 3; goto failed; } res = ioctl(fd, HAMMER2IOC_INODE_GET, &inode); if (res < 0) { fprintf(stderr, "%s: HAMMER2IOC_INODE_GET: error %s\n", path_str, strerror(errno)); res = 3; goto failed; } printf("%s\tcheck_algo=0x%02x\n", path_str, check_algo); inode.flags |= HAMMER2IOC_INODE_FLAG_CHECK; inode.ip_data.meta.check_algo = check_algo; res = ioctl(fd, HAMMER2IOC_INODE_SET, &inode); if (res < 0) { fprintf(stderr, "%s: HAMMER2IOC_INODE_SET: error %s\n", path_str, strerror(errno)); res = 3; goto failed; } res = 0; if (RecurseOpt && S_ISDIR(st->st_mode)) { DIR *dir; char *path; struct dirent *den; if ((dir = fdopendir(fd)) != NULL) { while ((den = readdir(dir)) != NULL) { if (strcmp(den->d_name, ".") == 0 || strcmp(den->d_name, "..") == 0) { continue; } asprintf(&path, "%s/%s", path_str, den->d_name); if (lstat(path, st) == 0) cmd_setcheck_core(check_algo, path, st); free(path); } closedir(dir); } } failed: close(fd); return res; }
static DIR* opendirat(int base_dir_fd, const char* name) { // Also check that |name| is relative. if (base_dir_fd < 0 || !name || *name == '/') return NULL; int new_dir_fd = openat(base_dir_fd, name, O_RDONLY | O_DIRECTORY); if (new_dir_fd < 0) return NULL; return fdopendir(new_dir_fd); }
DIR* fdopendupdir(int fd) { int newfd = dup(fd); if ( newfd < 0 ) return NULL; DIR* result = fdopendir(newfd); if ( !result ) return close(newfd), (DIR*) NULL; return result; }
/* Process all of the direct child files and subdirectories of dir_fd. * walk_path should already contain the full relative path to the directory that * dir_fd refers to. walk_path_end should point to the NUL terminator at the * end of that path. */ static void walk_directory_fd(int dir_fd, char *walk_path, char *walk_rel_path, char *walk_path_end, directory_walker_callback *callback, void *user_data) { DIR *dir; struct dirent *dirent; struct stat child_stat; dir = fdopendir(dir_fd); if (unlikely(dir == NULL)) { diag("Cannot open directory: %s", strerror(errno)); exit(EXIT_FAILURE); } while ((dirent = readdir(dir)) != NULL) { int child_fd; char *child_walk_path_end; if (streq(dirent->d_name, ".") || streq(dirent->d_name, "..")) { continue; } /* Append the child's base name to the directory's path, yielding the * full relative path to the child. */ child_walk_path_end = stpcpy(walk_path_end, dirent->d_name); /* Open up the child to see whether it's a file or directory. */ child_fd = openat(dir_fd, dirent->d_name, O_RDONLY); if (child_fd == -1) { diag("Cannot open file: %s", strerror(errno)); exit(EXIT_FAILURE); } if (fstat(child_fd, &child_stat) == -1) { diag("Cannot stat file: %s", strerror(errno)); exit(EXIT_FAILURE); } /* If the child is a directory, recurse into it. Otherwise call the * callback. */ if (S_ISDIR(child_stat.st_mode)) { *child_walk_path_end++ = '/'; walk_directory_fd (child_fd, walk_path, walk_rel_path, child_walk_path_end, callback, user_data); close(child_fd); } else if (strends(dirent->d_name, ".yaml")) { callback(child_fd, walk_path, walk_rel_path, user_data); close(child_fd); } } closedir(dir); }
void conf_file_or_dir(FILE *f) { struct stat st; DIR *dir; struct dirent *dp; struct fname *list = NULL; fstat(fileno(f), &st); if (S_ISREG(st.st_mode)) conf_file(f); else if (!S_ISDIR(st.st_mode)) return; #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L dir = fdopendir(fileno(f)); if (!dir) return; while ((dp = readdir(dir)) != NULL) { int l; struct fname *fn, **p; if (dp->d_ino == 0) continue; if (dp->d_name[0] == '.') continue; l = strlen(dp->d_name); if (l < 6 || strcmp(dp->d_name+l-5, ".conf") != 0) continue; fn = xmalloc(sizeof(*fn)+l+1); strcpy(fn->name, dp->d_name); for (p = &list; *p && strcmp((*p)->name, fn->name) < 0; p = & (*p)->next) ; fn->next = *p; *p = fn; } while (list) { int fd; FILE *f2; struct fname *fn = list; list = list->next; fd = openat(fileno(f), fn->name, O_RDONLY); free(fn); if (fd < 0) continue; f2 = fdopen(fd, "r"); if (!f2) { close(fd); continue; } conf_file(f2); fclose(f2); } closedir(dir); #endif }
int fdwalk (int proc_fd, int (*cb)(void *data, int fd), void *data) { int open_max; int fd; int dfd; int res = 0; DIR *d; dfd = openat (proc_fd, "self/fd", O_DIRECTORY | O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY); if (dfd == -1) return res; if ((d = fdopendir (dfd))) { struct dirent *de; while ((de = readdir (d))) { long l; char *e = NULL; if (de->d_name[0] == '.') continue; errno = 0; l = strtol (de->d_name, &e, 10); if (errno != 0 || !e || *e) continue; fd = (int) l; if ((long) fd != l) continue; if (fd == dirfd (d)) continue; if ((res = cb (data, fd)) != 0) break; } closedir (d); return res; } open_max = sysconf (_SC_OPEN_MAX); for (fd = 0; fd < open_max; fd++) if ((res = cb (data, fd)) != 0) break; return res; }