Skip to content

Commit

Permalink
userland: add "grep" command
Browse files Browse the repository at this point in the history
  • Loading branch information
mosmeh committed Jun 21, 2024
1 parent 644f029 commit e1766f0
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
1 change: 1 addition & 0 deletions userland/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ BIN_TARGET_NAMES := \
env \
eyes \
fib \
grep \
halt \
imgview \
init \
Expand Down
69 changes: 69 additions & 0 deletions userland/grep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// grep - print lines matching a pattern
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char* const argv[]) {
if (argc < 2) {
dprintf(STDERR_FILENO, "Usage: grep PATTERN [FILE]...\n");
return EXIT_FAILURE;
}

const char* pattern = argv[1];

for (int i = 2; i < argc; i++) {
const char* filename = argv[i];

struct stat st;
if (stat(filename, &st) < 0) {
perror("stat");
return EXIT_FAILURE;
}

char* buf = malloc(st.st_size + 1); // +1 for null terminator
if (!buf) {
perror("malloc");
return EXIT_FAILURE;
}

int fd = open(filename, O_RDONLY);
if (fd < 0) {
perror("open");
goto done;
}

size_t cursor = 0;
ssize_t nread;
while ((nread = read(fd, buf + cursor, st.st_size - cursor)) > 0)
cursor += nread;
if (nread < 0) {
perror("read");
goto done;
}
close(fd);
fd = -1;
buf[cursor] = 0;

static const char* sep = "\n";
char* saved_ptr;
for (char* line = strtok_r(buf, sep, &saved_ptr); line;
line = strtok_r(NULL, sep, &saved_ptr)) {
if (strstr(line, pattern)) {
if (argc > 3)
printf("%s:%s\n", filename, line);
else
puts(line);
}
}

done:
free(buf);
if (fd >= 0)
close(fd);
}

return EXIT_SUCCESS;
}

0 comments on commit e1766f0

Please sign in to comment.