* limitations under the License.
*/
+#include <ftw.h>
#include <stdlib.h>
int mkstemp64(char* filename) {
// open (our open is actually open64) and stat and stat64 are the same.
return mkstemp(filename);
}
+
+typedef int (*ftw_fn)(const char*, const struct stat*, int);
+typedef int (*nftw_fn)(const char*, const struct stat*, int, struct FTW*);
+
+int ftw64(const char *dirpath,
+ int (*fn)(const char*, const struct stat64*, int), int nopenfd) {
+ return ftw(dirpath, reinterpret_cast<ftw_fn>(fn), nopenfd);
+}
+
+int nftw64(const char * dirpath,
+ int (*fn)(const char*, const struct stat64*, int, struct FTW*),
+ int nopenfd, int flags) {
+ return nftw(dirpath, reinterpret_cast<nftw_fn>(fn), nopenfd, flags);
+}
int ftw(const char *, int (*)(const char *, const struct stat *, int), int);
int nftw(const char *, int (*)(const char *, const struct stat *, int,
struct FTW *), int, int);
+int ftw64(const char *, int (*)(const char *, const struct stat64 *, int), int);
+int nftw64(const char *, int (*)(const char *, const struct stat64 *, int,
+ struct FTW *), int, int);
__END_DECLS
#endif /* !_FTW_H */
eventfd_test.cpp \
fcntl_test.cpp \
fenv_test.cpp \
+ ftw_test.cpp \
getauxval_test.cpp \
getcwd_test.cpp \
inttypes_test.cpp \
#include <unistd.h>
-template<int (*mk_func)(char*)>
+template<int (*mk_fn)(char*)>
class GenericTemporaryFile {
public:
- GenericTemporaryFile() {
- // Since we might be running on the host or the target, and if we're
- // running on the host we might be running under bionic or glibc,
- // let's just try both possible temporary directories and take the
- // first one that works.
- init("/data/local/tmp");
- if (fd == -1) {
- init("/tmp");
+ GenericTemporaryFile(const char* dirpath = NULL) {
+ if (dirpath != NULL) {
+ init(dirpath);
+ } else {
+ // Since we might be running on the host or the target, and if we're
+ // running on the host we might be running under bionic or glibc,
+ // let's just try both possible temporary directories and take the
+ // first one that works.
+ init("/data/local/tmp");
+ if (fd == -1) {
+ init("/tmp");
+ }
}
}
private:
void init(const char* tmp_dir) {
snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir);
- fd = mk_func(filename);
+ fd = mk_fn(filename);
}
};
typedef GenericTemporaryFile<mkstemp> TemporaryFile;
+
+class TemporaryDir {
+ public:
+ TemporaryDir() {
+ if (!init("/data/local/tmp")) {
+ init("/tmp");
+ }
+ }
+
+ ~TemporaryDir() {
+ rmdir(dirname);
+ }
+
+ char dirname[1024];
+
+ private:
+ bool init(const char* tmp_dir) {
+ snprintf(dirname, sizeof(dirname), "%s/TemporaryDir-XXXXXX", tmp_dir);
+ return (mkdtemp(dirname) != NULL);
+ }
+
+};
--- /dev/null
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include "TemporaryFile.h"
+
+#include <ftw.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+void sanity_check_ftw(const char* fpath, const struct stat* sb, int tflag) {
+ ASSERT_TRUE(fpath != NULL);
+ ASSERT_TRUE(sb != NULL);
+ bool is_dir = S_ISDIR(sb->st_mode);
+ ASSERT_TRUE((is_dir && tflag == FTW_D) || (!is_dir && tflag == FTW_F));
+}
+
+void sanity_check_nftw(
+ const char* fpath, const struct stat* sb, int tflag, struct FTW* ftwbuf) {
+ sanity_check_ftw(fpath, sb, tflag);
+ // either the parent dir or the file
+ bool is_dir = S_ISDIR(sb->st_mode);
+ ASSERT_TRUE(
+ (is_dir && ftwbuf->level == 0) || (!is_dir && ftwbuf->level == 1));
+}
+
+int check_ftw(const char* fpath, const struct stat* sb, int tflag) {
+ sanity_check_ftw(fpath, sb, tflag);
+ return 0;
+}
+
+int check_ftw64(const char* fpath, const struct stat64* sb, int tflag) {
+ sanity_check_ftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag);
+ return 0;
+}
+
+int check_nftw(
+ const char* fpath, const struct stat* sb, int tflag, struct FTW* ftwbuf) {
+ sanity_check_nftw(fpath, sb, tflag, ftwbuf);
+ return 0;
+}
+
+int check_nftw64(
+ const char* fpath, const struct stat64* sb, int tflag, struct FTW* ftwbuf) {
+ sanity_check_nftw(fpath, reinterpret_cast<const struct stat*>(sb),
+ tflag, ftwbuf);
+ return 0;
+}
+
+TEST(ftw, ftw) {
+ TemporaryDir td;
+ TemporaryFile tf(td.dirname);
+ ftw(td.dirname, check_ftw, 1);
+}
+
+TEST(ftw, ftw64) {
+ TemporaryDir td;
+ GenericTemporaryFile<mkstemp64> tf(td.dirname);
+ ftw64(td.dirname, check_ftw64, 1);
+}
+
+TEST(ftw, nftw) {
+ TemporaryDir td;
+ TemporaryFile tf(td.dirname);
+ nftw(td.dirname, check_nftw, 1, 0);
+}
+
+TEST(ftw, nftw64) {
+ TemporaryDir td;
+ GenericTemporaryFile<mkstemp64> tf(td.dirname);
+ nftw64(td.dirname, check_nftw64, 1, 0);
+}