From 7b4c7a681cc4c0a53dc8a8baf4853e921cfbf5de Mon Sep 17 00:00:00 2001 From: bigbiff Date: Thu, 1 Jan 2015 19:44:14 -0500 Subject: Update blkid to 2.25.0 Break libblkid into 4 libraries: libblkid, libuuid, libutil-linux and libfdisk. This should help in later patch updates. Change-Id: I680d9a7feb031e5c29a603e9c58aff4b65826262 --- libblkid/lib/at.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 libblkid/lib/at.c (limited to 'libblkid/lib/at.c') diff --git a/libblkid/lib/at.c b/libblkid/lib/at.c new file mode 100644 index 000000000..f8bfe1399 --- /dev/null +++ b/libblkid/lib/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 + */ +#include +#include +#include +#include + +#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 +#include +#include +#include + +int main(int argc, char *argv[]) +{ + DIR *dir; + struct dirent *d; + char *dirname; + + if (argc != 2) { + fprintf(stderr, "usage: %s \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 -- cgit v1.2.3