summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/chdir.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/chdir.c b/lib/chdir.c
index b531b10ec..e8ce730d5 100644
--- a/lib/chdir.c
+++ b/lib/chdir.c
@@ -37,6 +37,10 @@
#include "mempcpy.h"
#include "openat.h"
+#ifndef O_DIRECTORY
+# define O_DIRECTORY 0
+#endif
+
#ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
@@ -71,6 +75,20 @@ struct cd_buf
int fd;
};
+/* Like memchr, but return the number of bytes from MEM
+ to the first occurrence of C thereafter. Search only
+ LEN bytes. Return LEN if C is not found. */
+static inline size_t
+memchrcspn (char const *mem, int c, size_t len)
+{
+ char const *found = memchr (mem, c, len);
+ if (!found)
+ return len;
+
+ len = found - mem;
+ return len;
+}
+
static void
cdb_init (struct cd_buf *cdb)
{
@@ -247,9 +265,8 @@ rpl_chdir (char const *dir)
break;
}
- /* FIXME: if performance of strcspn is an issue,
- use a little wrapper around memchr. */
- len = strcspn (start, "/");
+ len = memchrcspn (start, '/', dir_end - start);
+ assert (len == strcspn (start, "/"));
d = start + len;
if (cdb_append (&cdb, start, len) != 0)
goto Fail;