Minishell 1.0
42 School Minishell Project - A simple shell implementation
Yüklüyor...
Arıyor...
Eşleşme Yok
executor_heredoc.c
Bu dosyanın dokümantasyonuna git.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* executor_heredoc.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: hgenc <hgenc@student.42kocaeli.com.tr> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2026/01/26 17:39:45 by hgenc #+# #+# */
9/* Updated: 2026/02/19 15:00:00 by hgenc ### ########.fr */
10/* */
11/* ************************************************************************** */
12
13/**
14 * @file executor_heredoc.c
15 * @brief Heredoc implementasyonu (fork tabanlı)
16 *
17 * Heredoc okuma child process'te yapılır.
18 * readline yerine write+read kullanılır (cooked mode, SIG_DFL çalışır).
19 * Ctrl-C → child SIG_DFL ile ölür, parent terminali düzeltir.
20 */
21
23#include <signal.h>
24#include <stdlib.h>
25#include <sys/wait.h>
26#include <termios.h>
27#include <unistd.h>
28
29/**
30 * @brief Heredoc için bir satır oku (readline yerine read kullanır)
31 * @return char* Okunan satır (malloc), EOF: NULL
32 *
33 * Cooked mode'da read() Enter'a kadar bekler, tüm satırı döner.
34 * SIG_DFL bu modda doğru çalışır (readline override etmez).
35 */
36static char *heredoc_read_line(void)
37{
38 char buf[4096];
39 char c;
40 ssize_t ret;
41 int i;
42
43 i = 0;
44 while (i < 4095)
45 {
46 ret = read(STDIN_FILENO, &c, 1);
47 if (ret <= 0)
48 break ;
49 if (c == '\n')
50 break ;
51 buf[i++] = c;
52 }
53 if (i == 0 && ret <= 0)
54 return (NULL);
55 buf[i] = '\0';
56 return (ft_strdup(buf));
57}
58
59/**
60 * @brief Heredoc satırlarını oku ve pipe'a yaz (child process)
61 */
62static void heredoc_child(t_shell *shell, t_redir *redir, int write_fd)
63{
64 char *line;
65 struct termios term;
66
67 signal(SIGINT, SIG_DFL);
68 signal(SIGQUIT, SIG_IGN);
69 tcgetattr(STDIN_FILENO, &term);
70 term.c_lflag |= (ICANON | ECHO | ISIG);
71 term.c_iflag &= ~(IGNCR);
72 term.c_iflag |= ICRNL;
73 term.c_oflag |= (OPOST | ONLCR);
74 tcsetattr(STDIN_FILENO, TCSANOW, &term);
75 while (1)
76 {
77 write(2, "> ", 2);
78 line = heredoc_read_line();
79 if (!line)
80 {
81 ft_putstr_fd("minishell: warning: heredoc delimited by EOF\n", 2);
82 break ;
83 }
84 if (ft_strcmp(line, redir->file) == 0)
85 {
86 free(line);
87 break ;
88 }
89 if (!redir->quoted)
90 line = expand_heredoc_line(shell, line);
91 if (!write_heredoc_line(write_fd, line))
92 {
93 free(line);
94 break ;
95 }
96 free(line);
97 }
98}
99
100/**
101 * @brief Heredoc redirection uygula (fork tabanlı)
102 * @param shell Shell structure
103 * @param redir Redirection yapısı
104 * @return int başarı: fd, hata/iptal: -1
105 *
106 * Child process heredoc'u okur (write+read, readline değil).
107 * Ctrl-C: child ölür (SIG_DFL), parent terminali düzeltir.
108 */
109int redir_heredoc(t_shell *shell, t_redir *redir)
110{
111 int pipefd[2];
112 pid_t pid;
113 int status;
114 struct termios saved_term;
115
116 if (!redir || !redir->file)
117 return (-1);
118 if (!create_heredoc_pipe(pipefd))
119 return (-1);
120 tcgetattr(STDIN_FILENO, &saved_term);
121 signal(SIGINT, SIG_IGN);
122 pid = fork();
123 if (pid == 0)
124 {
125 close(pipefd[0]);
126 heredoc_child(shell, redir, pipefd[1]);
127 close(pipefd[1]);
128 shell_exit(shell, 0);
129 }
130 close(pipefd[1]);
131 waitpid(pid, &status, 0);
132 tcflush(STDIN_FILENO, TCIFLUSH);
133 tcsetattr(STDIN_FILENO, TCSANOW, &saved_term);
135 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
136 {
137 close(pipefd[0]);
138 write(1, "\n", 1);
139 shell->exit_status = 130;
140 return (-1);
141 }
142 return (pipefd[0]);
143}
void shell_exit(t_shell *shell, int exit_code)
Shell'i temizleyip programdan çıkar.
Definition cleanup.c:76
static void heredoc_child(t_shell *shell, t_redir *redir, int write_fd)
Heredoc satırlarını oku ve pipe'a yaz (child process).
static char * heredoc_read_line(void)
Heredoc için bir satır oku (readline yerine read kullanır).
int redir_heredoc(t_shell *shell, t_redir *redir)
Heredoc redirection uygula (fork tabanlı).
int create_heredoc_pipe(int *pipefd)
Heredoc için pipe oluştur.
char * expand_heredoc_line(t_shell *shell, char *line)
Heredoc satırındaki $VAR değişkenlerini genişlet.
int write_heredoc_line(int fd, char *line)
Heredoc satırını pipe'a yaz.
Minishell ana header dosyası
struct s_redir t_redir
struct s_shell t_shell
void setup_signals(void)
Definition signals.c:58
int quoted
Definition minishell.h:125
char * file
Definition minishell.h:124
int exit_status
Definition minishell.h:153
int ft_strcmp(const char *s1, const char *s2)
Definition utils.c:48