static struct tree *
tree_reopen(struct tree *t, const char *path, int restore_time)
{
+#if defined(O_PATH)
+ /* Linux */
+ const int o_flag = O_PATH;
+#elif defined(O_SEARCH)
+ /* SunOS */
+ const int o_flag = O_SEARCH;
+#elif defined(O_EXEC)
+ /* FreeBSD */
+ const int o_flag = O_EXEC;
+#endif
+
t->flags = (restore_time != 0)?needsRestoreTimes:0;
t->flags |= onInitialDir;
t->visit_type = 0;
t->stack->flags = needsFirstVisit;
t->maxOpenCount = t->openCount = 1;
t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
-#ifdef O_EXEC
+#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
/*
* Most likely reason to fail opening "." is that it's not readable,
* so try again for execute. The consequences of not opening this are
* unhelpful and unnecessary errors later.
*/
if (t->initial_dir_fd < 0)
- t->initial_dir_fd = open(".", O_EXEC | O_CLOEXEC);
+ t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
#endif
__archive_ensure_cloexec_flag(t->initial_dir_fd);
t->working_dir_fd = tree_dup(t->initial_dir_fd);
/*
* Test4: Traverse lock/lock2/dir1 from inside lock.
*
- * This test is expected to fail on platforms with no O_EXEC, because
+ * This test is expected to fail on platforms with no O_EXEC or
+ * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because
* the current traversal code can't handle the case where it can't
* obtain an open fd for the initial current directory. We need to
* check that condition here, because if O_EXEC _does_ exist, we don't
archive_entry_clear(ae);
r = archive_read_next_header2(a, ae);
if (r == ARCHIVE_FAILED) {
-#ifdef O_EXEC
+#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
assertEqualIntA(a, ARCHIVE_OK, r);
#endif
/* Close the disk object. */