LINUX.ORG.RU

Как запустить терминал из демона?


0

0

Здраствуйте!


Возникла проблемма, нужно запустить по событию из демона интерактивную программу (спрашивает имя пользователя пароль и т.д.) которая работает в обычном терменале.
Вот в принципе и суть вопроса!... как только не пытался: и напрямую открывал дескрипторы файлов псевдотерминалов... постоянно проблема с вводом в этот терминал, вывод на него работает нормально!
Помогите, что делать?

Если ты хочеш подключится к чужому терминалу то ты должен испросить разрешения текущего владельца терминала.

Хотя в общем плохо понятно чё те надо напиши поподробней - поподробней ответим

cvv ★★★★★
()

Я делал нечто похожее.
На 1 консоле висела некая программа (от Siemense), управляюшая производственной линией.
Захотелось руководству, чтобы печатаемые отчеты автоматов заносились в заводскую базу данных.
Ловил я их в фильтре lpd и надо было спросить пользователя хочет ли он распечатать задание или отправить его в базу данных.

Что было сделано:
1. Созданы два fifo (один от lpd к "диалогу с юзером", другой -- обратно)
2. На 12 вирт. консоли висела прога, ждущая команду от lpd через fifo_1, при получении команды делала chvt 12, чтобы переключиться с 1-ой консоли на 12-ую и через dialog получала данные от пользователя.
Данные возвращала фильтру lpd через fifo_2
3. делала chvt 1 -- вернуть юзера на 1-ую консоль к основной программе.

Проги (фильтр lpd и диалог на 12 консоле) были написаны на шел.
При использовании перл лучше использовать unix socket.

sdio ★★★★★
()
Ответ на: комментарий от sdio

Тоже вариант. Ещё бы неплохо запоминать vt на котором изначально работали.

cvv ★★★★★
()

2eugenex:

> постоянно проблема с вводом в этот терминал, вывод на него работает нормально!

Естественно! Выводить можешь, если имеешь право, а за ввод будешь сражаться с оригинальным читателем терминала.

Выход очевиден: узнать, что за шелл на нем висит и послать ему SIGSTOP. По окончании экзекуции послать ему SIGCONT

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Вдогонку:

Вышеописанный способ с переключением консолей совершенно Виндузовый: годится если только есть уверенность, что пользователь физически сидит за компъютером. Но Юних-пользователь может залогиниться откуда угодно. Например, у меня сейчас на моем десктопе штук 10 сессий к различным компьютерам открыты.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Да, так работает! Я попробывал сделать это из терминала ... но как это закодить, как узнать какой шелл запушен, и сколько их запущено!?

eugenex
() автор топика
Ответ на: комментарий от cvv

Поподробнее:

Есть некий демон, которому преспичело спросить пользователя у которого нет X-ов логин и пароль, по определённому событию, например, если он пингует какойнибудь комп...
Задача: открыть терминал и спросить инфу.

Я это делаю следующим образом!
Создаю pty с помощью:

if ((pid = forkpty(&fdMaster, pty_name, term, winsize)) < 0){
return -1;
}
else if (pid == 0) { // child
if (execl(appname, NULL, NULL) < 0) {
status = -1;
return status;
}
exit(0);
}
else { // parent
pid_t child;
int nread;

char buff[BUFFSIZE];
if ((child = fork()) < 0) { // error
status = -1;
return status;
}
else if (child == 0) { // child
for ( ; ; ) {
if ((nread = read(STDIN_FILENO, buff, BUFFSIZE)) < 0)
D("child read error ... \n");
else if (nread == 0)
break;
if (write(fdMaster, buff, nread) != nread)
D("child write error ... \n");
}
exit(0);
}
else { // parent
if (signal_intr(SIGTERM, sig_term) == SIG_ERR)
D("Error for SIG_TERM");

for ( ; ; ) {
if ((nread = read(fdMaster, buff, BUFFSIZE)) <= 0)
break;
if (write(STDOUT_FILENO, buff, nread) != nread){
status = -1;
}
}

if (sigcaught == 0) kill(child, SIGTERM);

status = 0;
return status;
}
exit(0);
}

Тут функция execl запускает прогу типа такой:

static char buf[MAX_PASS_LEN +1];
char *ptr;
sigset_t sig, sigsave;
struct termios term, termsave;
FILE *fp;
int c, n;

D(ctermid(NULL));

if ((fp = fopen(ctermid(NULL), "r+")) == NULL){
D("cannot open the terminal ...\n");
return (NULL);
}
setbuf(fp, NULL);

sigemptyset(&sig);
sigaddset(&sig, SIGINT);
sigaddset(&sig, SIGTSTP);
sigprocmask(SIG_BLOCK, &sig, &sigsave);

tcgetattr(fileno(fp), &termsave);
term = termsave;
term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
tcsetattr(fileno(fp), TCSAFLUSH, &term);

putc('\n', fp);
fputs(prompt, fp);

ptr = buf;
n = 0;
D("reading from terminal ...\n");
while ((c = getc(fp)) != '\n' && n < MAX_PASS_LEN) {
printf("you inserted symbol\n");
++n;
if (ptr < &buf[MAX_PASS_LEN])
*ptr++ = c;
}
*ptr = 0;
D("finished pass ...\n");
putc('\n', fp);

tcsetattr(fileno(fp), TCSAFLUSH, &termsave);

sigprocmask(SIG_SETMASK, &sigsave, NULL);
fclose(fp);
D("return pass code ...\n");
return (buf);

При этом возникает проблема!
писать в терминал я без проблем могу а читать нет!
Это действительно глючит с shellом. если посылать на шел SIGSTOP то всё ок, но как это сделать, как определить shell?

Или можо это всё сделать проще?

eugenex
() автор топика
Ответ на: комментарий от eugenex

eugenex (06.04.2005 10:31:59):

Приведенный тобой (немного ...странный) код не имеет отношения к проблеме записи демоном в существующий tty: ты САМ его создаешь, и САМ в него и пишешь, и читаешь. Не работает он потому, что ты сражаешься за терминал со своей же программой appname; никакого шелла у тебя нет вообще. Отвлекись немного, подумай, и все заработает, только выкини вообще appname.

> Есть некий демон, которому преспичело спросить пользователя у которого нет X-ов логин и пароль, по определённому событию, например, если он пингует какойнибудь комп... Задача: открыть терминал и спросить инфу.

В описанной постановке задача бессмыссленна.

Демон должен каким-то образом знать, с какого терминала юзер балует и лезть именно на этот терминал, иначе КОМУ будет адресовано сообщение? Про пинг -- вообще глупость -- как ты узнаешь, какой юзер тебя пингует?

Т.е., кто-то должен сообщить демону по крайней мере файл терминала. Наверное, этот же кто-то должен сообщить и ID текущего читателя tty.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Передача данных между демоном и терминалом не причём, необходим просто запуск из демона программы, которая работает в терминале спрашивает инфу и передаёт своими уже способами инфу в демон... Вроде так

Код вроде работает, создаётся псевдотерминал в котором прога пишет в терминал нормально но при чтении конфликты с шеллом!... :(

Реально может я и вобще не так делаю задачу?

eugenex
() автор топика
Ответ на: комментарий от eugenex

Или я сам чего-го не понял или ты не запускаешь терминал. Ты запускаешь сразу прогу. А надо вызывать что-то типа "xterm application". Вот тебе и будет терминал с приложением.

anonymous
()
Ответ на: комментарий от eugenex

2eugenex (06.04.2005 15:27:29):

> Реально может я и вобще не так делаю задачу?

Да, совершенно не так. Я уже писАл, что тебе надо.

1.

>необходим просто запуск из демона программы, которая работает в терминале

Каком терминале?

> ...спрашивает инфу...

У кого?

2.

> ...но при чтении конфликты с шеллом!

Каким шеллом? У тебя вообще нету шелла, ты свою прогу вместо него запускаешь!!

Твой псевдотерминал запускается вообще без интерфейса! Как заметил предыдущий анонимус, у твой псевдотерминал непонятно к чему подключен. Поведение такой конструкции вообще непредсказуемо!

Твоя читающая программа конфликтует с твоей аппликухой, и вместе они конфликтуют с шеллом, из-под которого ты это все пускаешь.

Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.