diff options
author | Dees Troy <dees_troy@teamw.in> | 2013-02-27 19:39:14 +0100 |
---|---|---|
committer | Gerrit Code Review <gerrit@5.9.244.119> | 2013-02-27 19:39:14 +0100 |
commit | 2cf31af56114cf997b10218db7c35ee047f5d400 (patch) | |
tree | 85f3b51e45ff8233922f2c0c151299868ca89371 /libblkid/at.c | |
parent | libtar - Fix extraction of hardlinks to use the prefix (diff) | |
parent | use libblkid to get filesystem type (diff) | |
download | android_bootable_recovery-2cf31af56114cf997b10218db7c35ee047f5d400.tar android_bootable_recovery-2cf31af56114cf997b10218db7c35ee047f5d400.tar.gz android_bootable_recovery-2cf31af56114cf997b10218db7c35ee047f5d400.tar.bz2 android_bootable_recovery-2cf31af56114cf997b10218db7c35ee047f5d400.tar.lz android_bootable_recovery-2cf31af56114cf997b10218db7c35ee047f5d400.tar.xz android_bootable_recovery-2cf31af56114cf997b10218db7c35ee047f5d400.tar.zst android_bootable_recovery-2cf31af56114cf997b10218db7c35ee047f5d400.zip |
Diffstat (limited to '')
-rw-r--r-- | libblkid/at.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/libblkid/at.c b/libblkid/at.c new file mode 100644 index 000000000..f8bfe1399 --- /dev/null +++ b/libblkid/at.c @@ -0,0 +1,143 @@ +/* + * Portable xxxat() functions. + * + * No copyright is claimed. This code is in the public domain; do with + * it what you wish. + * + * Written by Karel Zak <kzak@redhat.com> + */ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/stat.h> + +#include "at.h" +#include "c.h" + +#ifdef HAVE_FSTATAT +int fstat_at(int dir, const char *dirname __attribute__ ((__unused__)), + const char *filename, struct stat *st, int nofollow) +{ + return fstatat(dir, filename, st, + nofollow ? AT_SYMLINK_NOFOLLOW : 0); +} +#else +int fstat_at(int dir, const char *dirname, const char *filename, + struct stat *st, int nofollow) +{ + + if (*filename != '/') { + char path[PATH_MAX]; + int len; + + len = snprintf(path, sizeof(path), "%s/%s", dirname, filename); + if (len < 0 || len + 1 > sizeof(path)) + return -1; + + return nofollow ? lstat(path, st) : stat(path, st); + } + + return nofollow ? lstat(filename, st) : stat(filename, st); +} +#endif + +#ifdef HAVE_FSTATAT +int open_at(int dir, const char *dirname __attribute__ ((__unused__)), + const char *filename, int flags) +{ + return openat(dir, filename, flags); +} +#else +int open_at(int dir, const char *dirname, const char *filename, int flags) +{ + if (*filename != '/') { + char path[PATH_MAX]; + int len; + + len = snprintf(path, sizeof(path), "%s/%s", dirname, filename); + if (len < 0 || len + 1 > sizeof(path)) + return -1; + + return open(path, flags); + } + return open(filename, flags); +} +#endif + +FILE *fopen_at(int dir, const char *dirname, const char *filename, int flags, + const char *mode) +{ + int fd = open_at(dir, dirname, filename, flags); + + if (fd < 0) + return NULL; + + return fdopen(fd, mode); +} + +#ifdef HAVE_FSTATAT +ssize_t readlink_at(int dir, const char *dirname __attribute__ ((__unused__)), + const char *pathname, char *buf, size_t bufsiz) +{ + return readlinkat(dir, pathname, buf, bufsiz); +} +#else +ssize_t readlink_at(int dir, const char *dirname, const char *pathname, + char *buf, size_t bufsiz) +{ + if (*pathname != '/') { + char path[PATH_MAX]; + int len; + + len = snprintf(path, sizeof(path), "%s/%s", dirname, pathname); + if (len < 0 || len + 1 > sizeof(path)) + return -1; + + return readlink(path, buf, bufsiz); + } + return readlink(pathname, buf, bufsiz); +} +#endif + +#ifdef TEST_PROGRAM_AT +#include <errno.h> +#include <sys/types.h> +#include <dirent.h> +#include <string.h> + +int main(int argc, char *argv[]) +{ + DIR *dir; + struct dirent *d; + char *dirname; + + if (argc != 2) { + fprintf(stderr, "usage: %s <directory>\n", argv[0]); + exit(EXIT_FAILURE); + } + dirname = argv[1]; + + dir = opendir(dirname); + if (!dir) + err(EXIT_FAILURE, "cannot open %s", dirname); + + while ((d = readdir(dir))) { + struct stat st; + FILE *f; + + printf("%32s ", d->d_name); + + if (fstat_at(dirfd(dir), dirname, d->d_name, &st, 0) == 0) + printf("%16jd bytes ", st.st_size); + else + printf("%16s bytes ", "???"); + + f = fopen_at(dirfd(dir), dirname, d->d_name, O_RDONLY, "r"); + printf(" %s\n", f ? "OK" : strerror(errno)); + if (f) + fclose(f); + } + closedir(dir); + return EXIT_SUCCESS; +} +#endif |