summaryrefslogtreecommitdiff
path: root/42sh/src/builtins/cd.c
diff options
context:
space:
mode:
Diffstat (limited to '42sh/src/builtins/cd.c')
-rw-r--r--42sh/src/builtins/cd.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/42sh/src/builtins/cd.c b/42sh/src/builtins/cd.c
new file mode 100644
index 0000000..90fd9db
--- /dev/null
+++ b/42sh/src/builtins/cd.c
@@ -0,0 +1,74 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "builtins.h"
+#include "utils/env.h"
+
+int cd_pointpoint(char *path, char *old)
+{
+ char *current = strrchr(path, '/');
+ size_t len = current - path;
+ if (len == 0)
+ {
+ fprintf(stderr, "cd: error with ..\n");
+ return 2;
+ }
+ char *parent = malloc(len + 1);
+ memcpy(parent, current, len);
+ parent[len] = '\0';
+ old = path;
+ path = parent;
+ env_set("OLDPWD", old);
+ env_set("PWD", path);
+ free(parent);
+
+ return 0;
+}
+
+int cd(struct string **args)
+{
+ if (args[0] == NULL || args[1] != NULL)
+ {
+ fprintf(stderr, "cd: error too many arguments\n");
+ fflush(stdout);
+ return 2;
+ }
+ if (strcmp(env_get("PWD"), "") == 0)
+ {
+ fprintf(stderr, "cd: error with PWD\n");
+ fflush(stdout);
+ return 2;
+ }
+ char *old = env_get("OLDPWD");
+ char *path = env_get("PWD");
+ char *tmp = old;
+ if (strcmp(args[0]->data, "-") == 0)
+ {
+ if (strcmp(old, "") == 0)
+ {
+ fprintf(stderr, "cd: error with OLDPWD\n");
+ fflush(stdout);
+ return 2;
+ }
+ printf("%s\n", old);
+ old = path;
+ path = tmp;
+ }
+ else if (strcmp(args[0]->data, "..") == 0)
+ {
+ int res = cd_pointpoint(path, old);
+ fflush(stdout);
+ return res;
+ }
+ else
+ {
+ old = path;
+ path = args[0]->data;
+ }
+ env_set("OLDPWD", old);
+ env_set("PWD", path);
+ fflush(stdout);
+ return 0;
+}