Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Богатырев А. Весь текст 1009.15 Kb

Хрестоматия по программированию на Си в Unix

Предыдущая страница Следующая страница
1 ... 46 47 48 49 50 51 52  53 54 55 56 57 58 59 ... 87
                    PP.pid = child;
                    PP.command = av[0];
                    time( &PP.t_start ); PP.t_stop = PP.t_start;

                    signal( SIGHUP,  wm_done );
                    signal( SIGINT,  wm_done );
                    signal( SIGQUIT, wm_done );
                    signal( SIGTERM, wm_done );
                    signal( SIGILL,  wm_done );
                    signal( SIGBUS,  wm_done );
                    signal( SIGSEGV, wm_done );
            }
    }

    char buf[ BSIZE ];   /* буфер для передачи данных */

    /*                               /dev/pty?    /dev/ttyp?
         экран         *--------*          *--------*
         /|||          |        |  PP.pfd  |        |
        |||||<-STDOUT--|  мой   |<---------| псевдо |<-STDOUT---|
         \|||          |терминал|          |терминал|<-STDERR---|трассируемый
                       |(базовый)          |        |           |процесс
        -------        |        |  STDIN   |        |           |
        |.....|-STDIN-->        |---------->        |--STDIN--->|
        |_____|        |        |          |        |
        клавиатура     *--------*          *--------*
                                        master     slave

    */

    /* Опрос дескрипторов */
    void wm_select(){
            int nready;
            int nfds;
            int maxfd;
            int nopen;  /* число опрашиваемых дескрипторов */
            register f;

            fd_set set, rset;       /* маски */
            struct timeval timeout, rtimeout;

            FD_ZERO(&set); nopen = 0;        /* очистка маски */

            FD_SET (PP.pfd, &set); nopen++;  /* учесть в маске */
            FD_SET (STDIN,  &set); nopen++;
            maxfd = max(PP.pfd, STDIN);

            timeout.tv_sec = 3600;      /* секунд */
            timeout.tv_usec = 0;        /* миллисекунд */

А. Богатырев, 1992-95                  - 270 -                              Си в UNIX

            nfds =  maxfd + 1;
            while( nopen ){
               rset = set;
               rtimeout = timeout;

               /* опросить дескрипторы */
               if((nready = select( nfds, &rset, NULL, NULL, &rtimeout )) <= 0)
                    continue;

               for(f=0; f < nfds; f++ )
                    if( FD_ISSET(f, &rset)){  /* дескриптор f готов */
                            int n;

                            if((n = read(f, buf, sizeof buf)) <= 0 ){
                                FD_CLR(f, &set); nopen--; /* исключить */
                                close(f);

                            } else {
                                int fdout;

                                /* учет и контроль */
                                if( f == PP.pfd ){
                                    fdout = STDOUT;
                                    PP.out_bytes += n;
                                    if( fpscript )
                                        fwrite(buf, 1, n, fpscript);

                                } else if( f == STDIN  ) {
                                    fdout = PP.pfd;
                                    PP.in_bytes += n;
                                    if( halfflag && fpscript )
                                        fwrite(buf, 1, n, fpscript);
                                    if( autoecho )
                                        write(STDOUT, buf, n);
                                }
                                write(fdout, buf, n);
                            }
                    }
            }
    }

А. Богатырев, 1992-95                  - 271 -                              Си в UNIX

    int main(ac, av) char **av;
    {
            while( ac > 1 && *av[1] == '-' ){
                    switch(av[1][1]){
                    case 's':
                            scriptflg++;
                            break;
                    case 'f':
                            av++; ac--;
                            protocol = av[1];
                            scriptflg++;
                            break;
                    case 'h':
                            halfflag++;
                            break;
                    case 'a':
                            autoecho++;
                            break;
                    default:
                            fprintf(stderr, "Bad key %s\n", av[1]);
                            break;
                    }
                    ac--; av++;
            }
            if( scriptflg ){
                    fpscript = fopen( protocol, "w" );
            }
            ac--; av++;

            wm_init();
            PP = wm_ptypair();
            if( PP.pfd < 0 ){
                    fprintf(stderr, "Cannot get pty. Please wait and try again.\n");
                    return 1;
            }
            wm_fixtty();
            wm_startshell(ac, av);
            go++;
            wm_select();
            wm_done(0);
            /* NOTREACHED */
            return 0;
    }

6.12.  Простой интерпретатор команд.
     Данный раздел просто приводит исходный  текст  простого  интерпретатора  команд.
Функция match описана в главе "Текстовая обработка".

А. Богатырев, 1992-95                  - 272 -                              Си в UNIX

    /* Примитивный интерпретатор команд. Распознает построчно
     * команды вида: CMD ARG1 ... ARGn FILE >>FILE >&FILE >>&FILE
     * Сборка: cc -U42 -DCWDONLY sh.c match.c pwd.c -o sh
     */

    #include /* определение типов, используемых системой */
    #include       /* описание библиотеки ввода/вывода  */
    #include      /* описание сигналов                 */
    #include       /* определение O_RDONLY              */
    #include       /* коды системных ошибок             */
    #include       /* макросы для работы с символами    */
    #include      /* эмуляция файловой системы BSD 4.2 */
    #include         /* работа с /etc/passwd              */
    #include    /* описание формата wait()           */

    char cmd[256];          /* буфер для считывания команды */
    #define   MAXARGS 256   /* макс. количество аргументов  */
    char *arg[MAXARGS];     /* аргументы команды */
    char *fin, *fout;       /* имена для перенаправления ввода/вывода */
    int  rout;              /* флаги перенаправления вывода */

    char *firstfound;       /* имя найденной, но невыполняемой программы */
    #define LIM ':'         /* разделитель имен каталогов в path */
    extern char *malloc(), *getenv(), *strcpy(), *getwd();
    extern char *strchr(), *execat();
    extern void callshell(), printenv(), setenv(), dowait(), setcwd();
    extern struct passwd   *getpwuid();
            /* Предопределенные переменные */
    extern char **environ;  /* окружение: изначально смотрит на тот же
                             * массив, что и ev из main() */
    extern int errno;       /* код ошибки системного вызова   */

    char *strdup(s)char *s;
    { char *p; return(p=malloc(strlen(s)+1), strcpy(p,s)); }
            /* strcpy() возвращает свой первый аргумент */
    char *str3spl(s, p, q) char *s, *p, *q;
    { char *n = malloc(strlen(s)+strlen(p)+strlen(q)+1);
      strcpy(n, s); strcat(n, p); strcat(n, q); return n;
    }

    int cmps(s1, s2) char **s1, **s2;
    { return strcmp(*s1, *s2); }

А. Богатырев, 1992-95                  - 273 -                              Си в UNIX

    /* Перенаправить вывод */
    #define APPEND 0x01
    #define ERRTOO 0x02
    int output (name, append, err_too, created) char *name; int *created;
    {
        int     fd;
        *created = 0;     /* Создан ли файл ? */

        if( append ){                   /* >>file */
            /* Файл name существует? Пробуем открыть на запись */
            if((fd = open (name, O_WRONLY)) < 0) {
                if (errno == ENOENT) /* Файл еще не существовал */
                    goto CREATE;
                else
                    return 0;    /* Не имеем права писать в этот файл */
            }
            /* иначе fd == открытый файл, *created == 0 */
        }else{
    CREATE: /* Пытаемся создать (либо опустошить) файл "name" */
            if((fd = creat (name, 0666)) < 0 )
                        return 0;     /* Не могу создать файл  */
            else        *created = 1; /* Был создан новый файл */
        }
        if (append)
            lseek (fd, 0l, 2);      /* на конец файла */
     /* перенаправить стандартный вывод */
        dup2(fd, 1);
        if( err_too ) dup2(fd, 2);  /* err_too=1 для >& */
        close(fd); return 1;
    }

    /* Перенаправить ввод */
    int input (name) char *name;
    {
        int     fd;
        if((fd = open (name, O_RDONLY)) < 0 ) return 0;/* Не могу читать */
     /* перенаправить стандартный ввод */
        dup2(fd, 0); close(fd); return 1;
    }

А. Богатырев, 1992-95                  - 274 -                              Си в UNIX

    /* запуск команды */
    int cmdExec(progr, av, envp, inp, outp, outflg)
            char *progr;       /* имя программы */
            char **av;         /* список аргументов */
            char **envp;       /* окружение */
            char *inp, *outp;  /* файлы ввода-вывода (перенаправления) */
            int outflg;        /* режимы перенаправления вывода */
    {
            void (*del)(), (*quit)();
            int pid;
            int cr = 0;

            del = signal(SIGINT, SIG_IGN); quit = signal(SIGQUIT, SIG_IGN);
            if( ! (pid = fork())){     /* ветвление */
               /* порожденный процесс (сын) */
               signal(SIGINT, SIG_DFL); /* восстановить реакции */
               signal(SIGQUIT,SIG_DFL); /* по умолчанию         */
               /* getpid() выдает номер (идентификатор) данного процесса */
               printf( "Процесс pid=%d запущен\n", pid = getpid());

               /* Перенаправить ввод-вывод */
               if( inp ) if(!input( inp )){
                 fprintf(stderr, "Не могу <%s\n", inp ); goto Err;
               }
               if( outp )
                   if(!output (outp, outflg & APPEND, outflg & ERRTOO, &cr)){
                       fprintf(stderr, "Не могу >%s\n", outp ); goto Err;
                   }
     /* Заменить программу: при успехе
      * данная программа завершается, а вместо нее вызывается
      * функция main(ac, av, envp) программы, хранящейся в файле progr.
      * ac вычисляет система.
      */
               execvpe(progr, av, envp);

    Err:
      /* при неудаче печатаем причину и завершаем порожденный процесс */
               perror(firstfound ? firstfound: progr);
               /* Мы не делаем free(firstfound),firstfound = NULL
                * потому что данный процесс завершается (и тем ВСЯ его
                * память освобождается) :
                */
               if( cr && outp )  /* был создан новый файл     */
                   unlink(outp); /* но теперь он нам не нужен */

               exit(errno);
            }
            /* процесс - отец */

            /* Сейчас сигналы игнорируются, wait не может быть оборван
             * прерыванием с клавиатуры */
            dowait();       /* ожидать окончания сына */
            /* восстановить реакции на сигналы от клавиатуры */
            signal(SIGINT, del); signal(SIGQUIT, quit);
            return pid;     /* вернуть идентификатор сына */
    }

А. Богатырев, 1992-95                  - 275 -                              Си в UNIX

    /* Запуск программы с поиском по переменной среды PATH */
    int execvpe(progr, av, envp) char *progr, **av, **envp;
    {
            char *path, *cp;
            int try = 1;
Предыдущая страница Следующая страница
1 ... 46 47 48 49 50 51 52  53 54 55 56 57 58 59 ... 87
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама