X-Git-Url: http://git.tuebingen.mpg.de/?p=osl.git;a=blobdiff_plain;f=fsck.c;h=29c4e2c7dc9d72d940dbb7c4298f24d84f3dcfc8;hp=b5e4fdbe16e0fc593e303de69de8e521b845ed31;hb=53c4162f4a1fd70343332b9596e89d73c8547e51;hpb=a00170132c28eeea61033d820c22e8d48d35a0fd diff --git a/fsck.c b/fsck.c index b5e4fdb..29c4e2c 100644 --- a/fsck.c +++ b/fsck.c @@ -15,7 +15,7 @@ #include "log.h" #include "osl.h" #include "error.h" -#include "fd.h" +#include "util.h" #include "osl_core.h" #include "fsck.cmdline.h" @@ -222,6 +222,72 @@ static inline int __fchdir(int fd) return 1; } +/** + * Wrapper for chdir(2). + * + * \param path The specified directory. + * + * \return Standard. + */ +_static_inline_ int __chdir(const char *path) +{ + if (chdir(path) >= 0) + return 1; + return -ERRNO_TO_ERROR(errno); +} + +/** + * Save the cwd and open a given directory. + * + * \param dirname Path to the directory to open. + * \param dir Result pointer. + * \param cwd File descriptor of the current working directory. + * + * \return Standard. + * + * Opening the current directory (".") and calling fchdir() to return is + * usually faster and more reliable than saving cwd in some buffer and calling + * chdir() afterwards. + * + * If \a cwd is not \p NULL "." is opened and the resulting file descriptor is + * stored in \a cwd. If the function returns success, and \a cwd is not \p + * NULL, the caller must close this file descriptor (probably after calling + * fchdir(*cwd)). + * + * On errors, the function undos everything, so the caller needs neither close + * any files, nor change back to the original working directory. + * + * \sa getcwd(3). + * + */ +static int fsck_opendir(const char *dirname, DIR **dir, int *cwd) +{ + int ret; + + if (cwd) { + ret = osl_open(".", O_RDONLY, 0); + if (ret < 0) + return ret; + *cwd = ret; + } + ret = __chdir(dirname); + if (ret < 0) + goto close_cwd; + *dir = opendir("."); + if (*dir) + return 1; + ret = -ERRNO_TO_ERROR(errno); +/* Ignore return value of fchdir() and close(). We're busted anyway. */ + if (cwd) + fchdir(*cwd); +close_cwd: + if (cwd) + close(*cwd); + return ret; +} + + + /** * Traverse the given directory recursively. * @@ -241,7 +307,7 @@ static int for_each_file_in_dir(const char *dirname, { DIR *dir; struct dirent *entry; - int cwd_fd, ret2, ret = para_opendir(dirname, &dir, &cwd_fd); + int cwd_fd, ret2, ret = fsck_opendir(dirname, &dir, &cwd_fd); if (ret < 0) return ret == -ERRNO_TO_ERROR(EACCES)? 1 : ret; @@ -1119,7 +1185,7 @@ static int check_all_tables(char *db_dir) { DIR *dir; struct dirent *entry; - int cwd_fd, ret2, ret = para_opendir(db_dir, &dir, &cwd_fd); + int cwd_fd, ret2, ret = fsck_opendir(db_dir, &dir, &cwd_fd); if (ret < 0) return ret;