Commit bf73a988 authored by Seblu's avatar Seblu
Browse files

No commit message

No commit message
parent 30a57534
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ bin_PROGRAMS=42sh
		src/exec/exec_node.c			\
		src/exec/exec_or.c			\
		src/exec/exec_if.c			\
		src/exec/exec_red.c			\
		src/exec/exec_sep.c			\
		src/exec/exec_sepand.c			\
		src/exec/exec_while.c			\

src/builtin/builtin.c

0 → 100644
+105 −0
Original line number Diff line number Diff line
/*
** builtin.c for 42sh
**
** Made by Seblu
** Login   <seblu@epita.fr>
**
** Started on  Tue Apr 11 00:22:44 2006 Seblu
** Last update Sun Nov 12 16:47:59 2006 Seblu
*/

#include <string.h>
#include <unistd.h>
#include <assert.h>
#include "builtin.h"
#include "../main/42sh.h"
#include "../ast/ast.h"
#include "../opt/opt.h"

#define BUILTIN_NUMBER 7
#define BUILTIN_BONUS_NUMBER 7

static const char *builtin_name[BUILTIN_NUMBER] =
  {
    "cd",
    "echo",
    "exit",
    "shopt",
    "source",
    "unset",
    "export"
  };

static const char *builtin_bonus_name[BUILTIN_BONUS_NUMBER] =
  {
    ".",
    "..",
    "set",
    "varlist",
    "funclist",
    "exec",
    "history"
  };

static const t_func_builtin builtin_function[BUILTIN_NUMBER] =
  {
    builtin_cd,
    builtin_echo,
    builtin_exit,
    builtin_shopt,
    builtin_source,
    builtin_unset,
    builtin_export
  };

static const t_func_builtin builtin_bonus_function[BUILTIN_BONUS_NUMBER] =
  {
    builtin_simpledot,
    builtin_doubledot,
    builtin_set,
    builtin_varlist,
    builtin_funclist,
    builtin_exec,
    builtin_history
  };

/*!
** test if a command is a builtin
**
** @param name The name of the command
** @return 1 if \a name is a builtin, else 0
*/
int		is_a_builtin(const char *name, struct s_42sh *sh)
{
  register int	i;

  for (i = 0; i < BUILTIN_NUMBER; ++i)
    if (!strcmp(name, builtin_name[i]))
      return 1;
  if (opt_isset("bonus", sh->opt))
    for (i = 0; i < BUILTIN_BONUS_NUMBER; ++i)
      if (!strcmp(name, builtin_bonus_name[i]))
	return 1;
  return 0;
}

/*!
** execute a shell builtin
**
** @param builtin_name The name of the builtin
** @param argv The builtin arguments, terminate by NULL, argv[0] = builtin_name
** @return The return value of the builtin
*/
int		exec_builtin(struct s_cmd *cmd, struct s_42sh *sh)
{
  register int	i;

  for (i = 0; i < BUILTIN_NUMBER; ++i)
    if (!strcmp(cmd->argv[0], builtin_name[i]))
      return builtin_function[i](cmd->argv, sh);
  if (opt_isset("bonus", sh->opt))
    for (i = 0; i < BUILTIN_BONUS_NUMBER; ++i)
      if (!strcmp(cmd->argv[0], builtin_bonus_name[i]))
	return builtin_bonus_function[i](cmd->argv, sh);
  return 0;
}

src/builtin/builtin.h

0 → 100644
+44 −0
Original line number Diff line number Diff line
/*
** builtin.h for 42sh in /home/seblu/svn/42sh
**
** Made by Seblu
** Login   <seblu@epita.fr>
**
** Started on  Sun Nov 12 16:46:24 2006 Seblu
** Last update Sun Nov 12 16:47:03 2006 Seblu
*/

#ifndef BUILTIN_H_
# define BUILTIN_H_

struct s_42sh;
struct s_cmd;

typedef int (*t_func_builtin)(char *argv[], struct s_42sh *sh);

int	is_a_builtin(const char *name, struct s_42sh *sh);
int	exec_builtin(struct s_cmd *cmd, struct s_42sh *sh);

/*
** Regular builtin
*/
int	builtin_cd(char *argv[], struct s_42sh *sh);
int	builtin_echo(char *argv[], struct s_42sh *sh);
int	builtin_shopt(char *argv[], struct s_42sh *sh);
int	builtin_exit(char *argv[], struct s_42sh *sh);
int	builtin_source(char *argv[], struct s_42sh *sh);
int	builtin_unset(char *argv[], struct s_42sh *sh);
int	builtin_export(char *argv[], struct s_42sh *sh);

/*
** Bonus builtin
*/
int	builtin_simpledot(char *argv[], struct s_42sh *sh);
int	builtin_doubledot(char *argv[], struct s_42sh *sh);
int	builtin_set(char *argv[], struct s_42sh *sh);
int	builtin_varlist(char *argv[], struct s_42sh *sh);
int	builtin_funclist(char *argv[], struct s_42sh *sh);
int	builtin_exec(char *argv[], struct s_42sh *sh);
int	builtin_history(char *argv[], struct s_42sh *sh);

#endif /* ! BUILTIN_H_ */
+113 −0
Original line number Diff line number Diff line
/*
** builtin_cd.c for 42sh in /home/seblu/devel/c/42sh/src/execution
**
** Made by Seblu
** Login   <seblu@epita.fr>
**
** Started on  Tue Apr 11 00:23:47 2006 Seblu
** Last update Sun May 21 19:17:53 2006 Seblu
*/

#include <ctype.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "../main/42sh.h"
#include "builtin.h"
#include "../var/var.h"

#include "mem.h"

static int cd_var(struct s_42sh *sh, const char *name);
static int cd_minus(struct s_42sh *sh);
static int secure_chdir(const char *path);

/*!
** Builtin cd.
** @param argv The tab of args: terminated by NULL, argv[0] = "cd"
** @param sh The 42sh structure
*/
int	builtin_cd(char **argv, struct s_42sh *sh)
{
  assert(sh && argv && argv[0]);

  if (!argv[1])
    return cd_var(sh, "HOME");
  if (!strcmp("-", argv[1]))
    return cd_minus(sh);
  return secure_chdir(argv[1]);
}

/*!
** Change directory to home directory
**
** @param sh shell env
** @param name env var
**
** @return exit status
*/
static int	cd_var(struct s_42sh *sh, const char *name)
{
  const char	*new_dir;

  if (!(new_dir = var_get(sh->vars, name)))
  {
    fprintf(stderr, "42sh: cd: %s not set\n", name);
    return 1;
  }
  return secure_chdir(new_dir);
}

/*!
** Return in previous directory
**
** @param sh shell info
**
** @return return status
*/
static int	cd_minus(struct s_42sh *sh)
{
  if (cd_var(sh, "OLDPWD"))
    return 1;
  return 0;
}

/*!
** 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)
{
  const char	*errormsg = "";
  char		*tmp;

  errno = 0;
  if (chdir(path))
  {
    if (errno == ENOENT)
      errormsg = "No such file or directory";
    else if (errno == EACCES)
      errormsg = "Permission denied";
    else if (errno == ENAMETOOLONG)
      errormsg = "File name too long";
    else if (errno == ENOTDIR)
      errormsg = "Not a directory";
    else if (errno == ELOOP)
      errormsg = "Too many levels of symbolic links";
    else
      assert(0);
    fprintf(stderr, "42sh: cd %s: %s\n", path, errormsg);
    return 1;
  }
  if ((tmp = getenv("PWD")))
    var_setenv("OLDPWD", tmp, !0);
  var_setenv("PWD", (tmp = var_getcwd()), !0);
  free(tmp);
  return 0;
}
+33 −0
Original line number Diff line number Diff line
/*
** builtin_doubledot.c for 42sh in /home/seblu/devel/c/towork/42sh
**
** Made by Seblu
** Login   <seblu@epita.fr>
**
** Started on  Sat Apr  8 18:02:31 2006 Seblu
** Last update Sun Apr  9 12:38:38 2006 SIGOURE Benoit
*/

#include <stddef.h>
#include "builtin.h"

#include "mem.h"

/*!
** Builtin double dot, allow you to cdup
**
** @param argv argv vector
** @param sh sh data
**
** @return builtin return success
*/
int		builtin_doubledot(char *argv[], struct s_42sh *sh)
{
  char		*argv2[3];

  argv2[0] = "cd";
  argv2[1] = "..";
  argv2[2] = NULL;
  return builtin_cd(argv2, sh);
  argv = argv;
}
Loading