/** * @brief Select a random truetype font from the directory specified in magma.http.fonts. * @return NULL on failure, or a managed string containing the pathname of the randomly selected font file on success. */ stringer_t * register_captcha_random_font(void) { DIR *directory; stringer_t *path; struct dirent64 *dp; size_t count = 0, selection; // Open the current working directory. if (!(directory = opendir(magma.http.fonts))) { log_pedantic("Unable to open the font directory. { directory = %s }", magma.http.fonts); return NULL; } // Count the number of fonts. while ((dp = readdir64(directory))) { if (!st_cmp_ci_ends(NULLER(dp->d_name), PLACER(".ttf", 4))) { count++; } }; // No fonts were found. if (!count) { log_pedantic("The web fonts directory is empty. { directory = %s }", magma.http.fonts); closedir(directory); return NULL; } // Pick a random font. selection = (rand_get_uint32() % count) + 1; // Reset the directory stream. rewinddir(directory); // Do the loop again. while (selection && (dp = readdir64(directory))) { if (!st_cmp_ci_ends(NULLER(dp->d_name), PLACER(".ttf", 4))) { selection--; } } // Build the path. if (selection || !dp || !(path = st_aprint("%s/%s", magma.http.fonts, dp->d_name))) { log_pedantic("Could not build the font file path."); closedir(directory); return NULL; } closedir(directory); return path; }
std::vector<std::string> MAIN::Get_Directory_File_List(const std::string &i_szDirectory) /// get list of all files in the given direcctory { std::vector<std::string> szRet; DIR * dirList = opendir (i_szDirectory.c_str()); if (dirList) { dirent64 * direntInfo = readdir64(dirList); while (direntInfo) { if (direntInfo->d_name[0] != '.') // don't include . and ..; these can be assumed szRet.push_back(direntInfo->d_name); direntInfo = readdir64(dirList); } } return szRet; }
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); }
static int nprocessors_conf(void) { int ret = 0; DIR *dir = opendir("/sys/devices/system/cpu"); if (dir) { struct dirent64 *dp; while ((dp = readdir64(dir))) { if (dp->d_type == DT_DIR && dp->d_name[0] == 'c' && dp->d_name[1] == 'p' && dp->d_name[2] == 'u' && isdigit(dp->d_name[3])) ++ret; } closedir(dir); } else { #if defined __sparc__ char **l = NULL; parser_t *p = config_open("/proc/stat"); while (config_read(p, &l, 2, 2, "\0:", PARSE_NORMAL)) if (strncmp("ncpus probed", l[0], 13) == 0) { ret = atoi(l[1]); break; } config_close(p); #else ret = nprocessors_onln(); #endif } return ret != 0 ? ret : 1; }
char * portable_readdir(DIR* handle) { #ifdef USE_DIRENT64 struct dirent64 *entry_p; #else struct dirent *entry_p; #endif static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_static_mutex_lock(&mutex); #ifdef USE_READDIR entry_p = readdir(handle); #endif #ifdef USE_READDIR64 entry_p = readdir64(handle); #endif g_static_mutex_unlock(&mutex); if (entry_p == NULL) return NULL; /* FIXME: According to glibc documentation, d_name may not be null-terminated in some cases on some very old platforms. Not sure what to do about that case. */ return strdup(entry_p->d_name); }
SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp) { #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64) return readdir64(dirp); #else return readdir(dirp); #endif }
/* Read a directory entry from DIRP, store result in ENTRY and return pointer to result in *RESULT. */ int __readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result) { entry = readdir64 (dirp); *result = entry; if (entry == NULL || result == NULL) return -1; return 0; }
/*VARARGS*/ char * fpkginst(char *pkg, ...) { static char pkginst[PKGSIZ+1]; static DIR *pdirfp; struct dirent *dp; char *ckarch, *ckvers; va_list ap; va_start(ap, pkg); if (pkg == NULL) { /* request to close or rewind the file */ if (pdirfp) { (void) closedir(pdirfp); pdirfp = NULL; } return (NULL); } ckarch = va_arg(ap, char *); ckvers = va_arg(ap, char *); va_end(ap); if (!pkgdir) pkgdir = get_PKGLOC(); if (!pdirfp && ((pdirfp = opendir(pkgdir)) == NULL)) { errno = EACCES; return (NULL); } while ((dp = readdir64(pdirfp)) != NULL) { if (dp->d_name[0] == '.') continue; if (pkgnmchk(dp->d_name, pkg, 0)) continue; /* ignore invalid SVR4 package names */ if (ckinfo(dp->d_name, ckarch, ckvers)) continue; /* * Leave directory open in case user requests another * instance. */ (void) strcpy(pkginst, dp->d_name); return (pkginst); } errno = ESRCH; /* close any file we might have open */ (void) closedir(pdirfp); pdirfp = NULL; return (NULL); }
struct dirent *readdir(DIR *dir){ register struct dirent64 *de64=readdir64(dir); if(de64 == NULL) return NULL; else { dir->de32.d_ino=de64->d_ino; dir->de32.d_off=(de64->d_off > _MAX_OFF_T)?_MAX_OFF_T:de64->d_off; dir->de32.d_reclen=de64->d_reclen; dir->de32.d_type=de64->d_type; strcpy(dir->de32.d_name,de64->d_name); return &(dir->de32); } }
/* * Sys_FS_FindNext */ const char *Sys_FS_FindNext( unsigned musthave, unsigned canhave ) { struct dirent64 *d; assert( fdir ); assert( findbase && findpattern ); if( !fdir ) return NULL; while( ( d = readdir64( fdir ) ) != NULL ) { if( !CompareAttributes( d, findbase, musthave, canhave ) ) continue; if( fdots > 0 ) { // . and .. never match const char *base = COM_FileBase( d->d_name ); if( !strcmp( base, "." ) || !strcmp( base, ".." ) ) { fdots--; continue; } } if( !*findpattern || Com_GlobMatch( findpattern, d->d_name, 0 ) ) { const char *dname = d->d_name; size_t dname_len = strlen( dname ); size_t size = sizeof( char ) * ( findbase_size + dname_len + 1 + 1 ); if( findpath_size < size ) { if( findpath ) Mem_TempFree( findpath ); findpath_size = size * 2; // extra size to reduce reallocs findpath = Mem_TempMalloc( findpath_size ); } Q_snprintfz( findpath, findpath_size, "%s/%s%s", findbase, dname, dname[dname_len-1] != '/' && FS_DirentIsDir( d, findbase ) ? "/" : "" ); if( CompareAttributesForPath( d, findpath, musthave, canhave ) ) return findpath; } } return NULL; }
TEST(dirent, readdir64) { DIR* d = opendir("/proc/self"); ASSERT_TRUE(d != NULL); std::set<std::string> name_set; errno = 0; dirent64* e; while ((e = readdir64(d)) != NULL) { name_set.insert(e->d_name); } // Reading to the end of the directory is not an error. // readdir64(3) returns NULL, but leaves errno as 0. ASSERT_EQ(0, errno); ASSERT_EQ(closedir(d), 0); CheckProcSelf(name_set); }
// **************************************************************************** // *** Init // **************************************************************************** void khResourceManager::Init(void) { std::string statedir = geAssetRoot::Dirname(AssetDefs::AssetRoot(), geAssetRoot::StateDir); khLockGuard lock(mutex); // Find all the old task symlinks and tell the asset manager to resubmit // them. The symlinks have the form (taskid.task -> verref) DIR *dir = opendir(statedir.c_str()); if (!dir) { notify(NFY_FATAL, "Unable to opendir(%s): %s", statedir.c_str(), khstrerror(errno).c_str()); } struct dirent64 *entry; while ((entry = readdir64(dir))) { std::string dname = entry->d_name; if (dname == ".") continue; if (dname == "..") continue; if (!khHasExtension(dname, ".task")) continue; std::string child = statedir + "/" + dname; if (khSymlinkExists(child)) { uint32 taskid = 0; FromString(khDropExtension(dname), taskid); if (taskid == 0) { notify(NFY_FATAL, "Unrecognized task symlink %s", child.c_str()); } std::string verref; if (!khReadSymlink(child, verref)) { notify(NFY_FATAL, "Unable to process old tasks"); } if (!khUnlink(child)) { notify(NFY_FATAL, "Unable to process old tasks"); } // Tell the asset manager we lost this task // He'll re-submit it with all the details NotifyTaskLost(TaskLostMsg(verref, taskid)); } } closedir(dir); }
/* * This is an ON Consolidation Private interface. * * Print out the aliases available to the program user. Changes * depending in whether volume management is running. */ void _media_printaliases(void) { struct alias *s; DIR *dirp; struct dirent64 *dp; char pathbuf[MAXPATHLEN+1]; char *p; static const char *vold_root = NULL; if (vold_root == NULL) { vold_root = volmgt_root(); } if (!volmgt_running()) { /* no volume management */ for (s = device_aliases; *s->alias != NULLC; s++) { (void) printf("\t%s -> %s\n", s->alias, s->name); } return; } for (s = volmgt_aliases; *s->alias != NULLC; s++) { (void) printf("\t%s -> %s\n", s->alias, s->name); } (void) concat_paths(pathbuf, (char *)vold_root, ALIAS_DIR, NULL); if ((dirp = opendir(pathbuf)) == NULL) { return; } while (dp = readdir64(dirp)) { if (strcmp(dp->d_name, ".") == 0) { continue; } if (strcmp(dp->d_name, "..") == 0) { continue; } if ((p = media_findname(dp->d_name)) != NULL) { (void) printf("\t%s -> %s\n", dp->d_name, p); } } (void) closedir(dirp); }
std::vector<Path> DirectoryImplUnix::getContent(Uint32 flags) { dirent64* result; std::vector<Path> content; while((result = readdir64(m_handle))) { Path p = Path(m_path.toString() + Path::Separator + result->d_name); if((flags & (DirectorySearchFlag_Directories) && p.isDirectory()) || (flags & (DirectorySearchFlag_Files) && p.isFile())) { content.push_back(p); } } return content; }
int scandir64(const char *dir, struct dirent64 ***namelist, int (*select)(const struct dirent64 *), int (*compar)(const struct dirent64 **, const struct dirent64 **)) { DIR* d; struct dirent64 *D; size_t num=0; if (!(d=opendir(dir))) return -1; *namelist=0; while ((D=readdir64(d))) { if (select==0 || select(D)) { struct dirent64 **tmp; ++num; /* printf("realloc %p,%d -> ",*namelist,num*sizeof(struct dirent**)); */ if (!(tmp=reallocarray(*namelist,num,sizeof(struct dirent64*))) || !(tmp[num-1]=malloc(sizeof(struct dirent64)))) { size_t i; for (i=0; i<num-1; ++i) free(tmp[i]); free(*namelist); closedir(d); return -1; } memccpy(tmp[num-1]->d_name,D->d_name,0,NAME_MAX); tmp[num-1]->d_off=D->d_off; tmp[num-1]->d_reclen=D->d_reclen; tmp[num-1]->d_type=D->d_type; *namelist=tmp; /* printf("%p; tmp[num-1(%d)]=%p\n",*namelist,num-1,tmp[num-1]); */ } } closedir(d); #if 0 { int i; puts("pre-qsort:\n"); for (i=0; i<num-1; ++i) { puts((*namelist)[i]->d_name); } puts("post-qsort:\n"); } #endif // qsort(&(*namelist)[0],num,sizeof(struct dirent*),(int (*)(const void*,const void*))(compar)); if (compar) qsort(*namelist,num,sizeof(struct dirent64*),(int (*)(const void*,const void*))(compar)); return num; }
uintptr_t omrfile_findfirst(struct OMRPortLibrary *portLibrary, const char *path, char *resultbuf) { #if defined(AIXPPC) DIR64 *dirp = NULL; #else DIR *dirp = NULL; #endif #if defined(AIXPPC) struct dirent64 *entry; #else struct dirent *entry; #endif Trc_PRT_file_findfirst_Entry2(path, resultbuf); #if defined(AIXPPC) dirp = opendir64(path); #else dirp = opendir(path); #endif if (dirp == NULL) { Trc_PRT_file_findfirst_ExitFail(-1); return (uintptr_t)-1; } #if defined(AIXPPC) entry = readdir64(dirp); #else entry = readdir(dirp); #endif if (entry == NULL) { #if defined(AIXPPC) closedir64(dirp); #else closedir(dirp); #endif Trc_PRT_file_findfirst_ExitFail(-1); return (uintptr_t)-1; } strcpy(resultbuf, entry->d_name); Trc_PRT_file_findfirst_Exit((uintptr_t)dirp); return (uintptr_t)dirp; }
static char * svr4inst(char *pkg) { static char pkginst[PKGSIZ]; static DIR *pdirfp; struct dirent64 *dp; struct stat64 status; /* file status buffer */ char *pt; char path[PATH_MAX]; if (pkg == NULL) { if (pdirfp) { (void) closedir(pdirfp); pdirfp = NULL; } return (NULL); } if (!pdirfp && ((pdirfp = opendir(get_PKGOLD())) == NULL)) return (NULL); while ((dp = readdir64(pdirfp)) != NULL) { if (dp->d_name[0] == '.') continue; pt = strchr(dp->d_name, '.'); if (pt && strcmp(pt, ".name") == 0) { /* the pkgnmchk function works on .name extensions */ if (pkgnmchk(dp->d_name, pkg, 1)) continue; (void) sprintf(path, "%s/%s", get_PKGOLD(), dp->d_name); if (lstat64(path, &status)) continue; if ((status.st_mode & S_IFMT) != S_IFREG) continue; *pt = '\0'; (void) strcpy(pkginst, dp->d_name); return (pkginst); } } (void) closedir(pdirfp); pdirfp = NULL; return (NULL); }
const osd_directory_entry *osd_readdir(osd_directory *dir) { #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_FREEBSD) || defined(SDLMAME_OS2) dir->data = readdir(dir->fd); #else dir->data = readdir64(dir->fd); #endif if (dir->data == NULL) return NULL; dir->ent.name = dir->data->d_name; #if defined (SDLMAME_LINUX) || defined (SDLMAME_FREEBSD) || defined(SDLMAME_DARWIN) dir->ent.type = get_attributes_enttype(dir->data->d_type); #else dir->ent.type = get_attributes_stat(dir->data->d_name); #endif dir->ent.size = osd_get_file_size(dir->data->d_name); return &dir->ent; }
/* * Returns true if the specified directory is empty. If we can't open the * directory at all, return true so that the mount can fail with a more * informative error message. */ static boolean_t dir_is_empty(const char *dirname) { DIR *dirp; struct dirent64 *dp; if ((dirp = opendir(dirname)) == NULL) 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); }
static int walk_dir(acl_t acl, acl_t dacl, const char *fname) { int failed = 0; DIR *dir; struct dirent64 *d; char *name; if ((dir = opendir(fname)) == NULL) { if (errno != ENOTDIR) { fprintf(stderr, _("%s: opendir failed: %s\n"), program, strerror(errno)); return(1); } return(0); /* got a file, not an error */ } while ((d = readdir64(dir)) != NULL) { /* skip "." and ".." entries */ if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) continue; name = malloc(strlen(fname) + strlen(d->d_name) + 2); if (name == NULL) { fprintf(stderr, _("%s: malloc failed: %s\n"), program, strerror(errno)); exit(1); } sprintf(name, "%s/%s", fname, d->d_name); failed += set_acl(acl, dacl, name); free(name); } closedir(dir); return(failed); }
/** * Find the next filename and path matching a given handle. * * @param[in] portLibrary The port library * @param[in] findhandle handle returned from @ref omrfile_findfirst. * @param[out] resultbuf next filename and path matching findhandle. * * @return 0 on success, -1 on failure or if no matching entries. * @internal @todo return negative portable return code on failure. */ int32_t omrfile_findnext(struct OMRPortLibrary *portLibrary, uintptr_t findhandle, char *resultbuf) { #if defined(AIXPPC) struct dirent64 *entry; #else struct dirent *entry; #endif Trc_PRT_file_findnext_Entry2(findhandle, resultbuf); #if defined(AIXPPC) entry = readdir64((DIR64 *)findhandle); #else entry = readdir((DIR *)findhandle); #endif if (entry == NULL) { Trc_PRT_file_findnext_ExitFail(-1); return -1; } strcpy(resultbuf, entry->d_name); Trc_PRT_file_findnext_Exit(0); return 0; }
void _PXFREADDIR( #endif _f_int *IDIRID, _f_int *JDIRENT, _f_int *IERROR ) { #if defined(_MIPSEB) struct dirent64 *direntptr, *newdirentptr; #else struct dirent *direntptr, *newdirentptr; #endif int errno_save; DIR *dirp; int cdirent, cdirid; /* set errno to invalid error number so end of directory can be checked since * readdir returns NULL but does not set errno when the end of a directory * is reached. */ errno_save = errno; errno = -1; cdirid = *IDIRID; if (cdirid < 0) { cdirid = -cdirid; } /* fetch the real DIR pointer from the pxfdir_table */ dirp = _table_lookup(&_pxfdir_table, cdirid); if (dirp == NULL) { *IERROR = EBADID; return; } #if defined(_MIPSEB) if ((direntptr = readdir64(dirp)) == NULL) { #else if ((direntptr = readdir(dirp)) == NULL) { #endif if (errno == -1) { /* end of directory entries */ *IERROR = EEND; } else { *IERROR = errno; } errno = errno_save; return; } errno = errno_save; /* Since the size of the dirent structure returned from readdir varies in * size the old dirent struct needs to be free'd and a new struct of size * direntptr->d_reclen malloc'd. */ #if defined(_MIPSEB) newdirentptr = (struct dirent64 *)malloc(direntptr->d_reclen); #else newdirentptr = (struct dirent *)malloc(direntptr->d_reclen); #endif if (newdirentptr == NULL) { *IERROR = ENOMEM; return; } (void)memcpy(newdirentptr, direntptr, direntptr->d_reclen); /* Determine if a new entry in the pxfhandle table is needed. * If IDIRID is negative, then pxfreaddir has not been called * and a new pxfhandle table entry is needed. */ if (*IDIRID < 0) { cdirent = _pxfhandle_table_add(&_pxfhandle_table, newdirentptr, PXF_DIRENT); if (cdirent < 0) { *IERROR = ENOMEM; return; } else { *JDIRENT = cdirent; *IDIRID = cdirid; } } else if (!_pxfhandle_table_replace(&_pxfhandle_table, *JDIRENT, newdirentptr, PXF_DIRENT)) { *IERROR = EBADHANDLE; return; } *IERROR = 0; } #ifndef _UNICOS void pxfreaddir_( _f_int *IDIRID, _f_int *JDIRENT, _f_int *IERROR ) { _PXFREADDIR(IDIRID, JDIRENT, IERROR); }
struct dirent64 * readdir_largefile(DIR *dir) { return readdir64(dir); }
static int do_test (void) { /* fdopendir takes over the descriptor, make a copy. */ int dupfd = dup (dir_fd); if (dupfd == -1) { puts ("dup failed"); return 1; } if (lseek (dupfd, 0, SEEK_SET) != 0) { puts ("1st lseek failed"); return 1; } /* The directory should be empty safe the . and .. files. */ DIR *dir = fdopendir (dupfd); if (dir == NULL) { puts ("fdopendir failed"); return 1; } struct dirent64 *d; while ((d = readdir64 (dir)) != NULL) if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) { printf ("temp directory contains file \"%s\"\n", d->d_name); return 1; } closedir (dir); /* Try to create a file. */ int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666); if (fd == -1) { if (errno == ENOSYS) { puts ("*at functions not supported"); return 0; } puts ("file creation failed"); return 1; } write (fd, "hello", 5); puts ("file created"); struct stat64 st1; if (fstat64 (fd, &st1) != 0) { puts ("fstat64 failed"); return 1; } close (fd); if (linkat (dir_fd, "some-file", dir_fd, "another-file", 0) != 0) { puts ("symlinkat failed"); return 1; } struct stat64 st2; if (fstatat64 (dir_fd, "some-file", &st2, 0) != 0) { puts ("fstatat64 failed"); return 1; } if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) { puts ("file changed after symlinkat"); return 1; } if (fstatat64 (dir_fd, "another-file", &st2, AT_SYMLINK_NOFOLLOW) != 0) { puts ("2nd fstatat64 failed"); return 1; } if (S_ISLNK (st2.st_mode)) { puts ("2nd fstatat64 shows file is a symlink"); return 1; } if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino || st1.st_size != st2.st_size) { puts ("stat results for linked file do not match"); return 1; } if (fstatat64 (dir_fd, "another-file", &st2, 0) != 0) { puts ("3rd fstatat64 failed"); return 1; } if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino || st1.st_size != st2.st_size) { puts ("stat results do not match"); return 1; } if (unlinkat (dir_fd, "another-file", 0) != 0) { puts ("unlinkat failed"); return 1; } if (unlinkat (dir_fd, "some-file", 0) != 0) { puts ("2nd unlinkat failed"); return 1; } close (dir_fd); return 0; }
/* * Given a list of directories to search, find all pools stored on disk. This * includes partial pools which are not available to import. If no args are * given (argc is 0), then the default directory (/dev/dsk) is searched. * poolname or guid (but not both) are provided by the caller when trying * to import a specific pool. */ static nvlist_t * zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) { int i, dirs = iarg->paths; struct dirent64 *dp; char path[MAXPATHLEN]; char *end, **dir = iarg->path; size_t pathleft; nvlist_t *ret = NULL; static char *default_dir = "/dev/dsk"; pool_list_t pools = { 0 }; pool_entry_t *pe, *penext; vdev_entry_t *ve, *venext; config_entry_t *ce, *cenext; name_entry_t *ne, *nenext; avl_tree_t slice_cache; rdsk_node_t *slice; void *cookie; if (dirs == 0) { dirs = 1; dir = &default_dir; } /* * Go through and read the label configuration information from every * possible device, organizing the information according to pool GUID * and toplevel GUID. */ for (i = 0; i < dirs; i++) { tpool_t *t; char *rdsk; int dfd; boolean_t config_failed = B_FALSE; DIR *dirp; /* use realpath to normalize the path */ if (realpath(dir[i], path) == 0) { (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]); goto error; } end = &path[strlen(path)]; *end++ = '/'; *end = 0; pathleft = &path[sizeof (path)] - end; /* * Using raw devices instead of block devices when we're * reading the labels skips a bunch of slow operations during * close(2) processing, so we replace /dev/dsk with /dev/rdsk. */ if (strcmp(path, "/dev/dsk/") == 0) rdsk = "/dev/rdsk/"; else rdsk = path; if ((dfd = open64(rdsk, O_RDONLY)) < 0 || (dirp = fdopendir(dfd)) == NULL) { if (dfd >= 0) (void) close(dfd); zfs_error_aux(hdl, strerror(errno)); (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), rdsk); goto error; } avl_create(&slice_cache, slice_cache_compare, sizeof (rdsk_node_t), offsetof(rdsk_node_t, rn_node)); /* * This is not MT-safe, but we have no MT consumers of libzfs */ while ((dp = readdir64(dirp)) != NULL) { const char *name = dp->d_name; if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; slice = zfs_alloc(hdl, sizeof (rdsk_node_t)); slice->rn_name = zfs_strdup(hdl, name); slice->rn_avl = &slice_cache; slice->rn_dfd = dfd; slice->rn_hdl = hdl; slice->rn_nozpool = B_FALSE; avl_add(&slice_cache, slice); } /* * create a thread pool to do all of this in parallel; * rn_nozpool is not protected, so this is racy in that * multiple tasks could decide that the same slice can * not hold a zpool, which is benign. Also choose * double the number of processors; we hold a lot of * locks in the kernel, so going beyond this doesn't * buy us much. */ t = tpool_create(1, 2 * sysconf(_SC_NPROCESSORS_ONLN), 0, NULL); for (slice = avl_first(&slice_cache); slice; (slice = avl_walk(&slice_cache, slice, AVL_AFTER))) (void) tpool_dispatch(t, zpool_open_func, slice); tpool_wait(t); tpool_destroy(t); cookie = NULL; while ((slice = avl_destroy_nodes(&slice_cache, &cookie)) != NULL) { if (slice->rn_config != NULL && !config_failed) { nvlist_t *config = slice->rn_config; boolean_t matched = B_TRUE; if (iarg->poolname != NULL) { char *pname; matched = nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &pname) == 0 && strcmp(iarg->poolname, pname) == 0; } else if (iarg->guid != 0) { uint64_t this_guid; matched = nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &this_guid) == 0 && iarg->guid == this_guid; } if (!matched) { nvlist_free(config); } else { /* * use the non-raw path for the config */ (void) strlcpy(end, slice->rn_name, pathleft); if (add_config(hdl, &pools, path, config) != 0) config_failed = B_TRUE; } } free(slice->rn_name); free(slice); } avl_destroy(&slice_cache); (void) closedir(dirp); if (config_failed) goto error; } ret = get_configs(hdl, &pools, iarg->can_be_active); error: for (pe = pools.pools; pe != NULL; pe = penext) { penext = pe->pe_next; for (ve = pe->pe_vdevs; ve != NULL; ve = venext) { venext = ve->ve_next; for (ce = ve->ve_configs; ce != NULL; ce = cenext) { cenext = ce->ce_next; if (ce->ce_config) nvlist_free(ce->ce_config); free(ce); } free(ve); } free(pe); } for (ne = pools.names; ne != NULL; ne = nenext) { nenext = ne->ne_next; free(ne->ne_name); free(ne); } return (ret); }
/* * Given a list of directories to search, find all pools stored on disk. This * includes partial pools which are not available to import. If no args are * given (argc is 0), then the default directory (/dev/dsk) is searched. * poolname or guid (but not both) are provided by the caller when trying * to import a specific pool. */ static nvlist_t * zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) { int i, dirs = iarg->paths; DIR *dirp = NULL; struct dirent64 *dp; char path[MAXPATHLEN]; char *end, **dir = iarg->path; size_t pathleft; struct stat64 statbuf; nvlist_t *ret = NULL, *config; int fd; pool_list_t pools = { 0 }; pool_entry_t *pe, *penext; vdev_entry_t *ve, *venext; config_entry_t *ce, *cenext; name_entry_t *ne, *nenext; verify(iarg->poolname == NULL || iarg->guid == 0); if (dirs == 0) { #ifdef HAVE_LIBBLKID /* Use libblkid to scan all device for their type */ if (zpool_find_import_blkid(hdl, &pools) == 0) goto skip_scanning; (void) zfs_error_fmt(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "blkid failure falling back " "to manual probing")); #endif /* HAVE_LIBBLKID */ dir = zpool_default_import_path; dirs = DEFAULT_IMPORT_PATH_SIZE; } /* * Go through and read the label configuration information from every * possible device, organizing the information according to pool GUID * and toplevel GUID. */ for (i = 0; i < dirs; i++) { char *rdsk; int dfd; /* use realpath to normalize the path */ if (realpath(dir[i], path) == 0) { /* it is safe to skip missing search paths */ if (errno == ENOENT) continue; zfs_error_aux(hdl, strerror(errno)); (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]); goto error; } end = &path[strlen(path)]; *end++ = '/'; *end = 0; pathleft = &path[sizeof (path)] - end; /* * Using raw devices instead of block devices when we're * reading the labels skips a bunch of slow operations during * close(2) processing, so we replace /dev/dsk with /dev/rdsk. */ if (strcmp(path, "/dev/dsk/") == 0) rdsk = "/dev/rdsk/"; else rdsk = path; if ((dfd = open64(rdsk, O_RDONLY)) < 0 || (dirp = fdopendir(dfd)) == NULL) { zfs_error_aux(hdl, strerror(errno)); (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), rdsk); goto error; } /* * This is not MT-safe, but we have no MT consumers of libzfs */ while ((dp = readdir64(dirp)) != NULL) { const char *name = dp->d_name; if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; /* * Skip checking devices with well known prefixes: * watchdog - A special close is required to avoid * triggering it and resetting the system. * fuse - Fuse control device. * ppp - Generic PPP driver. * tty* - Generic serial interface. * vcs* - Virtual console memory. * parport* - Parallel port interface. * lp* - Printer interface. * fd* - Floppy interface. * hpet - High Precision Event Timer, crashes qemu * when accessed from a virtual machine. * core - Symlink to /proc/kcore, causes a crash * when access from Xen dom0. */ if ((strncmp(name, "watchdog", 8) == 0) || (strncmp(name, "fuse", 4) == 0) || (strncmp(name, "ppp", 3) == 0) || (strncmp(name, "tty", 3) == 0) || (strncmp(name, "vcs", 3) == 0) || (strncmp(name, "parport", 7) == 0) || (strncmp(name, "lp", 2) == 0) || (strncmp(name, "fd", 2) == 0) || (strncmp(name, "hpet", 4) == 0) || (strncmp(name, "core", 4) == 0)) continue; /* * Ignore failed stats. We only want regular * files and block devices. */ if ((fstatat64(dfd, name, &statbuf, 0) != 0) || (!S_ISREG(statbuf.st_mode) && !S_ISBLK(statbuf.st_mode))) continue; if ((fd = openat64(dfd, name, O_RDONLY)) < 0) continue; if ((zpool_read_label(fd, &config)) != 0) { (void) close(fd); (void) no_memory(hdl); goto error; } (void) close(fd); if (config != NULL) { boolean_t matched = B_TRUE; char *pname; if ((iarg->poolname != NULL) && (nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &pname) == 0)) { if (strcmp(iarg->poolname, pname)) matched = B_FALSE; } else if (iarg->guid != 0) { uint64_t this_guid; matched = nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &this_guid) == 0 && iarg->guid == this_guid; } if (!matched) { nvlist_free(config); config = NULL; continue; } /* use the non-raw path for the config */ (void) strlcpy(end, name, pathleft); if (add_config(hdl, &pools, path, i+1, config)) goto error; } } (void) closedir(dirp); dirp = NULL; } #ifdef HAVE_LIBBLKID skip_scanning: #endif ret = get_configs(hdl, &pools, iarg->can_be_active); error: for (pe = pools.pools; pe != NULL; pe = penext) { penext = pe->pe_next; for (ve = pe->pe_vdevs; ve != NULL; ve = venext) { venext = ve->ve_next; for (ce = ve->ve_configs; ce != NULL; ce = cenext) { cenext = ce->ce_next; if (ce->ce_config) nvlist_free(ce->ce_config); free(ce); } free(ve); } free(pe); } for (ne = pools.names; ne != NULL; ne = nenext) { nenext = ne->ne_next; if (ne->ne_name) free(ne->ne_name); free(ne); } if (dirp) (void) closedir(dirp); return (ret); }
static int srch_dir(const entry_t path, /* current path */ int match_mask, /* flags mask */ int depth, /* current depth (/dev = 0) */ const entry_t skip_dirs[], /* directories not needing searching */ struct stat64 *fsb) /* the file being searched for */ { DIR *dirp; struct dirent64 *direntp; struct stat64 tsb; char file_name[MAX_DEV_PATH]; entry_t file; char *last_comp; int found = 0; int dirno = 0; size_t path_len; file.name = file_name; file.flags = path.flags & match_mask; if (file.flags == 0) file.flags = match_mask; /* * do we need to search this directory? (always search /dev at depth 0) */ if ((skip_dirs != NULL) && (depth != 0)) while (skip_dirs[dirno].name != NULL) if (strcmp(skip_dirs[dirno++].name, path.name) == 0) return (0); /* * open directory */ if ((dirp = opendir(path.name)) == NULL) { return (0); } /* * skip two first entries ('.' and '..') */ if (((direntp = readdir64(dirp)) == NULL) || ((direntp = readdir64(dirp)) == NULL)) { (void) closedir(dirp); return (0); } path_len = strlen(path.name); (void) strcpy(file_name, path.name); last_comp = file_name + path_len; *last_comp++ = '/'; /* * read thru the directory */ while ((!found) && ((direntp = readdir64(dirp)) != NULL)) { /* * if the file name (path + "/" + d_name + NULL) would be too * long, skip it */ if ((path_len + strlen(direntp->d_name) + 2) > MAX_DEV_PATH) continue; else (void) strcpy(last_comp, direntp->d_name); if (stat64(file_name, &tsb) < 0) continue; /* * if a file is a directory and we are not too deep, recurse */ if ((tsb.st_mode & S_IFMT) == S_IFDIR) if (depth < MAX_SRCH_DEPTH) found = srch_dir(file, match_mask, depth+1, skip_dirs, fsb); else continue; /* * else if it is not a directory, is it a character special * file? */ else if ((tsb.st_mode & S_IFMT) == S_IFCHR) { int flag = 0; if (tsb.st_dev == fsb->st_dev) flag |= MATCH_FS; if (tsb.st_rdev == fsb->st_rdev) flag |= MATCH_MM; if (tsb.st_ino == fsb->st_ino) flag |= MATCH_INO; if ((flag & file.flags) == file.flags) { (void) strcpy(rbuf, file.name); found = 1; } else if ((flag & (MATCH_MM | MATCH_FS)) == (MATCH_MM | MATCH_FS)) { /* * no (inodes do not match), but save the name * for later */ (void) strcpy(dev_rbuf, file.name); dev_flag = 1; } } } (void) closedir(dirp); return (found); }
/*VARARGS*/ char * fpkginst(char *pkg, ...) { static char pkginst[PKGSIZ+1]; static DIR *pdirfp; struct dirent64 *dp; char *pt, *ckarch, *ckvers; va_list ap; va_start(ap, pkg); if (pkg == NULL) { /* request to close or rewind the file */ if (pdirfp) { (void) closedir(pdirfp); pdirfp = NULL; } (void) svr4inst(NULL); /* close any files used here */ return (NULL); } ckarch = va_arg(ap, char *); ckvers = va_arg(ap, char *); va_end(ap); if (!pkgdir) pkgdir = get_PKGLOC(); if (!pdirfp && ((pdirfp = opendir(pkgdir)) == NULL)) { errno = EACCES; return (NULL); } while ((dp = readdir64(pdirfp)) != NULL) { if (dp->d_name[0] == '.') continue; if (pkgnmchk(dp->d_name, pkg, 0)) continue; /* ignore invalid SVR4 package names */ if (ckinfo(dp->d_name, ckarch, ckvers)) continue; /* * Leave directory open in case user requests another * instance. */ (void) strcpy(pkginst, dp->d_name); return (pkginst); } /* * If we are searching the directory which contains info about * installed packages, check the pre-svr4 directory for an instance * and be sure it matches any version specification provided to us */ if (strcmp(pkgdir, get_PKGLOC()) == 0 && (ckarch == NULL)) { /* search for pre-SVR4 instance */ if (pt = svr4inst(pkg)) return (pt); } errno = ESRCH; /* close any file we might have open */ (void) closedir(pdirfp); pdirfp = NULL; return (NULL); }
static int do_test (void) { /* fdopendir takes over the descriptor, make a copy. */ int dupfd = dup (dir_fd); if (dupfd == -1) { puts ("dup failed"); return 1; } if (lseek (dupfd, 0, SEEK_SET) != 0) { puts ("1st lseek failed"); return 1; } /* The directory should be empty save the . and .. files. */ DIR *dir = fdopendir (dupfd); if (dir == NULL) { puts ("fdopendir failed"); return 1; } struct dirent64 *d; while ((d = readdir64 (dir)) != NULL) if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) { printf ("temp directory contains file \"%s\"\n", d->d_name); return 1; } closedir (dir); umask (022); /* Try to create a file. */ int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666); if (fd == -1) { if (errno == ENOSYS) { puts ("*at functions not supported"); return 0; } puts ("file creation failed"); return 1; } write (fd, "hello", 5); puts ("file created"); struct stat64 st1; if (fstat64 (fd, &st1) != 0) { puts ("fstat64 failed"); return 1; } /* Before closing the file, try using this file descriptor to open another file. This must fail. */ if (fchmodat (fd, "some-file", 0400, 0) != -1) { puts ("fchmodat using descriptor for normal file worked"); return 1; } if (errno != ENOTDIR) { puts ("\ error for fchmodat using descriptor for normal file not ENOTDIR "); return 1; }
static int ses_plugin_load_dir(ses_target_t *tp, const char *pluginroot) { char path[PATH_MAX]; DIR *dirp; struct dirent64 *dp; char *vendor, *product, *revision; char isa[257]; (void) snprintf(path, sizeof (path), "%s/%s", pluginroot, LIBSES_PLUGIN_FRAMEWORK); #if defined(_LP64) if (sysinfo(SI_ARCHITECTURE_64, isa, sizeof (isa)) < 0) isa[0] = '\0'; #else isa[0] = '\0'; #endif if ((dirp = opendir(path)) != NULL) { while ((dp = readdir64(dirp)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; (void) snprintf(path, sizeof (path), "%s/%s/%s/%s", pluginroot, LIBSES_PLUGIN_FRAMEWORK, isa, dp->d_name); if (ses_plugin_loadone(tp, path, 0) != 0) { (void) closedir(dirp); return (-1); } } (void) closedir(dirp); } /* * Create a local copy of the vendor/product/revision, strip out any * questionable characters, and then attempt to load each plugin. */ vendor = strdupa(libscsi_vendor(tp->st_target)); product = strdupa(libscsi_product(tp->st_target)); revision = strdupa(libscsi_revision(tp->st_target)); ses_plugin_cleanstr(vendor); ses_plugin_cleanstr(product); ses_plugin_cleanstr(revision); (void) snprintf(path, sizeof (path), "%s/%s/%s/%s%s", pluginroot, LIBSES_PLUGIN_VENDOR, isa, vendor, LIBSES_PLUGIN_EXT); if (ses_plugin_loadone(tp, path, 1) != 0) return (-1); (void) snprintf(path, sizeof (path), "%s/%s/%s/%s-%s%s", pluginroot, LIBSES_PLUGIN_VENDOR, isa, vendor, product, LIBSES_PLUGIN_EXT); if (ses_plugin_loadone(tp, path, 2) != 0) return (-1); (void) snprintf(path, sizeof (path), "%s/%s/%s/%s-%s-%s%s", pluginroot, LIBSES_PLUGIN_VENDOR, isa, vendor, product, revision, LIBSES_PLUGIN_EXT); if (ses_plugin_loadone(tp, path, 3) != 0) return (-1); return (0); }