summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-05-02 18:02:47 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-05-02 18:02:47 -0400
commit889b35ebd1659d7e14deee8b3c6cf63d2237ff9e (patch)
tree4ce4c9df59c03d78038f88602c31a60d9daec137
parentadd more escape codes to printf (diff)
downloadlazysphere-889b35ebd1659d7e14deee8b3c6cf63d2237ff9e.tar.gz
lazysphere-889b35ebd1659d7e14deee8b3c6cf63d2237ff9e.tar.bz2
lazysphere-889b35ebd1659d7e14deee8b3c6cf63d2237ff9e.zip
fix ls segfault
-rw-r--r--Makefile1
-rw-r--r--src/commands/ls.c138
-rw-r--r--src/commands/printf.c2
-rw-r--r--src/util/shared.c23
-rw-r--r--src/util/shared.h5
5 files changed, 95 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index 708443e..ba4984d 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,6 @@ CCFLAGS = -std=c99 -Wall -Wextra -pedantic -O2
CCFLAGS += -D_DEFAULT_SOURCE -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH) -DCHECK_LINK
CCFLAGS += $(INCFLAGS)
-LDFLAGS = -s
LDFLAGS += $(INCFLAGS)
BIN = bin
diff --git a/src/commands/ls.c b/src/commands/ls.c
index 3aad1a1..fec8cdd 100644
--- a/src/commands/ls.c
+++ b/src/commands/ls.c
@@ -5,6 +5,7 @@
#include <dirent.h>
#include <ftw.h>
#include <limits.h>
+#include <string.h>
#define FILE_COLOR ANSCII BLACK COLOR
#define DIR_COLOR ANSCII BOLD NEXT NORMAL BLUE COLOR
@@ -28,7 +29,7 @@ static struct {
struct FileInfo {
struct passwd* usr;
struct group* grp;
- char name[PATH_MAX];
+ char* name;
char date[13];
char mode[11];
char size[5];
@@ -62,41 +63,27 @@ static DIR* get_directory(char* path) {
return d;
}
-static void append_path(char buf[PATH_MAX], const char* dir_path, const char* file_path) {
- size_t dir_len = strlen(dir_path);
- size_t file_len = strlen(file_path);
-
- memcpy(buf, dir_path, dir_len);
- if (buf[dir_len-1] != '/') {
- buf[dir_len] = '/';
- dir_len++;
- }
- memcpy(buf + dir_len, file_path, file_len);
- buf[dir_len + file_len] = '\0';
-}
-
-static bool get_file_info(const char* file_path, const char* dir_path, struct FileInfo* info) {
+static bool get_file_info(const char* file_name, struct FileInfo* info) {
uid_t uid = getuid();
gid_t gid = getgid();
- char buf[PATH_MAX];
- append_path(buf, dir_path, file_path);
-
struct stat s;
memset(&s, 0, sizeof(struct stat));
- if (lstat(buf, &s) < 0) {
- printf("\x1b[0merror: failed to read file '%s': %s\n", buf, strerror(errno));
+ int save = push_path_buffer(file_name);
+
+ if (lstat(get_path_buffer(), &s) < 0) {
+ printf("\x1b[0merror: failed to read file '%s': %s\n", get_path_buffer(), strerror(errno));
+ pop_path_buffer(save);
return false;
}
-
+
int ty = (s.st_mode & S_IFMT) >> 12;
info->set_uid = false;
info->set_gid = false;
info->exec = false;
- info->name[0] = '\0';
switch (ty) {
case DT_BLK:
@@ -168,17 +155,32 @@ static bool get_file_info(const char* file_path, const char* dir_path, struct Fi
info->mode[10] = '\0';
info->usr = getpwuid(s.st_uid);
+ if (info->usr == NULL) {
+ fprintf(stderr, "error: failed to get user from %s\n", get_path_buffer());
+ pop_path_buffer(save);
+ return false;
+ }
+
info->grp = getgrgid(s.st_gid);
+ if (info->grp == NULL) {
+ fprintf(stderr, "error: failed to get user from %s\n", get_path_buffer());
+ pop_path_buffer(save);
+ return false;
+ }
+
info->links = s.st_nlink;
info->type = ty;
- strcpy(info->name, file_path);
+ size_t file_len = strlen(file_name) + 1;
+ info->name = malloc(file_len);
+ memcpy(info->name, file_name, file_len);
print_file_size(s.st_size, info->size);
print_date_time(s.st_mtim.tv_sec + s.st_mtim.tv_nsec / 1000000000, info->date);
- info->bytes = (s.st_size + s.st_blksize - 1) / s.st_blksize * s.st_blksize;
+ info->bytes = (s.st_size + s.st_blksize - 1) / s.st_blksize;
+ pop_path_buffer(save);
return true;
}
@@ -213,7 +215,7 @@ static char* get_file_color(struct FileInfo* info) {
return color;
}
-static void list_files(struct FileInfo* files, int file_len, struct FileListInfo info, const char* dir_path) {
+static void list_files(struct FileInfo* files, int file_len, struct FileListInfo info) {
if (flags.more_info) {
char total[13];
@@ -254,17 +256,17 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo
flags.colored != NO ? "\x1b[0m" : ""
);
if (finfo.type == DT_LNK) {
- char path[PATH_MAX];
- append_path(path, dir_path, finfo.name);
+ int save = push_path_buffer(finfo.name);
char lnk[PATH_MAX];
ssize_t n;
- if ((n = readlink(path, lnk, PATH_MAX)) != -1) {
+ if ((n = readlink(get_path_buffer(), lnk, PATH_MAX)) != -1) {
printf(" -> %.*s\n", (int)n, lnk);
} else {
putchar('\n');
}
-
+
+ pop_path_buffer(save);
} else {
putchar('\n');
}
@@ -280,6 +282,7 @@ static void list_files(struct FileInfo* files, int file_len, struct FileListInfo
flags.colored != NO ? "\x1b[0m" : "");
}
}
+ free(finfo.name);
}
if (!flags.more_info) printf("\n");
@@ -303,12 +306,10 @@ static void push_file(
struct FileInfo** files,
struct FileListInfo* info,
int* size, int* capacity,
- const char* file_path,
- const char* dir_path
+ const char* file_path
) {
-
struct FileInfo finfo;
- if (!get_file_info(file_path, dir_path, &finfo)) return;
+ if (!get_file_info(file_path, &finfo)) return;
if (*size == *capacity) {
*capacity *= 2;
@@ -336,13 +337,15 @@ static void push_file(
(*size)++;
}
-static bool recurse_directory(char* path) {
+static void recurse_directory(char* dir_name) {
DIR* d;
struct dirent* file;
- bool first = true;
+ int save = push_path_buffer(dir_name);
- d = get_directory(path);
- if (d == NULL) return false;
+ d = get_directory(get_path_buffer());
+ if (d == NULL) {
+ return;
+ }
int capacity = 8;
int size = 0;
@@ -351,50 +354,42 @@ static bool recurse_directory(char* path) {
memset(&info, 0, sizeof(struct FileListInfo));
while((file = readdir(d)) != NULL) {
- if (file->d_type == DT_DIR && !is_dot_dir(file->d_name)) continue;
if (!flags.hidden && prefix(".", file->d_name)) continue;
if (flags.hide_dot && is_dot_dir(file->d_name)) continue;
- if (first) {
- if (flags.colored == NO)
- printf("\n%s:\n", path);
- else
- printf("\n%s%s:%s\n", DIR_COLOR, path, FILE_COLOR);
- first = false;
+ if (file->d_type == DT_DIR && !is_dot_dir(file->d_name)) {
+ recurse_directory(file->d_name);
+ } else {
+ push_file(&files, &info, &size, &capacity, file->d_name);
}
- push_file(&files, &info, &size, &capacity, file->d_name, path);
}
-
- list_files(files, size, info, path);
- free(files);
- if (!flags.more_info) printf("\n");
- closedir(d);
+ if (flags.colored == NO)
+ printf("\n%s:\n", get_path_buffer());
+ else
+ printf("\n%s%s:%s\n", DIR_COLOR, get_path_buffer(), FILE_COLOR);
- d = get_directory(path);
- if (d == NULL) return false;
-
- while((file = readdir(d)) != NULL) {
- if (file->d_type != DT_DIR) continue;
- if (!flags.hidden && prefix(".", file->d_name)) continue;
- if (is_dot_dir(file->d_name)) continue;
- char buf[PATH_MAX];
- append_path(buf, path, file->d_name);
- recurse_directory(buf);
- }
+ list_files(files, size, info);
+
+ free(files);
+
+ if (!flags.more_info) printf("\n");
closedir(d);
- return true;
+ pop_path_buffer(save);
}
-static bool list_directory(char* path) {
+static void list_directory(char* path) {
if (flags.recurse) {
- return recurse_directory(path);
+ recurse_directory(path);
+ return;
}
DIR* d = get_directory(path);
- if (d == NULL) return false;
+ if (d == NULL) return;
+
+ int save = push_path_buffer(path);
int capacity = 8;
int size = 0;
@@ -406,14 +401,15 @@ static bool list_directory(char* path) {
while ((file = readdir(d)) != NULL) {
if (!flags.hidden && prefix(".", file->d_name)) continue;
if (flags.hide_dot && is_dot_dir(file->d_name)) continue;
- push_file(&files, &info, &size, &capacity, file->d_name, path);
+ push_file(&files, &info, &size, &capacity, file->d_name);
}
- if (size > 0) list_files(files, size, info, path);
+ if (size > 0) list_files(files, size, info);
free(files);
-
+
+ pop_path_buffer(save);
+
closedir(d);
- return true;
}
static bool is_dir(const char* path) {
@@ -431,10 +427,10 @@ static void list_file_args(int start, int argc, char** argv) {
for (int i = start; i < argc; i++) {
if (is_dir(argv[i])) continue;
- push_file((struct FileInfo**) &files, &info, &size, &capacity, argv[i], argv[i][0] == '/' ? "" : ".");
+ push_file((struct FileInfo**) &files, &info, &size, &capacity, argv[i]);
}
- if (size > 0) list_files(files, size, info, ".");
+ if (size > 0) list_files(files, size, info);
free(files);
}
diff --git a/src/commands/printf.c b/src/commands/printf.c
index 4663a86..f9f3931 100644
--- a/src/commands/printf.c
+++ b/src/commands/printf.c
@@ -75,8 +75,6 @@ static void handle_slash(char n) {
case 'f':
putchar('\f');
break;
- case 'e':
- putchar('\e');
case 'a':
putchar('\a');
break;
diff --git a/src/util/shared.c b/src/util/shared.c
index 3e6fca3..600a967 100644
--- a/src/util/shared.c
+++ b/src/util/shared.c
@@ -1,6 +1,7 @@
#include "shared.h"
#include <errno.h>
+#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -232,3 +233,25 @@ FILE* get_tty_stream(char* type) {
return file;
}
+static char path_buffer[PATH_MAX + 1];
+static int path_buffer_index = 0;
+
+char* get_path_buffer() {
+ return path_buffer;
+}
+
+int push_path_buffer(const char* string) {
+ int save = path_buffer_index;
+ if (path_buffer_index > 1 || (path_buffer_index == 1 && path_buffer[0] != '/')) {
+ path_buffer[path_buffer_index++] = '/';
+ }
+ int string_len = strlen(string);
+ memcpy(path_buffer + path_buffer_index, string, string_len + 1);
+ path_buffer_index += string_len;
+ return save;
+}
+
+void pop_path_buffer(int i) {
+ path_buffer_index = i;
+ path_buffer[path_buffer_index] = '\0';
+}
diff --git a/src/util/shared.h b/src/util/shared.h
index c0945c1..9bade52 100644
--- a/src/util/shared.h
+++ b/src/util/shared.h
@@ -57,3 +57,8 @@ int parse_args (int argc, char** argv, void (*help)(void), int (*short_arg)(char
int get_tty();
FILE* get_tty_stream(char* type);
+
+char* get_path_buffer();
+int push_path_buffer(const char* string);
+void pop_path_buffer(int i);
+