Minishell 1.0
42 School Minishell Project - A simple shell implementation
Yüklüyor...
Arıyor...
Eşleşme Yok
executor_cmd.c
Bu dosyanın dokümantasyonuna git.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* executor_cmd.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: hgenc <hgenc@student.42kocaeli.com.tr> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2026/01/26 17:39:30 by hgenc #+# #+# */
9/* Updated: 2026/02/16 16:30:00 by hgenc ### ########.fr */
10/* */
11/* ************************************************************************** */
12
13/**
14 * @file executor_cmd.c
15 * @brief Komut çalıştırma fonksiyonları
16 */
17
19#include <stdio.h>
20#include <stdlib.h>
21#include <sys/wait.h>
22#include <unistd.h>
23
24/**
25 * @brief _ underscore değişkenini son argümanla günceller
26 */
27static void update_underscore(t_shell *shell, t_cmd *cmd)
28{
29 int i;
30
31 if (!cmd || !cmd->args || !cmd->args[0])
32 return ;
33 i = 0;
34 while (cmd->args[i + 1])
35 i++;
36 update_env_value(shell->env_list, "_", cmd->args[i]);
37}
38
39/**
40 * @brief Builtin'i parent process'te çalıştır (fork yok)
41 */
43{
44 int saved_fds[2];
45 int result;
46
47 if (!save_std_fds(saved_fds))
48 return (1);
49 if (!setup_redirs(shell, cmd))
50 {
51 restore_std_fds(saved_fds);
52 return (1);
53 }
54 result = execute_builtin(shell, cmd);
55 restore_std_fds(saved_fds);
56 return (result);
57}
58
59/**
60 * @brief Bulunan path ile child process'te execve çalıştır
61 */
62static void child_exec(t_shell *shell, t_cmd *cmd, char *path)
63{
64 char **envp;
65
67 if (!setup_redirs(shell, cmd))
68 {
69 free(path);
70 shell_exit(shell, 1);
71 }
72 envp = create_envp(shell);
73 if (execve(path, cmd->args, envp) < 0)
74 {
75 perror("minishell");
76 free(path);
77 free_str_array(envp);
78 shell_exit(shell, 126);
79 }
80}
81
82/**
83 * @brief Harici komutu çalıştır — path kontrolü fork öncesi yapılır
84 * böylece "command not found" hatası parent'ta sırayla basılır
85 */
87{
88 pid_t pid;
89 char *path;
90 int res;
91
92 path = find_cmd_path(shell, cmd->args[0]);
93 if (!path)
94 {
95 shell_error(cmd->args[0], NULL, "command not found");
96 return (127);
97 }
98 if (is_executable(path) != 2)
99 {
100 shell_error(cmd->args[0], NULL, "Permission denied");
101 free(path);
102 return (126);
103 }
104 update_env_value(shell->env_list, "_", path);
105 pid = fork();
106 if (pid == 0)
107 child_exec(shell, cmd, path);
108 free(path);
109 if (pid > 0)
110 {
111 res = wait_for_child(pid);
112 return (res);
113 }
114 shell_error(NULL, NULL, "fork failed");
115 return (1);
116}
117
118/**
119 * @brief Ana komut çalıştırma dispatcher
120 */
121int execute_cmd(t_shell *shell, t_cmd *cmd)
122{
123 int saved_fds[2];
124 int result;
125
126 if (!cmd)
127 return (0);
128 if (!cmd->args || !cmd->args[0])
129 {
130 if (cmd->redirections)
131 {
132 if (!save_std_fds(saved_fds))
133 return (1);
134 if (!setup_redirs(shell, cmd))
135 {
136 restore_std_fds(saved_fds);
137 return (1);
138 }
139 restore_std_fds(saved_fds);
140 }
141 return (0);
142 }
143 update_env_value(shell->env_list, "_", cmd->args[0]);
144 if (is_builtin(cmd->args[0]))
145 result = run_builtin_parent(shell, cmd);
146 else
147 result = execute_external(shell, cmd);
148 update_underscore(shell, cmd);
149 return (result);
150}
int execute_builtin(t_shell *shell, t_cmd *cmd)
Definition builtins.c:44
int is_builtin(char *cmd)
Definition builtins.c:19
void shell_exit(t_shell *shell, int exit_code)
Shell'i temizleyip programdan çıkar.
Definition cleanup.c:76
void free_str_array(char **arr)
NULL-terminated string dizisini serbest bırakır.
Definition cleanup.c:30
int update_env_value(t_list *env_list, char *key, char *new_value)
Mevcut env değişkeninin değerini günceller.
Definition env_utils.c:52
char ** create_envp(t_shell *shell)
shell->env_list'i char **envp formatına çevir
Definition env_utils.c:111
void shell_error(char *cmd, char *arg, char *msg)
static void child_exec(t_shell *shell, t_cmd *cmd, char *path)
Bulunan path ile child process'te execve çalıştır.
static void update_underscore(t_shell *shell, t_cmd *cmd)
_ underscore değişkenini son argümanla günceller
int execute_cmd(t_shell *shell, t_cmd *cmd)
Ana komut çalıştırma dispatcher.
int execute_external(t_shell *shell, t_cmd *cmd)
Harici komutu çalıştır — path kontrolü fork öncesi yapılır böylece "command not found" hatası parent'...
int run_builtin_parent(t_shell *shell, t_cmd *cmd)
Builtin'i parent process'te çalıştır (fork yok).
int is_executable(char *path)
Dosyanın var olup olmadığını ve çalıştırılabilir olup olmadığını kontrol et.
char * find_cmd_path(t_shell *shell, char *cmd)
Ana PATH arama fonksiyonu.
int setup_redirs(t_shell *shell, t_cmd *cmd)
Tüm redirectionları uygula.
int wait_for_child(pid_t pid)
Child process'i bekle ve exit status al EINTR: sinyal gelirse waitpid'i tekrar dene (zombie bırakma).
int save_std_fds(int *saved_fds)
stdin ve stdout'u kaydet (builtin için)
int restore_std_fds(int *saved_fds)
Kaydedilen fd'leri geri yükle.
Minishell ana header dosyası
struct s_cmd t_cmd
struct s_shell t_shell
void reset_signals(void)
Definition signals.c:73
char ** args
Definition minishell.h:129
t_list * redirections
Definition minishell.h:131
t_list * env_list
Definition minishell.h:149