Я пишу мини-оболочку Unix на C и сейчас добавляю расширение команды. Под этим я подразумеваю, что я могу вкладывать команды в другие команды, например:
$> echo hello $(echo world! ... $(echo and stuff))
hello world! ... and stuff
Я думаю, что он работает в основном, однако он неправильно отмечает конец расширенной строки, например, если я делаю:
$> echo a $(echo b $(echo c))
a b c
$> echo d $(echo e)
d e c
Смотрите, он печатает c, хотя я этого не просил. Вот мой код:
msh.c — http://pastebin.com/sd6DZYwB expand.c — http://pastebin.com/uLqvFGPw
У меня есть еще код, но его много, и это те части, с которыми у меня сейчас проблемы. Я попытаюсь рассказать вам основной способ, которым я это делаю.
Main находится в msh.c, здесь он получает строку ввода либо из командной строки, либо из файла оболочки, а затем вызывает processline (char *line, int outFD, int waitFlag), где line — это только что полученная строка, outFD — это файловый дескриптор выходного файла, а waitFlag сообщает нам, следует ли нам ждать, если мы разветвимся. Когда мы вызываем это из main, мы делаем это так:
processline (buffer, 1, 1);
В processline мы выделяем новую строку:
char expanded_line[EXPANDEDLEN];
Затем мы вызываем расширение в файле expand.c:
expand(line, expanded_line, EXPANDEDLEN);
В расширении мы буквально копируем символы из строки в Expand_line, пока не найдем $(, который затем вызывает:
static int expCmdOutput(char *orig, char *new, int *oldl_ind, int *newl_ind)
orig — это строка, а new — расширенная строка. oldl_ind и newl_ind — текущие позиции в строке и развернутой строке соответственно. Затем мы передаем и рекурсивно вызываем processline, передавая ему вложенную команду (например, если бы у нас было «echo a $(echo b)», мы бы передали processline «echo b»).
Вот где я запутался, каждый раз, когда вызывается расширение, он выделяет новый кусок памяти EXPANDEDLEN long? Если это так, это плохо, потому что у меня очень быстро закончится место в стеке (в случае сильно вложенного ввода командной строки). В расширении я вставляю нулевой символ в конец расширенной строки, так почему же он печатается за его пределами?
Если вам, ребята, нужен еще код или пояснения, просто спросите. Во-вторых, я помещаю код в pastebin, потому что его много, и по моему опыту людям не нравится, когда я заполняю несколько страниц кодом.