Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » нестандартный output

Ответить
Настройки темы
нестандартный output

Аватара для Guest

Guest



Профиль | Цитировать


Хочу сделать так:с помощью функции popen() открыть /bin/bash на запись,записать туда допустим "uname -r " но вывод uname -r произвести не на stdout ,а на другой ф.дескриптор с помощью dup2():
printf(">>>> Opening stream popen <<<<\n";
FILE *fp,*lp;
lp=fopen("output","w+";
char ch[20];
fp=popen("/bin/bash","w";
printf("Enter command\n";
scanf("%s",&ch);
dup2(0,lp);
dup2(1,lp);
fprintf(fp,"%s",ch);
pclose(fp);
Но все равно выводится на экран а не в файл output!


*

Отправлено: 16:21, 28-05-2004

 

Аватара для Guest

Guest


Профиль | Цитировать


Я сам запутался.....
Прежде я решил сделать все сначала(ну в смысле не переделать)
Сперва я сделал клиент - сервер,клиент просто передает одно сообщение(строку) серверу.Дальше я решил сделать цикл отправки и приема сообщений .Вроде получается.
Но вот пара вопросов:
Почему на код
Код: Выделить весь код
 if(strcmp(s,"kill")==0) {
       printf("Exiting...\n");
exit(0)
}
Где s - строка для посылки,он после первого вызова send() пишет Segmentation fault.
Мне тогда выход из кллиента не сделать!
И еще один вопрос - если я скажем сервер запустил,потом послал ему строку "kill",сервер выключился,то если сразу его врубить то он пишет "BIND() :Address already in use" и приходится просто немного ждать!Я ведь делаю в конце программы
close(s)
close(s_new)
shutdown(....);
в чем дело?
Сейчас я постараюсь сам решить вопрос чтобы не сбивать с толко вас и себя....

Добавлено:

так проблемму решил,т.е теперь клиент - сервак свободно обмениваются сообщениями.

Отправлено: 16:10, 09-06-2004 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для Guest

Guest


Профиль | Цитировать


2hasherfrog: Ура почти получилось!
Теперь если я скажем посылаю серверу команду "uname" он обратно посылает "Linux"
Но теперь вот что.Я максимум могу принимать одну строку,поэтому команда df вернет мне всего лишь одну строчку.Это происходит потому что я вызываю recv() только один раз - мне как я понял нужно сделать цикл с приемом сообщения....только вот не получается!
Вот сервер в "кратком содержании":
Код: Выделить весь код
.....
s_new=accept(..);
....
while(1) {
fp=popen("/bin/sh","w");
dup2(s_new,1);
dup2(s_new,2);
recv=(s,recved,sizeof(recved),0);//принимаем команду
fprintf(fp,"%s",recved);//пишем в /bin/sh а он автоматом отправляет на сокет

Теперь клиент


Код: Выделить весь код
while(1) {
printf("Enter command:");
scanf("%s",input);
send(s,input,sizeof(input),0);//посылаем команду
recv(s,recved,sizeof(recved),0);//принимаем результат
}
вот в клиенте как мне организовать цикл с приемом сообщения?

Отправлено: 19:25, 09-06-2004 | #12


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


Насчёт получения только одной строки из ожидаемого множества. Тут уже немного зыбкая почва. Не пробовал. Точнее, не пробовал именно так. По-другому я делал. у меня тоже была проблема - приходила только одна строка, потом был длительный таймаут, потом я просил ещё рез и тут приходила куча - и задержавшиеся сообщения, и новые. Но это потому программа основывалась на QProcess и там странно организована работа с пайпами. Поскольку в данном случае всё "своё", надо подумать... Может дело в самих пайпах, а может, в неправильной работе в ними.

Как вариант 1: может, надо добавить флаг  MSG_WAITALL в recv()?
Как вариант 2: Работайте с select.
Вот кусок моего старого кода от логгера:
Код: Выделить весь код
    do { 
        ... 
        //listen child error messages 
        if (!bPipeIsBroken) 
        { 
            //starts listen child 
            fd_set rfds; 
            struct timeval tv; 
            int retval; 
 
            FD_ZERO(&rfds); 
            FD_SET(fd[0], &rfds); 
            tv.tv_sec = 1; 
            tv.tv_usec = 100; 
 
            retval = select(fd[0] + 1, &rfds, NULL, NULL, &tv); 
            // if (retval == -1)  -> broken pipe? 
            if (retval == -1) break; 
            // if (retval == 0) -> no data at input 
            if (retval == 0) continue; 
 
            char buffer[512]; 
            ssize_t msg_len = read(fd[0], buffer, 512); 
            if ((msg_len == -1)  ||  (msg_len == 0)) 
            { 
                bPipeIsBroken = 1;  //$$ 
                //if (g_bVerbouse) printf("Pipe seems to be broken\n"); //$$ 
                continue; //error, but not SIGPIPE //$$ 
            } 
 
            buffer[msg_len] = 0; 
            //Ucop checks only stderr channel.Thus, if program-child will ask something or 
            //requests input from user, its question will be displayed. Lucky hit! 
            logger.fprintf("%s", buffer); 
        } 
    } while (1);
Очень похоже на [s]man select[/s]. Разберётесь, ладно? Я сейчас занимаюсь очень похожей проблемой, только у меня всё гораздо сложней.

ЗЫ. Нда-с, не совсем понятно. fd[1] - конец трубы, из которой должна идти инфа.
logger - класс логгера, не обращайте внимания.

[s]Исправлено: hasherfrog, 10:13 10-06-2004[/s]

Отправлено: 10:10, 10-06-2004 | #13


Аватара для Guest

Guest


Профиль | Цитировать


ок,попробую разобратся......

Отправлено: 11:55, 10-06-2004 | #14


Аватара для Guest

Guest


Профиль | Цитировать


У меня еще такой вопрос(надеюсь последний)
После того как popen запускает прогу ,то после завершения проги посылается какой-нибудь флаг типа EOF или еще что-то?Так было бы очень удобно,ведь я б знал до какого места считывать строки из сокета...

Отправлено: 14:24, 11-06-2004 | #15


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


Вообще-то, хм... popen - это по сути, fork. Какая программа должна завершиться первой? Та, которая отпочковалась или та, которая слушает процесс?
В приведённом мной последнем куске кода строка if (retval == -1) break прекращает слушание, потому что программа-потомок судя по всему, окончила работу. feof для FILE* при этом вернёт true, кстати. Но лучше не рассчитывать на FILE*, а работать с select'ом Ей можно после этого выходить. Если же основная программа хочет выйти первой, то она просто должна посиснуть на проводе с помощью pclose. как pclose вернёт управление - потомка нет, можно и самой уходить.
Надеюсь, мысль понятна...

Отправлено: 14:37, 11-06-2004 | #16


Аватара для Guest

Guest


Профиль | Цитировать


Так popen у меня запускается,и он я запускаю /bin/sh,которая вырубится если я пошлю скажем команду killpopen.А та утилита,которую я запускаю с помощью sh и должна что то вернуть в конце!Вот к чему я клоню!
У меня же такая схема:
Сервак получает команду,записывает ее в fp,там /bin/sh форкает прогу какую-нибудь,прога все выводит на сокет - я со стороны клиента должен все что она вывела принять....... только я не знаю СКОЛЬКО раз мне нужно вызвать функцию recv,ведь мне данные приходят по строкам!
а если бы в конце прога что-то посылала,то я мог бы сделать что-то вроде
while(recved!=EOF) {
recv(s,recved,sizeof(recved),0);
printf("%s",recved);
}
Вот!
p.s. ваша мысль плохо понятна(в смысле я плохо понимаю....)

Добавлено:

Это похоже примерно на это:
сервак:
char first[20]="aaaaaaaa";
char second[20]="bbbbbbb";
char third[20]="EOF";
send(first);
send(second);
send(third);
клиент:
while(recved!="EOF" {
recv(&recved);
printf(recved);
}

Отправлено: 16:27, 11-06-2004 | #17


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


Всё ходим вокруг одного и того же.
Код: Выделить весь код
do { 
  if (select(...) == -1) 
  break; //закрылся /bin/sh 
  recv(...) 
  printf(...); 
} while (1); //пока не закроется /bin/sh
Вы не сможете узнать о закрытии конкретной отфоркнутой от /bin/sh программы. Вы можете только читать вывод всех программ, выполняющихся в рамках \bin\sh.

 

Отправлено: 16:36, 11-06-2004 | #18


Аватара для Guest

Guest


Профиль | Цитировать


Я вас начинаю понимать!
Возможно я просто использую неудобный механизм передачи - мысль с завершением самой /bin/sh понятна.т.е после записи команды в /bin/sh,я вырубаю коннект(pclose(fp)),соответственно на клиенте вырубается дескриптор сокета(select) а что бы послать следующую команду,нужно просто заново присоединится с серваком,и повторить цикл.......только бы это щас реализовать.........
(p.s. надо бы зарегистрироватся...)

Отправлено: 16:42, 11-06-2004 | #19



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » нестандартный output

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Нет звука на звуковой карте Realtek HD Audio output ButaJIuK Непонятные проблемы с Железом 7 21-03-2009 13:26
Нестандартный шрифт на Веб-странице darksmoke Вебмастеру 1 02-02-2009 07:56
Установка - Нестандартный способ установки WinVISTA Сергей Витальевич Microsoft Windows Vista 23 25-11-2008 05:36
Проблема с LPT портом - нестандартный адрес gahcep Непонятные проблемы с Железом 0 29-04-2008 13:06
Проблема с Audio output device iBass Непонятные проблемы с Железом 0 11-04-2008 19:57




 
Переход