From 6a0845d54a2d516cfa57f9035e07ab40f85e1e06 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sun, 18 Nov 2018 09:56:43 +0900 Subject: [PATCH] dirname: add command and libc function --- apps/dirname.c | 22 ++++++++++++++++++ base/usr/include/libgen.h | 2 +- libc/libgen/dirname.c | 48 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 apps/dirname.c create mode 100644 libc/libgen/dirname.c diff --git a/apps/dirname.c b/apps/dirname.c new file mode 100644 index 00000000..eaf4c5af --- /dev/null +++ b/apps/dirname.c @@ -0,0 +1,22 @@ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * This file is part of ToaruOS and is released under the terms + * of the NCSA / University of Illinois License - see LICENSE.md + * Copyright (C) 2018 K. Lange + * + * dirname - print directory name from path string + */ +#include +#include +#include + +int main(int argc, char * argv[]) { + if (argc < 2) { + fprintf(stderr, "%s: expected argument\n", argv[0]); + return 1; + } + + char * c = dirname(argv[1]); + fprintf(stdout, "%s\n", c); + return 0; +} + diff --git a/base/usr/include/libgen.h b/base/usr/include/libgen.h index e1de5d75..93b13279 100644 --- a/base/usr/include/libgen.h +++ b/base/usr/include/libgen.h @@ -4,7 +4,7 @@ _Begin_C_Header -//extern char * dirname(char * path); +extern char * dirname(char * path); extern char * basename(char * path); _End_C_Header diff --git a/libc/libgen/dirname.c b/libc/libgen/dirname.c new file mode 100644 index 00000000..480abc2a --- /dev/null +++ b/libc/libgen/dirname.c @@ -0,0 +1,48 @@ +#include +#include +#include + +char * dirname(char * path) { + int has_slash = 0; + char * c = path; + while (*c) { + if (*c == '/') { + has_slash = 1; + } + c++; + } + if (!has_slash) { + return "."; + } + + c--; + while (*c == '/') { + *c = '\0'; + if (c == path) break; + c--; + } + + if (c == path) { + return "/"; + } + + /* All trailing slashes are cleared out */ + while (*c != '/') { + *c = '\0'; + if (c == path) break; + c--; + } + + if (c == path) { + if (*c == '/') return "/"; + return "."; + } + + while (*c == '/') { + if (c == path) return "/"; + *c = '\0'; + c--; + } + + return path; +}