Skip to content
builtin_cd.c 1.55 KiB
Newer Older
Seblu's avatar
Seblu committed
/*
Seblu's avatar
Seblu committed
** builtin_cd.c for 42sh
Seblu's avatar
Seblu committed
**
** Made by Seblu
** Login   <seblu@epita.fr>
**
** Started on  Tue Apr 11 00:23:47 2006 Seblu
Seblu's avatar
Seblu committed
** Last update Thu Nov 16 16:57:54 2006 seblu
Seblu's avatar
Seblu committed
*/

#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
Seblu's avatar
Seblu committed
#include <string.h>
Seblu's avatar
Seblu committed
#include <unistd.h>
Seblu's avatar
Seblu committed
#include "../common/function.h"
#include "../shell/shell.h"
#include "../shell/var.h"
Seblu's avatar
Seblu committed

Seblu's avatar
Seblu committed
/*
** ============
** DECLARATIONS
** ============
*/
Seblu's avatar
Seblu committed

/*!
Seblu's avatar
Seblu committed
** Change directory to home directory
**
** @param name env var
**
** @return success status
Seblu's avatar
Seblu committed
*/
Seblu's avatar
Seblu committed
static int	cd_var(const char *name);

/*!
** Change of directory and on error, print good error.
**
** @param path new path
**
** @return error status with error code (0 is good)
*/
static int	secure_chdir(const char *path);

/*
** ===========
** DEFINITIONS
** ===========
*/

int		builtin_cd(char **argv)
Seblu's avatar
Seblu committed
{
Seblu's avatar
Seblu committed
  assert(argv && argv[0]);
Seblu's avatar
Seblu committed

  if (!argv[1])
Seblu's avatar
Seblu committed
    return cd_var("HOME");
Seblu's avatar
Seblu committed
  if (!strcmp("-", argv[1]))
Seblu's avatar
Seblu committed
    return cd_var("OLDPWD");
Seblu's avatar
Seblu committed
  return secure_chdir(argv[1]);
}

Seblu's avatar
Seblu committed
static int	cd_var(const char *name)
Seblu's avatar
Seblu committed
{
  const char	*new_dir;

Seblu's avatar
Seblu committed
  if (!(new_dir = var_get(shell->var, name))) {
    fprintf(stderr, "%s: cd: %s not set\n", shell->name, name);
Seblu's avatar
Seblu committed
    return 1;
  }
  return secure_chdir(new_dir);
}

static int	secure_chdir(const char *path)
{
  char		*tmp;

Seblu's avatar
Seblu committed
  if (chdir(path)) {
    fprintf(stderr, "%s: cd %s: %s\n", shell->name, path, strerror(errno));
Seblu's avatar
Seblu committed
    return 1;
  }
Seblu's avatar
Seblu committed
  //FIXME: getenv return name=val and setenv2 take cut arguments
Seblu's avatar
Seblu committed
  if ((tmp = getenv("PWD")))
Seblu's avatar
Seblu committed
    setenv2("OLDPWD", tmp, !0);
  setenv2("PWD", (tmp = getcwd2()), !0);
Seblu's avatar
Seblu committed
  return 0;
}