На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела *nix / gcc / Eclipse / Qt / wxWidgets / GTK+
  • При создании темы ОБЯЗАТЕЛЬНО указывайте версию тулкита / библиотеки / компилятора.
  • Перед тем как задать вопрос, сформулируйте его правильно, чтобы вас могли понять.
  • Нарушение Правил может повлечь наказание со стороны модераторов.


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: archimed7592
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Разделение терминала , Разделение окна терминала на две части
    Здравствуйте. У меня есть задания по написания своего собственного командного интерпретатора. Я уже практически всё написал, но столкнулся с одной проблемой, которую я на данный момент не могу решить. Мне нужно у терминал «отколоть» последний рядок для нужд интерпретатора (вывод информации обо всех фоновых процессах). Помогите, как это можно сделать, что бы программы, которые запускает интерпретатор не использовали этот последний рядок, а использовали только верхнюю часть окна. Заранее спасибо за помощь!
      Можно запустить эти программы, предварительно перенаправив их ввод/вывод в пайпы, которые уже будет обслуживать интерпретатор. Т.е., весь ввод интерпретатора подается в программу, а интрепретатор сам обрабатывает вывод программ, выводя строки нужным образом.
      Пример создания пайпов и работы с ними есть во многих книжках (например, advanced linux programming). Собственно вывод можно сделать с использованием библиотеки ncurses.
        2mo3r: Я уже с этой пробеломой вожусь неделю, всё никак не получается :(
        Пожалуйста, если для вас это большого труда не составит, приведите примерчик программы, которая запускает на выполнение команду к примеру "man man" и так что бы при запуске этой команды, команда "man man" занимала не весь экран, а одна строчка была свободна, в которой была размещена надпись к примеру: "this programm used ncurses". Заранее благодарен за помощь.
          а тебе интерпретатор нужно написать самому, или использовать какой-нибудь стандартный ( например в винде cmd, в Unix bash )?
            Интерпритатор нужно написать самому.
              какая ось и на чем пишешь?
                Ось unix, язык C.
                  Не уверен, что это точно работает, но как-то так:
                  1. Интерпретатор запускает программу, перенаправляя ее ввод-вывод в pipe_in, pipe_out.
                  2. В цикле делает select (select используется для того, чтобы ожидать операции ввода-вывода) на свой stdin и pipe_out. Если есть данные в stdin, то отправить их в pipe_in. Если есть данные в pipe_out, то отобразить их на экране.
                  3. Если select возвращает EBADF, то это значит, что один из пайпов был закрыт. Если это pipe_in или pipe_out, то программа завершилась.

                  Пример привести, к сожалению, не могу.
                    Пример
                    ExpandedWrap disabled
                      #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 можно указать, что размеры определять надо системным вызовом, а не через окружение).
                      Мысли уловил, попытаюсь их реализовать!
                        еще можно открыть свой виртуальный терминал и задать ему размер.
                        а ввод/вывод дублировать на основной
                          Вот модифицировал исходник под себя. Всё работает просто замечательно, если запускаемая команда не использует стандартный ввод. Вот если использует - начинаются проблемы. Подскажите, что мне нужно сделать со стандартным вводом запускаемой программы, для того что бы будущий интерпретатор корректно работал.

                          ExpandedWrap disabled
                            #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;
                            }
                          Сообщение отредактировано: Headina -
                            Что неужели никто не может помочь? Что я только с файл. дискрипторами не делал никак не получается :'(
                            Помогите с stdin сделать то же, что я сделали для stdout. А то у меня никак не получается :(
                            Программы которые не используют stdin запускаются хорошо. Я запутался, ПОМОГИТЕ!
                            Сообщение отредактировано: Headina -
                              В принципе, точно так же, как и stdout: сделать пайп и dup2 для этого пайпа. И еще в цикле for(;;) нужно будет делать не просто fgetc, а select, и потом fgetc — потому что неизвестно, откуда придут данные — от запускаемой программы или из stdin.
                                Цитата mo3r @
                                В принципе, точно так же, как и stdout: сделать пайп и dup2 для этого пайпа. И еще в цикле for(;;) нужно будет делать не просто fgetc, а select, и потом fgetc — потому что неизвестно, откуда придут данные — от запускаемой программы или из stdin.

                                Что самое странное я так всё и делаю, но оно не работает. Не можешь код привести??? Потому что я думаю, что я какой мелкий нюанс упускаю. ПЛЗ!
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0380 ]   [ 15 queries used ]   [ Generated: 19.05.24, 00:16 GMT ]