restart: deleted all source and header files, restarting project
This commit is contained in:
BIN
.github/README/minishelln.png
vendored
Normal file
BIN
.github/README/minishelln.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
129
README.md
129
README.md
@@ -1,23 +1,118 @@
|
|||||||
## Dependencies
|
<div align="center">
|
||||||
|
|
||||||
- Debian/Ubuntu
|
<!-- Project badge -->
|
||||||
```
|
<a href=".">
|
||||||
sudo apt-get install make libreadline-dev
|
<img src=".github/README/minishelln.png">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Project name -->
|
||||||
|
<h1>minishell</h1>
|
||||||
|
|
||||||
|
<!-- Short description -->
|
||||||
|
<p>A simple bash-like shell written in C.</p>
|
||||||
|
|
||||||
|
<!-- Info badges -->
|
||||||
|
<img src="https://img.shields.io/badge/Score-No-black?style=for-the-badge&labelColor=black" alt="Score">
|
||||||
|
<!-- <img src="https://img.shields.io/badge/Score-100%2F100-brightgreen?style=for-the-badge&labelColor=black" alt="Score"> -->
|
||||||
|
<!-- <img src="https://img.shields.io/badge/Score-125%2F100-brightgreen?style=for-the-badge&labelColor=black" alt="Score"> -->
|
||||||
|
<img src="https://img.shields.io/badge/Language-C-blue?style=for-the-badge&labelColor=black" alt="Language">
|
||||||
|
<br>
|
||||||
|
<img src="https://img.shields.io/github/last-commit/sdevsantiago/minishell?display_timestamp=committer&style=for-the-badge&labelColor=black" alt="Last commit">
|
||||||
|
<br>
|
||||||
|
<img src="https://github.com/sdevsantiago/minishell/actions/workflows/norminette.yml/badge.svg">
|
||||||
|
<img src="https://github.com/sdevsantiago/minishell/actions/workflows/makefile.yml/badge.svg">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ℹ️ About Project
|
||||||
|
|
||||||
|
> The purpose of this project is to create a simple bash-like shell.
|
||||||
|
|
||||||
|
DETAILED INFO
|
||||||
|
|
||||||
|
For detailed info, refer to this project [subject](docs/en.subject.pdf).
|
||||||
|
|
||||||
|
## 🚀 Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- GCC compiler
|
||||||
|
- Make utility
|
||||||
|
- Unix-like system (Linux, macOS, WSL)
|
||||||
|
|
||||||
|
### Install prerequisites
|
||||||
|
|
||||||
|
- APT
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install build-essential libreadline-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
- Pacman
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pacman -Sy base-devel readline-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Build
|
||||||
|
|
||||||
|
1. **Clone the repository:**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/sdevsantiago/minishell.git
|
||||||
|
cd minishell
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Compile the project:**
|
||||||
|
```bash
|
||||||
|
make # Full compilation
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Clean build files:**
|
||||||
|
```bash
|
||||||
|
make clean # Remove object files
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Available Make Targets
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `make` | Compiles all |
|
||||||
|
| `make all` | Same as `make` |
|
||||||
|
| `make clean` | Remove object files (*.o) |
|
||||||
|
| `make fclean` | Remove object files and binaries |
|
||||||
|
| `make re` | Clean and rebuild everything |
|
||||||
|
|
||||||
|
## 👨💻 Usage
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
INSTRUCTIONS
|
||||||
|
|
||||||
|
## 📏 Norminette
|
||||||
|
|
||||||
|
The code strictly complies with 42's **Norminette v4**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
norminette *.c *.h
|
||||||
```
|
```
|
||||||
|
|
||||||
## How to install
|
More info in the official [Norminette](https://github.com/42school/norminette) repository.
|
||||||
|
|
||||||
1. Clone the repository
|
## 🙇♂️ Special thanks
|
||||||
```
|
|
||||||
git clone https://github.com/sdevsantiago/minishell.git && cd minishell
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Build the project
|
- [lrcouto](https://github.com/lrcouto) and [ayogun](https://github.com/ayogun) for creating and publishing, respectively, the [42-project-badges](https://github.com/ayogun/42-project-badges) repository.
|
||||||
```
|
- [gcamerli](https://github.com/gcamerli) for creating the [42unlicense](https://github.com/gcamerli/42unlicense) repository.
|
||||||
make && make clean
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Execute the program
|
## ⚖️ License
|
||||||
```
|
|
||||||
./minishell
|
<div align="center">
|
||||||
```
|
|
||||||
|
<a href="./LICENSE">
|
||||||
|
<img src="https://img.shields.io/badge/License-42_Unlicense-red?style=for-the-badge&labelColor=black">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
**This work is published under the terms of [42 Unlicense](LICENSE).** This means you are free to use, modify, and share this software.
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* builtins.h :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 17:18:21 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/20 22:22:40 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#ifndef BUILTINS_H
|
|
||||||
# define BUILTINS_H
|
|
||||||
|
|
||||||
# include <string.h>
|
|
||||||
# include <stdio.h>
|
|
||||||
|
|
||||||
// cd.c
|
|
||||||
|
|
||||||
int cd_builtin(int argc, char const *argv[]);
|
|
||||||
|
|
||||||
# define CD_HELP
|
|
||||||
|
|
||||||
// echo.c
|
|
||||||
|
|
||||||
typedef struct s_echo_flags
|
|
||||||
{
|
|
||||||
int newline; // print newline after everything has been printed
|
|
||||||
} t_echo_flags;
|
|
||||||
|
|
||||||
int echo_builtin(int argc, char const *argv[]);
|
|
||||||
|
|
||||||
# define ECHO_HELP
|
|
||||||
|
|
||||||
// // env.c
|
|
||||||
|
|
||||||
// int env_builtin(int argc, char const *argv[], char **envp);
|
|
||||||
|
|
||||||
// exit.c
|
|
||||||
|
|
||||||
int exit_builtin(int argc, char const *argv[]);
|
|
||||||
|
|
||||||
# define EXIT_HELP
|
|
||||||
|
|
||||||
// export.c
|
|
||||||
|
|
||||||
int export_builtin(int argc, char const *argv[], char **envp);
|
|
||||||
|
|
||||||
# define EXPORT_HELP
|
|
||||||
|
|
||||||
// printenv.c
|
|
||||||
|
|
||||||
int printenv_builtin(int argc, char const *argv[], char const *envp[]);
|
|
||||||
|
|
||||||
# define PRINTENV_HELP
|
|
||||||
|
|
||||||
// pwd.c
|
|
||||||
|
|
||||||
int pwd_builtin(int argc, char const *argv[]);
|
|
||||||
|
|
||||||
# define PWD_HELP
|
|
||||||
|
|
||||||
// unset.c
|
|
||||||
|
|
||||||
int unset_builtin(int argc, char const *argv[], char **envp);
|
|
||||||
|
|
||||||
# define UNSET_HELP
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* history.h :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/20 22:07:04 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/21 14:43:08 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#ifndef HISTORY_H
|
|
||||||
# define HISTORY_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// history.c
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* minishell.h :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/07/31 03:42:51 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/21 14:55:18 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#ifndef MINISHELL_H
|
|
||||||
# define MINISHELL_H
|
|
||||||
|
|
||||||
# include "builtins.h"
|
|
||||||
# include "history.h"
|
|
||||||
# include "libft.h"
|
|
||||||
# include "get_next_line.h"
|
|
||||||
# include <fcntl.h>
|
|
||||||
# include <signal.h>
|
|
||||||
# include <readline/history.h>
|
|
||||||
# include <readline/readline.h>
|
|
||||||
# include <sys/wait.h>
|
|
||||||
|
|
||||||
typedef struct s_cmd
|
|
||||||
{
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
} t_cmd;
|
|
||||||
|
|
||||||
typedef struct s_history
|
|
||||||
{
|
|
||||||
char *hist_file;
|
|
||||||
size_t hist_file_size;
|
|
||||||
t_cdlist hist;
|
|
||||||
size_t hist_size;
|
|
||||||
} t_history;
|
|
||||||
|
|
||||||
typedef struct s_minishell
|
|
||||||
{
|
|
||||||
char **envp;
|
|
||||||
t_history *history;
|
|
||||||
char *history_file;
|
|
||||||
} t_minishell;
|
|
||||||
|
|
||||||
/* ******************************** Features ******************************** */
|
|
||||||
|
|
||||||
/* History */
|
|
||||||
|
|
||||||
// history.c
|
|
||||||
void ms_add_history(const char *line);
|
|
||||||
int ms_read_history(const char *hist_file);
|
|
||||||
void ms_write_history(const char *hist_file);
|
|
||||||
|
|
||||||
/* ******************************* Commands ********************************* */
|
|
||||||
|
|
||||||
// command_utils.c
|
|
||||||
|
|
||||||
int is_absolutepath(char const *cmd);
|
|
||||||
int is_builtin(t_cmd *cmd);
|
|
||||||
int is_local(char const *cmd);
|
|
||||||
|
|
||||||
// exec.c
|
|
||||||
|
|
||||||
int exec_cmd(t_cmd *cmd, char **envp);
|
|
||||||
int exec_builtin(t_cmd *cmd, char **envp);
|
|
||||||
|
|
||||||
// parse.c
|
|
||||||
|
|
||||||
t_cmd parse_cmd(char *line, t_minishell *minishell);
|
|
||||||
|
|
||||||
// signals.c
|
|
||||||
|
|
||||||
void init_signal(void);
|
|
||||||
|
|
||||||
/* ********************************* Utils ********************************** */
|
|
||||||
|
|
||||||
// get_hostname.c
|
|
||||||
char *get_hostname(void);
|
|
||||||
|
|
||||||
/* ******************************** Builtins ******************************** */
|
|
||||||
|
|
||||||
// builtin_utils.c
|
|
||||||
int is_builtin(t_cmd *cmd);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* command_utils.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/05 19:52:37 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/20 22:15:22 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int is_absolutepath(
|
|
||||||
char const *cmd)
|
|
||||||
{
|
|
||||||
return (cmd[0] == '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Checks if the given command string refers to a local executable.
|
|
||||||
*
|
|
||||||
* This function determines whether the provided command string starts with
|
|
||||||
* "./", which is a common convention for executing local files in Unix-like
|
|
||||||
* systems.
|
|
||||||
*
|
|
||||||
* @param cmd The command string to check.
|
|
||||||
*
|
|
||||||
* @return 1 if the command starts with "./", 0 otherwise.
|
|
||||||
*/
|
|
||||||
int is_local(
|
|
||||||
char const *cmd)
|
|
||||||
{
|
|
||||||
return (cmd[0] == '.' && cmd[1] == '/');
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* exec.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 16:24:47 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 20:21:27 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int exec_builtin(
|
|
||||||
t_cmd *cmd,
|
|
||||||
char **envp)
|
|
||||||
{
|
|
||||||
if (ft_strncmp(cmd->argv[0], "cd\0", 3) == 0)
|
|
||||||
return (cd_builtin(cmd->argc, (char const **)cmd->argv));
|
|
||||||
else if (ft_strncmp(cmd->argv[0], "echo\0", 5) == 0)
|
|
||||||
return (echo_builtin(cmd->argc, (char const **)cmd->argv));
|
|
||||||
// else if (ft_strncmp(cmd->argv[0], "env\0", 4) == 0)
|
|
||||||
// return (env_builtin(cmd->argc, (char const **)cmd->argv, envp));
|
|
||||||
// else if (ft_strncmp(cmd->argv[0], "exit\0", 5) == 0)
|
|
||||||
// return (exit_builtin(cmd->argc, (char const **)cmd->argv));
|
|
||||||
else if (ft_strncmp(cmd->argv[0], "export\0", 7) == 0)
|
|
||||||
return (export_builtin(cmd->argc, (char const **)cmd->argv, envp));
|
|
||||||
else if ((ft_strncmp(cmd->argv[0], "env\0", 4) == 0 && cmd->argc == 1)
|
|
||||||
|| ft_strncmp(cmd->argv[0], "printenv\0", 9) == 0)
|
|
||||||
return (printenv_builtin(
|
|
||||||
cmd->argc, (char const **)cmd->argv, (char const **)envp));
|
|
||||||
else if (ft_strncmp(cmd->argv[0], "pwd\0", 4) == 0)
|
|
||||||
return (pwd_builtin(cmd->argc, (char const **)cmd->argv));
|
|
||||||
else if (ft_strncmp(cmd->argv[0], "unset\0", 6) == 0)
|
|
||||||
return (unset_builtin(cmd->argc, (char const **)cmd->argv, envp));
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int exec_cmd(
|
|
||||||
t_cmd *cmd,
|
|
||||||
char **envp)
|
|
||||||
{
|
|
||||||
int exit_code;
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
exit_code = 0;
|
|
||||||
pid = fork();
|
|
||||||
if (pid == 0)
|
|
||||||
exit_code = execve(cmd->argv[0], cmd->argv, envp);
|
|
||||||
waitpid(pid, NULL, 0);
|
|
||||||
return (exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* parse.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 16:40:35 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 19:56:15 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
static char *resolve_cmd_path(char const *cmd, char const *path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Parses a command line string into a t_cmd structure.
|
|
||||||
*
|
|
||||||
* This function takes a command line string and a pointer to the minishell
|
|
||||||
* context, splits the line into arguments, and fills a t_cmd structure with
|
|
||||||
* the command path, argument vector, and argument count.
|
|
||||||
*
|
|
||||||
* @param line The input command line string to parse.
|
|
||||||
* @param minishell Pointer to the minishell context.
|
|
||||||
*
|
|
||||||
* @return t_cmd The parsed command structure containing the command path,
|
|
||||||
* argument vector, and argument count.
|
|
||||||
*
|
|
||||||
* @todo Manage double quote
|
|
||||||
*
|
|
||||||
* @note The string array cmd.argv must be freed after the command has been
|
|
||||||
* executed.
|
|
||||||
*/
|
|
||||||
t_cmd parse_cmd(
|
|
||||||
char *line,
|
|
||||||
t_minishell *minishell)
|
|
||||||
{
|
|
||||||
t_cmd cmd;
|
|
||||||
char *abs_path;
|
|
||||||
|
|
||||||
(void)minishell;
|
|
||||||
ft_bzero(&cmd, sizeof(t_cmd));
|
|
||||||
cmd.argv = ft_split(line, ' ');
|
|
||||||
// skip check for the moment
|
|
||||||
cmd.argc = 0;
|
|
||||||
while (cmd.argv[cmd.argc])
|
|
||||||
cmd.argc++;
|
|
||||||
if (!is_local(cmd.argv[0]) && !is_absolutepath(cmd.argv[0])
|
|
||||||
&& !is_builtin(&cmd))
|
|
||||||
{
|
|
||||||
abs_path = resolve_cmd_path(cmd.argv[0], getenv("PATH"));
|
|
||||||
if (abs_path)
|
|
||||||
{
|
|
||||||
free(cmd.argv[0]);
|
|
||||||
cmd.argv[0] = abs_path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *resolve_cmd_path(char const *cmd, char const *path)
|
|
||||||
{
|
|
||||||
char *abs_path;
|
|
||||||
char const **path_splitted = (char const **)ft_split(path, ':');
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
abs_path = NULL;
|
|
||||||
i = 0;
|
|
||||||
while (path_splitted[i])
|
|
||||||
{
|
|
||||||
abs_path = ft_strnjoin(
|
|
||||||
3, (char *)path_splitted[i], "/", (char *)cmd);
|
|
||||||
if (access(abs_path, X_OK) != -1)
|
|
||||||
break ;
|
|
||||||
free(abs_path);
|
|
||||||
abs_path = NULL;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
ft_free_split((char **)path_splitted);
|
|
||||||
return (abs_path);
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* builtin_utils.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/20 22:15:23 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/20 22:48:11 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Checks if the given command is a shell builtin.
|
|
||||||
*
|
|
||||||
* This function compares the input command string against a list of known
|
|
||||||
* shell builtin commands ("cd", "echo", "env", "exit", "export", "pwd",
|
|
||||||
* "unset"). It returns a non-zero value if the command matches any of these
|
|
||||||
* builtins, otherwise returns 0.
|
|
||||||
*
|
|
||||||
* @param cmd The command string to check.
|
|
||||||
*
|
|
||||||
* @return int Non-zero if the command is a builtin, 0 otherwise.
|
|
||||||
*/
|
|
||||||
int is_builtin(
|
|
||||||
t_cmd *cmd)
|
|
||||||
{
|
|
||||||
return (ft_strncmp(cmd->argv[0], "cd\0", 3) == 0
|
|
||||||
|| ft_strncmp(cmd->argv[0], "echo\0", 5) == 0
|
|
||||||
|| (ft_strncmp(cmd->argv[0], "env\0", 4) == 0 && cmd->argc == 1)
|
|
||||||
|| ft_strncmp(cmd->argv[0], "exit\0", 5) == 0
|
|
||||||
|| ft_strncmp(cmd->argv[0], "export\0", 7) == 0
|
|
||||||
|| ft_strncmp(cmd->argv[0], "printenv\0", 9) == 0
|
|
||||||
|| ft_strncmp(cmd->argv[0], "pwd\0", 4) == 0
|
|
||||||
|| ft_strncmp(cmd->argv[0], "unset\0", 6) == 0);
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* cd.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 11:09:13 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 18:35:36 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int cd_builtin(
|
|
||||||
int argc,
|
|
||||||
char const *argv[])
|
|
||||||
{
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
if (argc == 1)
|
|
||||||
path = getenv("HOME");
|
|
||||||
else
|
|
||||||
path = (char *)argv[1];
|
|
||||||
// be aware of execution permission
|
|
||||||
if (chdir(path) != 0)
|
|
||||||
return (fprintf(stderr, "cd: %s: %s\n", path, strerror(errno)), 1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* echo.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 13:22:11 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 09:22:15 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
static t_echo_flags set_flags(char const *argv[], size_t *i);
|
|
||||||
static void set_default_flags(t_echo_flags *flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Executes the echo builtin command.
|
|
||||||
*
|
|
||||||
* This function processes the arguments passed to the echo command,
|
|
||||||
* handles any flags (such as -n for no trailing newline), and prints
|
|
||||||
* the arguments to standard output separated by spaces.
|
|
||||||
*
|
|
||||||
* @param argc The number of arguments in argv.
|
|
||||||
* @param argv The array of argument strings, with argv[0] being "echo".
|
|
||||||
*
|
|
||||||
* @return EXIT_SUCCESS on successful execution.
|
|
||||||
*/
|
|
||||||
int echo_builtin(
|
|
||||||
int argc,
|
|
||||||
char const *argv[])
|
|
||||||
{
|
|
||||||
t_echo_flags flags;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
(void)argc;
|
|
||||||
flags = set_flags(argv, &i);
|
|
||||||
while (argv[i])
|
|
||||||
{
|
|
||||||
ft_putstr((char *)argv[i]);
|
|
||||||
if (argv[++i])
|
|
||||||
ft_putchar(' ');
|
|
||||||
}
|
|
||||||
if (flags.newline)
|
|
||||||
ft_putchar('\n');
|
|
||||||
return (EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Parses command-line arguments to set flags for the echo builtin.
|
|
||||||
*
|
|
||||||
* This function examines the arguments passed to the echo command, starting
|
|
||||||
* from argv[1], and sets the appropriate flags based on the presence of
|
|
||||||
* options (e.g., "-n"). It updates the index `i` to point to the first
|
|
||||||
* non-option argument.
|
|
||||||
*
|
|
||||||
* @param argv Array of argument strings (NULL-terminated).
|
|
||||||
* @param i Pointer to a size_t variable that will be updated to the index
|
|
||||||
* of the first non-option argument.
|
|
||||||
*
|
|
||||||
* @return t_echo_flags Structure containing the parsed flags (e.g., whether
|
|
||||||
* to print a trailing newline).
|
|
||||||
*/
|
|
||||||
static t_echo_flags set_flags(
|
|
||||||
char const *argv[],
|
|
||||||
size_t *i
|
|
||||||
)
|
|
||||||
{
|
|
||||||
t_echo_flags flags;
|
|
||||||
size_t j;
|
|
||||||
|
|
||||||
set_default_flags(&flags);
|
|
||||||
*i = 1;
|
|
||||||
if (!argv[1])
|
|
||||||
return (flags);
|
|
||||||
while (*argv[*i] == '-')
|
|
||||||
{
|
|
||||||
j = 1;
|
|
||||||
if (!argv[*i][j])
|
|
||||||
return (flags);
|
|
||||||
while (argv[*i][j])
|
|
||||||
{
|
|
||||||
if (argv[*i][j] == 'n')
|
|
||||||
flags.newline = 0;
|
|
||||||
else
|
|
||||||
return (set_default_flags(&flags), flags);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
(*i)++;
|
|
||||||
}
|
|
||||||
return (flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes the t_echo_flags structure with default values.
|
|
||||||
*
|
|
||||||
* This function zeroes out all fields of the given t_echo_flags structure
|
|
||||||
* and sets the 'newline' flag to 1, indicating that a newline should be
|
|
||||||
* printed by default.
|
|
||||||
*
|
|
||||||
* @param flags Pointer to the t_echo_flags structure to initialize.
|
|
||||||
*/
|
|
||||||
static void set_default_flags(t_echo_flags *flags)
|
|
||||||
{
|
|
||||||
ft_bzero(flags, sizeof(t_echo_flags));
|
|
||||||
flags->newline = 1;
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* env.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 14:15:09 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/07 17:21:24 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
static void printenv(char **envp);
|
|
||||||
|
|
||||||
int env_builtin(
|
|
||||||
int argc,
|
|
||||||
char const *argv[],
|
|
||||||
char **envp)
|
|
||||||
{
|
|
||||||
// (void)envp;
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
printenv(envp);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printenv(
|
|
||||||
char **envp)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (envp[i])
|
|
||||||
ft_putendl(envp[i++]);
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* exit.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 14:38:18 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 18:45:33 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Handles the shell's exit builtin command.
|
|
||||||
*
|
|
||||||
* Prints "exit" to standard output and determines the exit code based on the
|
|
||||||
* arguments provided.
|
|
||||||
*
|
|
||||||
* @param argc The number of arguments passed to the exit command.
|
|
||||||
* @param argv The array of argument strings.
|
|
||||||
* @return The exit code to be used by the shell.
|
|
||||||
*
|
|
||||||
* Behavior:
|
|
||||||
* - If no additional arguments are provided (argc == 1), exits with code 0.
|
|
||||||
* - If more than one argument is provided:
|
|
||||||
* - If the first argument is not a valid numeric string, prints an error
|
|
||||||
* message to stderr and exits with error code 2.
|
|
||||||
* - If the first argument is valid but there are too many arguments,
|
|
||||||
* prints an error message to stderr and returns -1. In this case the
|
|
||||||
* shell must not exit.
|
|
||||||
* - Otherwise, parses the first argument as a long integer and casts it to an
|
|
||||||
* unsigned char, then to an unsigned int to ensure the exit code is within
|
|
||||||
* the range 0-255.
|
|
||||||
*/
|
|
||||||
int exit_builtin(
|
|
||||||
int argc,
|
|
||||||
char const *argv[])
|
|
||||||
{
|
|
||||||
int exit_code;
|
|
||||||
|
|
||||||
ft_putendl("exit");
|
|
||||||
if (argc == 1)
|
|
||||||
exit_code = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ft_strisnum(argv[1]))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "exit: %s: numeric argument required\n", argv[1]);
|
|
||||||
exit_code = 2;
|
|
||||||
}
|
|
||||||
else if (argc > 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "exit: too many arguments\n");
|
|
||||||
exit_code = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
exit_code = (unsigned int)((unsigned char)(ft_atol(argv[1])));
|
|
||||||
}
|
|
||||||
return (exit_code);
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* export.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/04 21:38:45 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 14:55:31 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int export_builtin(int argc, char const *argv[], char **envp)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
char **env;
|
|
||||||
|
|
||||||
(void)argv;
|
|
||||||
if (argc == 2)
|
|
||||||
{
|
|
||||||
i = 0;
|
|
||||||
env = ft_split(argv[1], '=');
|
|
||||||
while (envp[i]) // ENV=value
|
|
||||||
{
|
|
||||||
if (ft_strncmp(envp[i], env[0], ft_strlen(env[0])) == 0)
|
|
||||||
{
|
|
||||||
char *line = ft_strnjoin(3, env[0], "=", env[1]);
|
|
||||||
envp[i] = line;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
ft_free_split(env);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* printenv.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/05 19:45:36 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 20:19:10 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int printenv_builtin(
|
|
||||||
int argc,
|
|
||||||
char const *argv[],
|
|
||||||
char const *envp[])
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
i = 0;
|
|
||||||
while (envp[i])
|
|
||||||
ft_putendl((char *)(envp[i++]));
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* pwd.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 11:52:33 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/03 02:11:02 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int pwd_builtin(
|
|
||||||
int argc,
|
|
||||||
char const *argv[])
|
|
||||||
{
|
|
||||||
char cwd[PATH_MAX];
|
|
||||||
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
if (!getcwd(cwd, sizeof(cwd)))
|
|
||||||
ft_eputendl("getcwd()");
|
|
||||||
ft_putendl(cwd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* type.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/20 22:12:49 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/20 22:27:32 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int type_builtin(
|
|
||||||
int argc,
|
|
||||||
char const *argv[])
|
|
||||||
{
|
|
||||||
int exit_code;
|
|
||||||
|
|
||||||
if (is_builtin((t_cmd*){argc, argv}))
|
|
||||||
{
|
|
||||||
printf("%s is a shell builtin\n", argv[0]);
|
|
||||||
exit_code = 0;
|
|
||||||
}
|
|
||||||
return (exit_code);
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* unset.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/04 21:39:35 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/05 09:31:22 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int unset_builtin(int argc, char const *argv[], char **envp)
|
|
||||||
{
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
(void)envp;
|
|
||||||
printf("Not yet implemented\n");
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* history.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/20 22:06:47 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/21 14:39:00 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
int ms_read_history(
|
|
||||||
const char *hist_file)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char *line;
|
|
||||||
|
|
||||||
fd = open(hist_file, O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
return (0);
|
|
||||||
line = get_next_line(fd);
|
|
||||||
while (line)
|
|
||||||
{
|
|
||||||
add_history(line);
|
|
||||||
free(&line);
|
|
||||||
line = get_next_line(fd);
|
|
||||||
}
|
|
||||||
if (line)
|
|
||||||
ft_free(&line);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ms_write_history(
|
|
||||||
const char *hist_file)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
182
src/minishell.c
182
src/minishell.c
@@ -1,182 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* minishell.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/07/31 03:42:25 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/10/17 20:11:24 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
static t_minishell init_minishell(char **envp);
|
|
||||||
static int minishell(t_minishell *minishell);
|
|
||||||
static void clear_minishell(t_minishell *minishell);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Entry point for the minishell program.
|
|
||||||
*
|
|
||||||
* Validates the number of command-line arguments, initializes the minishell
|
|
||||||
* structure, starts the main shell loop, and performs necessary cleanup before
|
|
||||||
* exiting.
|
|
||||||
*
|
|
||||||
* @param argc Number of command-line arguments.
|
|
||||||
* @param argv Array of command-line argument strings.
|
|
||||||
* @param envp Array of environment variable strings.
|
|
||||||
*
|
|
||||||
* @return int Returns EXIT_SUCCESS if the program completes successfully, or
|
|
||||||
* an error code on failure.
|
|
||||||
*/
|
|
||||||
int main(
|
|
||||||
int argc,
|
|
||||||
char const *argv[],
|
|
||||||
char **envp)
|
|
||||||
{
|
|
||||||
t_minishell shell;
|
|
||||||
int exit_code;
|
|
||||||
|
|
||||||
(void)argv;
|
|
||||||
errno = 0;
|
|
||||||
if (argc != 1)
|
|
||||||
return (errno = EINVAL, errno);
|
|
||||||
init_signal();
|
|
||||||
shell = init_minishell(envp);
|
|
||||||
if (errno)
|
|
||||||
fprintf(stderr, "minishell: %s\n" , strerror(errno));
|
|
||||||
exit_code = minishell(&shell);
|
|
||||||
clear_minishell(&shell);
|
|
||||||
return (exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes and returns a t_minishell structure with default values.
|
|
||||||
*
|
|
||||||
* This function zeroes out a t_minishell struct, sets up the history file path
|
|
||||||
* by joining the HOME environment variable with HISTORY_FILE, and splits the
|
|
||||||
* PATH environment variable into an array of strings using ':' as the
|
|
||||||
* delimiter.
|
|
||||||
*
|
|
||||||
* @return t_minishell The initialized minishell structure.
|
|
||||||
*/
|
|
||||||
static t_minishell init_minishell(
|
|
||||||
char **envp)
|
|
||||||
{
|
|
||||||
t_minishell minishell;
|
|
||||||
size_t n_env;
|
|
||||||
|
|
||||||
ft_bzero(&minishell, sizeof(t_minishell));
|
|
||||||
n_env = 0;
|
|
||||||
while (envp[n_env])
|
|
||||||
n_env++;
|
|
||||||
minishell.envp = (char **)malloc(n_env * sizeof(char *));
|
|
||||||
if (!minishell.envp && errno == ENOMEM)
|
|
||||||
return (clear_minishell(&minishell), minishell);
|
|
||||||
return (minishell);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Main loop for the minishell program.
|
|
||||||
*
|
|
||||||
* This function implements the main interactive loop of the minishell. It
|
|
||||||
* displays a dynamic prompt showing the user, hostname, and current working
|
|
||||||
* directory, reads user input, adds commands to the history, and executes
|
|
||||||
* commands by forking a new process. The loop continues until the user enters
|
|
||||||
* "exit" or EOF is encountered.
|
|
||||||
*
|
|
||||||
* @param minishell Pointer to the minishell state structure, containing at
|
|
||||||
* least the history file path.
|
|
||||||
* @param envp Environment variables to be passed to executed commands.
|
|
||||||
*
|
|
||||||
* The function performs the following steps:
|
|
||||||
* - Loads command history from the specified history file.
|
|
||||||
* - Constructs and displays a prompt with user, hostname, and current
|
|
||||||
* directory.
|
|
||||||
* - Reads a line of input from the user.
|
|
||||||
* - If the input is not empty:
|
|
||||||
* - Adds the command to the history and writes it to the history file.
|
|
||||||
* - If the command is "exit", breaks the loop and exits.
|
|
||||||
* - Otherwise, constructs the command path, forks a child process, and
|
|
||||||
* executes the command using execve.
|
|
||||||
* - Waits for the child process to finish.
|
|
||||||
* - Cleans up allocated memory and clears the history on exit.
|
|
||||||
*/
|
|
||||||
static int minishell(t_minishell *minishell)
|
|
||||||
{
|
|
||||||
int exit_code;
|
|
||||||
char *line;
|
|
||||||
t_cmd cmd;
|
|
||||||
|
|
||||||
exit_code = 0;
|
|
||||||
line = NULL;
|
|
||||||
// read_history(minishell->history_file);
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (line)
|
|
||||||
free(line);
|
|
||||||
char *prompt = NULL;
|
|
||||||
if (prompt)
|
|
||||||
{
|
|
||||||
line = readline(prompt);
|
|
||||||
free(prompt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
line = readline("minishell> ");
|
|
||||||
if (!line)
|
|
||||||
{
|
|
||||||
write_history(minishell->history_file);
|
|
||||||
cmd = parse_cmd("exit", minishell);
|
|
||||||
exit_code = exit_builtin(cmd.argc, (const char **)cmd.argv);
|
|
||||||
if (exit_code != -1)
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
if (*line)
|
|
||||||
{
|
|
||||||
add_history(line);
|
|
||||||
cmd = parse_cmd(line, minishell);
|
|
||||||
free(line);
|
|
||||||
line = NULL;
|
|
||||||
if (ft_strncmp(cmd.argv[0], "exit\0", 5) == 0)
|
|
||||||
{
|
|
||||||
exit_code = exit_builtin(cmd.argc, (const char **)cmd.argv);
|
|
||||||
write_history(minishell->history_file);
|
|
||||||
if (exit_code != -1)
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
else if (is_builtin(&cmd))
|
|
||||||
exec_builtin(&cmd, minishell->envp);
|
|
||||||
else
|
|
||||||
exec_cmd(&cmd, minishell->envp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
write_history(minishell->history_file);
|
|
||||||
rl_clear_history();
|
|
||||||
if (line)
|
|
||||||
free(line);
|
|
||||||
return (exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Clears and frees resources associated with a t_minishell instance.
|
|
||||||
*
|
|
||||||
* This function performs the following actions:
|
|
||||||
* - Zeroes out the contents of the history_file string.
|
|
||||||
* - Frees the memory allocated for the history_file.
|
|
||||||
* - Frees the memory allocated for the path array using ft_free_split.
|
|
||||||
* - Zeroes out the entire t_minishell structure.
|
|
||||||
*
|
|
||||||
* @param minishell Pointer to the t_minishell structure to be cleared and
|
|
||||||
* freed.
|
|
||||||
*/
|
|
||||||
static void clear_minishell(
|
|
||||||
t_minishell *minishell
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ft_bzero(minishell->history_file,
|
|
||||||
ft_strlen(minishell->history_file) * sizeof(char));
|
|
||||||
free(minishell->history_file);
|
|
||||||
ft_bzero(minishell, sizeof(t_minishell));
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* get_hostname.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/01 02:32:19 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/01 13:13:54 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Retrieves the system's hostname from the /etc/hostname file.
|
|
||||||
*
|
|
||||||
* This function opens the /etc/hostname file, reads the first line to obtain
|
|
||||||
* the hostname, trims any trailing newline character, and returns the result
|
|
||||||
* as a dynamically allocated string. The caller is responsible for freeing
|
|
||||||
* the returned string.
|
|
||||||
*
|
|
||||||
* @return A pointer to the trimmed hostname string on success, or NULL on
|
|
||||||
* failure.
|
|
||||||
*
|
|
||||||
* @note The returned string must be freed later to avoid leaks.
|
|
||||||
*/
|
|
||||||
char *get_hostname(void)
|
|
||||||
{
|
|
||||||
char *hostname;
|
|
||||||
char *hostname_trimmed;
|
|
||||||
int hostname_file;
|
|
||||||
|
|
||||||
hostname_file = open("/etc/hostname", O_RDONLY);
|
|
||||||
if (hostname_file != -1)
|
|
||||||
{
|
|
||||||
hostname = get_next_line(hostname_file);
|
|
||||||
close(hostname_file);
|
|
||||||
}
|
|
||||||
if (!hostname)
|
|
||||||
hostname = NULL;
|
|
||||||
hostname_trimmed = ft_strtrim(hostname, "\n");
|
|
||||||
if (hostname)
|
|
||||||
free(hostname);
|
|
||||||
return (hostname_trimmed);
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* signals.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/08/05 19:06:16 by sede-san #+# #+# */
|
|
||||||
/* Updated: 2025/08/20 19:37:40 by sede-san ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "minishell.h"
|
|
||||||
|
|
||||||
static void sighandler(int signal, siginfo_t *signal_info, void *context);
|
|
||||||
|
|
||||||
void init_signal(void)
|
|
||||||
{
|
|
||||||
struct sigaction signal;
|
|
||||||
|
|
||||||
signal.sa_sigaction = sighandler;
|
|
||||||
signal.sa_flags = SA_SIGINFO;
|
|
||||||
sigemptyset(&signal.sa_mask);
|
|
||||||
sigaddset(&signal.sa_mask, SIGINT);
|
|
||||||
sigaction(SIGINT, &signal, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sighandler(
|
|
||||||
int signal,
|
|
||||||
siginfo_t *signal_info,
|
|
||||||
void *context)
|
|
||||||
{
|
|
||||||
(void)signal_info;
|
|
||||||
(void)context;
|
|
||||||
if (signal == SIGINT)
|
|
||||||
{
|
|
||||||
rl_on_new_line();
|
|
||||||
rl_replace_line("", 0);
|
|
||||||
rl_redisplay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user