From 5a5eeb1513cfb7e02a352ef0dd987e85697a83eb Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 22 Jun 2010 13:27:59 +0200 Subject: lib: add wrappers for "at" functions Signed-off-by: Karel Zak --- lib/Makefile.am | 3 +- lib/at.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 lib/at.c (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am index 9a3bf35bd..36396a385 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/config/include-Makefile.am AM_CPPFLAGS += -DTEST_PROGRAM noinst_PROGRAMS = test_blkdev test_ismounted test_wholedisk test_mangle \ - test_tt test_canonicalize + test_tt test_canonicalize test_at if LINUX if HAVE_CPU_SET_T noinst_PROGRAMS += test_cpuset @@ -14,6 +14,7 @@ test_blkdev_SOURCES = blkdev.c test_ismounted_SOURCES = ismounted.c test_wholedisk_SOURCES = wholedisk.c test_mangle_SOURCES = mangle.c +test_at_SOURCES = at.c if LINUX test_cpuset_SOURCES = cpuset.c endif diff --git a/lib/at.c b/lib/at.c new file mode 100644 index 000000000..1993f9983 --- /dev/null +++ b/lib/at.c @@ -0,0 +1,100 @@ +/* + * Portable xxxat() functions. + * + * Copyright (C) 2010 Karel Zak + */ +#include +#include +#include +#include + +#include "at.h" + +int fstat_at(int dir, const char *dirname, const char *filename, + struct stat *st, int nofollow) +{ +#ifdef HAVE_FSTATAT + return fstatat(dir, filename, st, + nofollow ? AT_SYMLINK_NOFOLLOW : 0); +#else + 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); +#endif +} + +int open_at(int dir, const char *dirname, const char *filename, int flags) +{ +#ifdef HAVE_FSTATAT + return openat(dir, filename, flags); +#else + 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); +#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 TEST_PROGRAM +#include +#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, "%s: open failed", 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-55-g7522