Я делаю мини-оболочку, и мне нужно создать в C команду как «<<» в bash. Поэтому мне нужно ввести какой-то ввод в терминал и перенаправить его на стандартный ввод, но у меня проблемы с этим.
Пример того, что должно получиться:
Minishell > cat << deli
> jlaf
> faljs
> deli
jlaf
faljs
Что происходит:
Minishell > cat << deli
> jlaf
> faljs
> deli
jlaf
faljs
То же самое, но он зависает после фальш. Код для "<<" следующий:
buffer = readline("> ");
while (strncmp(buffer, delimiter, ft_strlen(buffer)) != 0)
{
str = ft_strjoin(str, ft_strjoin("\n", buffer);
free(buffer);
buffer = readline("> ");
}
write(0, str+1, ft_strlen(str));
Readline() — это функция c, которая считывает ввод каждой строки, пока не достигнет разделителя в цикле, ft_strjoin просто соединяет две строки и возвращает новую. В конце я пытаюсь записать все прочитанные строки на стандартный ввод, что, как мне кажется, является проблемой. Позже я выполняю процесс в execve, например, cat, если я поставил «cat << разделитель» на стандартный вывод и, предположительно, с ранее записанной информацией в стандартном вводе. Но что-то не так, и он показывает вывод, но я застреваю в терминале. ¿Что может быть проблемой в этом коде?
И это только одна из форм перенаправления. Если вы поддерживаете здесь документы, то, вероятно, вы также поддерживаете перенаправление из файла с < и в файл с >. Возможно, вы также поддерживаете конвейеры с помощью |. Все эти формы перенаправления используют аналогичные строительные блоки, особенно семейство функций dup, с разумным использованием конвейеров. Я бы искал способы поделиться кодом для этих возможностей.
Обычно (традиционно) вы записываете здесь документ в файл (вероятно, анонимный файл), а затем дублируете файловый дескриптор файла в стандартный ввод дочернего элемента (и закрываете его в родительском). Будучи анонимными, данные файла будут освобождены, когда завершится последний процесс с файловым дескриптором для файла. Вы не показываете проверку ошибок на write(0, …) — вы должны.
@JonathanLeffler: я думаю, что это стоит сделать ответом.
Transferring a comment into a semblance of an answer.
Обычно (традиционно) вы записываете здесь документ в файл (вероятно, анонимный файл), а затем дублируете файловый дескриптор файла в стандартный ввод дочернего элемента (и закрываете его в родительском). Будучи анонимными, данные файла будут освобождены, когда завершится последний процесс с файловым дескриптором для файла.
«Анонимный» файл — это файл, который вы создаете с именем (и для которого вы получаете файловый дескриптор), а затем сразу же удаляете. Стандартный C tmpfile() создает такой файл для вас, но возвращает файловый поток (FILE *). Вы, вероятно, хотите эквивалент, который дает вам дескриптор файла. Функции POSIX mkstemp() и unlink() даст вам эту функциональность.
Зависит от ОС. В системе unix (например, Linux) вам нужно создать канал, dup2, который передает канал на fd 0 в дочернем элементе (т. е. после разветвления, но перед выполнением), и записать в этот канал в родительском.