Commit cff93e34 authored by Noah Loomans's avatar Noah Loomans

builtin/cd: fix SEGFAULT when HOME or PWD has not been set

This can be reproduced using:

  $ env -i ./minishell
  cd -

and

  $ env -i ./minishell
  cd

and

  $ env -i ./minishell
  cd ~
parent 6411d842
......@@ -28,5 +28,6 @@ int env_unset(struct s_env **env, char *key);
char **env_to_envp(struct s_env *env);
void env_free(struct s_env **env);
int env_is_valid_key(char *key);
int env_has(struct s_env *env, char *key);
#endif
......@@ -21,39 +21,39 @@
#include "env.h"
#include "builtin.h"
static void cd(t_env **env, char *cwd)
static int cd(t_env **env, char *old_path, char *new_path)
{
char *old_pwd;
old_pwd = env_get(*env, "PWD");
env_set(env, "OLDPWD", old_pwd);
env_set(env, "PWD", cwd);
ft_strdel(&old_pwd);
if (chdir(new_path) == -1)
return (-1);
env_set(env, "OLDPWD", old_path);
env_set(env, "PWD", new_path);
return (0);
}
int builtin_cd(int argc, char **argv, t_env **env)
{
char to_path[PATH_MAX];
char cwd[PATH_MAX];
char old_path[PATH_MAX];
char new_path[PATH_MAX];
getcwd(cwd, PATH_MAX);
getcwd(old_path, PATH_MAX);
if (argc > 2)
return (ft_eprintf(1, "cd: to many arguments\n"));
if (argc == 1)
ft_strlcpy(to_path, env_get_unsafe_ptr(*env, "HOME"), PATH_MAX);
else if (ft_strncmp(argv[1], "~", 1) == 0)
ft_snprintf(to_path, PATH_MAX, "%s%s",
env_get_unsafe_ptr(*env, "HOME"), argv[1] + 1);
{
if (!env_has(*env, "HOME"))
return (ft_eprintf(1, "cd: $HOME not set\n"));
ft_strlcpy(new_path, env_get_unsafe_ptr(*env, "HOME"), PATH_MAX);
}
else if (ft_strcmp(argv[1], "-") == 0)
{
ft_strlcpy(to_path, env_get_unsafe_ptr(*env, "OLDPWD"), PATH_MAX);
ft_printf("%s\n", to_path);
if (!env_has(*env, "OLDPWD"))
return (ft_eprintf(1, "cd: $OLDPWD not set\n"));
ft_strlcpy(new_path, env_get_unsafe_ptr(*env, "OLDPWD"), PATH_MAX);
ft_printf("%s\n", new_path);
}
else
ft_strlcpy(to_path, argv[1], PATH_MAX);
if (chdir(to_path) == 0)
cd(env, cwd);
else
return (ft_eprintf(1, "cd: unable to change dir '%s'\n", to_path));
ft_strlcpy(new_path, argv[1], PATH_MAX);
if (cd(env, old_path, new_path) == -1)
return (ft_eprintf(1, "cd: unable to change dir '%s'\n", new_path));
return (0);
}
......@@ -69,3 +69,8 @@ int env_unset(struct s_env **head, char *key)
*head = next;
return (0);
}
int env_has(struct s_env *env, char *key)
{
return (env_get_unsafe_ptr(env, key) != NULL);
}
......@@ -75,10 +75,10 @@ static char *expand_arg(t_env *env, char *arg)
size_t offset;
char *new_line;
if (ft_strncmp(arg, "~/", 2) == 0)
if (env_has(env, "HOME") && ft_strncmp(arg, "~/", 2) == 0)
ft_asprintf(&new_line, "%s/%s",
env_get_unsafe_ptr(env, "HOME"), arg + 2);
else if (ft_strcmp(arg, "~") == 0)
else if (env_has(env, "HOME") && ft_strcmp(arg, "~") == 0)
new_line = env_get(env, "HOME");
else
new_line = ft_strdup(arg);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment