URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7860
[ Назад ]

Исходное сообщение
"Каким образом bash показывает приглашение?"

Отправлено Towellie , 26-Янв-09 17:05 
Вобщем наколбасил программу для проброса стандартного ввода/вывода(stdin stdout stderr) через пайпы
запускаю таким образом bash - а тот не показывает приграшение на ввод каким способом он выводит приглашение на ввод? - Мне вообше login(Тоже молчит как партизан) нужен - просто баш нагляднее. А ls - работает нормально. Может есть еще какой то дескриптор?

Вот моя программка - прокоипилируйте ее у себя и повводите какие нибудь команды ls там ошибки все три дескриптера пробрасываются - вам будет интересно.
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/poll.h>

int main()
{
    int pid[2],pipe0[2],pipe1[2],pipe2[2];
    
    char *prog1_argv[2],buffer[1024];
    prog1_argv[0] = "/usr/local/bin/bash";
    prog1_argv[1] = NULL;
    
    
    /*
    * Create the pipe
    */
    if (pipe(pipe0) < 0)
    {
        perror ("pipe 0");
        return 0;
    }
    if (pipe(pipe1) < 0)
    {
        perror ("pipe 1");
        return 0;
    }
    if (pipe(pipe2) < 0)
    {
        perror ("pipe 2");
        return 0;
    }
    
    /*
    * Create a process space for the ls  
    */
    if ((pid[0]=fork()) < 0)
    {
        perror ("Fork failed");
        return 0;
    }
    
    if (!pid[0])
    {
        /*
        * Set stdout to pipe    
        */
        dup2(pipe0[1], 1);
        dup2(pipe1[0], 0);
        dup2(pipe2[1], 2);
        //perror("ERRRORTWERQWWER!\n");
        //printf("\n");
        //printf("My pid is %d\n",getpid());    
        /* Execute the ls */
        execvp(prog1_argv[0],prog1_argv);
        }
    if (pid[0])
    {
    /*parent*/
        struct pollfd fds[3];
        fds[0].fd = pipe0[0];
        fds[0].events = POLLIN;
        fds[1].fd = pipe2[0];
        fds[1].events = POLLIN;
        fds[2].fd = 0;
        fds[2].events = POLLIN;        
        int i,len;
        //buffer[0]=0;
        while (1)
        {    
            /* Опрашиваем с бесконечным интервалом ожидания
            (обозначается -1) */
            if (poll(fds, 3, 1000) < 0)
            {
                printf("Poll Error\n");
                return 0;
            }
            //sleep(1);
            for (i=0;i<3;i++)
            {
            switch (fds[i].revents)
                {
                default: /* Для события-ошибки */
                    printf("Error\n");
                    return 0;
                case 0:
                    //printf("No Data\n");
                    break;  /* Событий не произошло */
                case POLLIN:
                        //printf("%d",i);
                        for (;;)
                        {
                            if(i==0)    len = read( pipe0[0], buffer, sizeof(buffer));//stdout
                            if(i==1)    len = read( pipe2[0], buffer, sizeof(buffer));//stderr
                            if(i==2)len = read( 0, buffer, sizeof(buffer));//stdin
                            //printf( "Recieved=%ld\n", len );
                            if ( len > 0 ) break;
                        }     
                        buffer[len] = '\0';
                        if(i==0)    printf("%d bytes was writed to stdout\n",fwrite(buffer, strlen(buffer), 1, stdout));
                        if(i==1)    printf("%d bytes was writed to stderr\n",fwrite(buffer, strlen(buffer), 1, stderr));
                        if(i==2)    printf("%d bytes was writed to pipe\n",write(pipe1[1],buffer, strlen(buffer)));
                break;
                }
            }    
        }
    }
    return 1;
}


Содержание

Сообщения в этом обсуждении
"Каким образом bash показывает приглашение?"
Отправлено vic , 26-Янв-09 17:18 
Приглашение на ввод будет тогда когда башу (или другой интерктивной программе) скажут прямо что надо в интерактивном режиме работать (например через ключ командной строки) или сам баш (или другая интерактивная программа) сам продетектит необходимость интерктивного режима, а детктит он по состоянию дескриптора, если дескриптор связан с терминалом, то интерактивный режим - приглашение.
Таким образом башу надо сказать что stdin и stdout у него терминалы или попробовать ключем принудить его к интерактивности :)

"Каким образом bash показывает приглашение?"
Отправлено Towellie , 26-Янв-09 17:29 
Вобщем с ключом -i он вылетает - видимо видит что его обманули. :|
Блин и что делать как его заставить записывать в pipe?


"Каким образом bash показывает приглашение?"
Отправлено vic , 26-Янв-09 17:30 
>Вобщем с ключом -i он вылетает - видимо видит что его обманули.
>:|
>Блин и что делать как его заставить записывать в pipe?

Почитать про терминал, про управление терминалом :)


"Каким образом bash показывает приглашение?"
Отправлено Towellie , 26-Янв-09 18:13 
http://symmetrica.net/uploads/linapi/linapi10.pdf
Если честно эта статья поставила меня в тупик - в ней говорится о том что если приложение не хочет писать в не в терминал - оно писать не будет :(
Есть какие нибудь идеи?

"Каким образом bash показывает приглашение?"
Отправлено 0dmin , 26-Янв-09 19:34 
>если приложение не хочет писать в не в терминал - оно писать не будет :(
>Есть какие нибудь идеи?

Как ты думаешь - для чего тебе советовали читать про управление терминалами?
Нет, не для улучшения английско :)
Пойми как прилада решает что вот это - терминал и подсунь своё ...


"Каким образом bash показывает приглашение?"
Отправлено const86 , 27-Янв-09 08:58 
>Блин и что делать как его заставить записывать в pipe?

А если создать pty? Зачем залезать через окно, когда рядом есть дверь и ключ в кармане лежит?
man 7 pty