commit cd005c8f7f4752e128a7e7c71807b4f7d42a5f08
parent 8d32c194500ebac1f5929f8028606849ed6ecce1
Author: phoebos <ben@bvnf.space>
Date: Tue, 21 Sep 2021 00:37:35 +0100
ls: use fstatat so it works with relative paths
Diffstat:
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/ls.c b/ls.c
@@ -1,5 +1,6 @@
#include <dirent.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
@@ -36,6 +37,7 @@ ls(const char *path, int flags) {
/* directory */
int n, i;
struct dirent **dp;
+ int dfd = open(path, O_RDONLY);
n = scandir(path, &dp, 0, alphasort);
if (n == -1) {
fprintf(stderr, "ls: %s: %s\n", path, strerror(errno));
@@ -43,7 +45,7 @@ ls(const char *path, int flags) {
}
for (i = 0; i < n; i++) {
struct stat stt;
- if (lstat(dp[i]->d_name, &stt) == -1) {
+ if (fstatat(dfd, dp[i]->d_name, &stt, AT_SYMLINK_NOFOLLOW) == -1) {
fprintf(stderr, "ls: %s: %s\n", dp[i]->d_name, strerror(errno));
return 1;
}
@@ -54,6 +56,7 @@ ls(const char *path, int flags) {
printname(&e, flags);
}
+ close(dfd);
} else {
/* file */
struct ent e = { .name = path, .mode = st.st_mode };