Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[13.58.185.199] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Здравствуйте. У меня есть задания по написания своего собственного командного интерпретатора. Я уже практически всё написал, но столкнулся с одной проблемой, которую я на данный момент не могу решить. Мне нужно у терминал «отколоть» последний рядок для нужд интерпретатора (вывод информации обо всех фоновых процессах). Помогите, как это можно сделать, что бы программы, которые запускает интерпретатор не использовали этот последний рядок, а использовали только верхнюю часть окна. Заранее спасибо за помощь!
|
Сообщ.
#2
,
|
|
|
Можно запустить эти программы, предварительно перенаправив их ввод/вывод в пайпы, которые уже будет обслуживать интерпретатор. Т.е., весь ввод интерпретатора подается в программу, а интрепретатор сам обрабатывает вывод программ, выводя строки нужным образом.
Пример создания пайпов и работы с ними есть во многих книжках (например, advanced linux programming). Собственно вывод можно сделать с использованием библиотеки ncurses. |
Сообщ.
#3
,
|
|
|
2mo3r: Я уже с этой пробеломой вожусь неделю, всё никак не получается
Пожалуйста, если для вас это большого труда не составит, приведите примерчик программы, которая запускает на выполнение команду к примеру "man man" и так что бы при запуске этой команды, команда "man man" занимала не весь экран, а одна строчка была свободна, в которой была размещена надпись к примеру: "this programm used ncurses". Заранее благодарен за помощь. |
Сообщ.
#4
,
|
|
|
а тебе интерпретатор нужно написать самому, или использовать какой-нибудь стандартный ( например в винде cmd, в Unix bash )?
|
Сообщ.
#5
,
|
|
|
Интерпритатор нужно написать самому.
|
Сообщ.
#6
,
|
|
|
какая ось и на чем пишешь?
|
Сообщ.
#7
,
|
|
|
Ось unix, язык C.
|
Сообщ.
#8
,
|
|
|
Не уверен, что это точно работает, но как-то так:
1. Интерпретатор запускает программу, перенаправляя ее ввод-вывод в pipe_in, pipe_out. 2. В цикле делает select (select используется для того, чтобы ожидать операции ввода-вывода) на свой stdin и pipe_out. Если есть данные в stdin, то отправить их в pipe_in. Если есть данные в pipe_out, то отобразить их на экране. 3. Если select возвращает EBADF, то это значит, что один из пайпов был закрыт. Если это pipe_in или pipe_out, то программа завершилась. Пример привести, к сожалению, не могу. |
Сообщ.
#9
,
|
|
|
Пример
#include <curses.h> #include <unistd.h> #include <string.h> #include <stdlib.h> WINDOW *w1, *w2; void ifconfig(void) { FILE *f = popen("sh -c \"/sbin/ifconfig\"", "r"); if (!f) { wprintw(w2, "error"); return; } for(;;) { int c = fgetc(f); if (c == EOF) break; wprintw(w1, "%c", c); } pclose(f); wrefresh(w1); } int main (int argc, char *argv[]) { initscr(); cbreak(); keypad(stdscr, TRUE); w1 = newwin(LINES-4, COLS, 0, 0); scrollok(w1, TRUE); wrefresh(w1); w2 = newwin(3, COLS, LINES-3, 0); mvwprintw(w2, 0, 2, "Hi there!"); wrefresh(w2); ifconfig(); /* типа пауза */ char x[80]; int messageLength = 79; mvwgetnstr( w2, 1, 1, x, messageLength); endwin(); return 0; } Но это, правда, работает только для программ, которые пользуют минимум функций терминала. Может стоит попробовать перед запуском других программ изменить переменные окружения, которые описывают геометрические параметры терминала (хотя в той же ncurses можно указать, что размеры определять надо системным вызовом, а не через окружение). |
Сообщ.
#10
,
|
|
|
Мысли уловил, попытаюсь их реализовать!
|
Сообщ.
#11
,
|
|
|
еще можно открыть свой виртуальный терминал и задать ему размер.
а ввод/вывод дублировать на основной |
Сообщ.
#12
,
|
|
|
Вот модифицировал исходник под себя. Всё работает просто замечательно, если запускаемая команда не использует стандартный ввод. Вот если использует - начинаются проблемы. Подскажите, что мне нужно сделать со стандартным вводом запускаемой программы, для того что бы будущий интерпретатор корректно работал.
#include <curses.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> WINDOW *w1, *w2; void cmd(void) { int fds[2]; int status; FILE *stream; pid_t pid; pipe(fds); switch (pid=fork()) { case 0: dup2(fds[1], STDOUT_FILENO); execlp("bash",0); exit(0); default: close(fds[1]); stream = fdopen(fds[0],"r"); if (!stream) { wprintw(w2, "error"); wrefresh(w2); return; } for(;;) { int c = fgetc(stream); if (c == EOF) break; wprintw(w1, "%c", c); wrefresh(w1); } pclose(stream); break; } mvwprintw(w2, 1, 2, "OK"); wrefresh(w2); } int main (int argc, char *argv[]) { initscr(); cbreak(); keypad(stdscr, TRUE); w1 = newwin(LINES-4, COLS, 0, 0); scrollok(w1, TRUE); wrefresh(w1); w2 = newwin(3, COLS, LINES-3, 0); mvwprintw(w2, 0, 2, "Hello World!"); wrefresh(w2); cmd(); char x[80]; int messageLength = 79; mvwgetnstr( w2, 1, 1, x, messageLength); endwin(); return 0; } |
Сообщ.
#13
,
|
|
|
Что неужели никто не может помочь? Что я только с файл. дискрипторами не делал никак не получается
Помогите с stdin сделать то же, что я сделали для stdout. А то у меня никак не получается Программы которые не используют stdin запускаются хорошо. Я запутался, ПОМОГИТЕ! |
Сообщ.
#14
,
|
|
|
В принципе, точно так же, как и stdout: сделать пайп и dup2 для этого пайпа. И еще в цикле for(;;) нужно будет делать не просто fgetc, а select, и потом fgetc — потому что неизвестно, откуда придут данные — от запускаемой программы или из stdin.
|
Сообщ.
#15
,
|
|
|
Цитата mo3r @ В принципе, точно так же, как и stdout: сделать пайп и dup2 для этого пайпа. И еще в цикле for(;;) нужно будет делать не просто fgetc, а select, и потом fgetc — потому что неизвестно, откуда придут данные — от запускаемой программы или из stdin. Что самое странное я так всё и делаю, но оно не работает. Не можешь код привести??? Потому что я думаю, что я какой мелкий нюанс упускаю. ПЛЗ! |