LINUX.ORG.RU

Как реализовать самозапуск чере fork+exec?


0

0

Короче нужно запускать программу через казанню комбинацию, но не просто запускать а с помощью xinit'a, т.е. execlp ( /usr/X11R6/bin/xinint, /usr/X11R6/bin/xinint, /usr/bin/ldm, 0 ). А после такого запуска, же выполнять код QT. Пробовал делать файл-метку для обозначения запуска, но в итоге получалось через раз, т.е. файл не удалялся.

#include "ldm.h"


size_t get_executable_path ( char* buffer, size_t len )
{
char* path_end;

if ( readlink ("/proc/self/exe", buffer, len ) <= 0 )
return -1;

path_end = strrchr ( buffer, '/' );
if ( path_end == NULL )
return -1;

++path_end;

*path_end = '\0';

return ( size_t ) ( path_end - buffer );
}

void go_to_cur_dir ( )
{
char path[PATH_MAX];
get_executable_path (path, sizeof (path));
chdir ( path );
}

void set_run ( )
{
QFile *run = new QFile ( LOCK );
run->open ( IO_WriteOnly );
run->putch ( getpid ( ) );
run->close ( );
delete run;
}

void rem_run ( )
{
QFile *run = new QFile ( LOCK );
run->remove ( );
delete run;
}

bool run ( )
{
if ( QFile::exists ( LOCK ) )
return true;
else
return false;
}

void wrap ( )
{
passwd *pw= getpwnam ( "root" );
setenv ( "HOME", pw->pw_dir, 1 );
setenv ( "USER", "root", 1 );

pid_t pid = fork ( );
if ( pid == 0 )
{
pid_t pid = fork();
if ( pid == 0 )
{
set_run ( );
execlp ( XINIT, XINIT, LDM, 0 );
rem_run ( );
}
}
rem_run ( );
}

int main ( int argc, char **argv )
{
go_to_cur_dir ( );
if ( run ( ) )
{
rem_run ( );

QApplication app ( argc, argv );

ldm *login = new ldm;
app.setMainWidget ( login );
login->show ( );

return app.exec ( );
}
else
{
wrap ( );
}
}


Заранее спасибо!!!

★★★★★

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


P.S.
а что у тебя делает get_executable_path() ?
уж не тоже ли самое что и делает стандартный dirname?
man 3 dirname ;)


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

> а что у тебя делает get_executable_path() ?

Она возвращает путь к прогграмме, т.е. путь в папку где лежит прога.

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

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


void wrap ( )
{
passwd *pw= getpwnam ( "root" );
setenv ( "HOME", pw->pw_dir, 1 );
setenv ( "USER", "root", 1 );

pid_t pid = fork ( );
if ( pid == 0 )
{
pid_t pid = fork();
if ( pid == 0 )
{
set_run ( );
execlp ( XINIT, XINIT, LDM, 0 );
rem_run ( ); <----- ты об этом
}
}
rem_run ( ); <-------- ты об этом
}


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

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

void wrap ( ) 
{ 
	passwd *pw= getpwnam ( "root" ); 
	setenv ( "HOME", pw->pw_dir, 1 ); 
	setenv ( "USER", "root", 1 ); 
	
	pid_t pid = fork ( ); 
	if ( pid == 0 ) { 
		pid_t pid = fork(); 
		if ( pid == 0 ) { 
			set_run ( ); 
			execlp ( XINIT, XINIT, LDM, 0 ); 
			rem_run ( ); //эта строка действительно 
                               //не выполнится при успешном запуске execlp()
		} 
	} 
	rem_run ( ); // эта строка выполнится двумя процессами,
                   //родителем и первым чилдом (кстати зачем тебе два чилда?)
}

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

С форками работаю почти первый раз. И изучал их работу на примере логонера (mdm - не мой) в котором применялось даже три чилда, почему не знаю. Я сначала поставил три - работает, потом два - работает, один... - не работает. Поэтому осталось два.

Короче это всё работает если работа проги завершается нормально. Иначе он будет описанная проблема, файл не удаляется.

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

... а если так:


void wrap ( )
{
passwd *pw= getpwnam ( "root" );

setuid( pw->pw_uid );
setgid( pw->pw_gid );
setenv ( "HOME", pw->pw_dir, 1 );
setenv ( "USER", pw->pw_name, 1 );

int r = 0;
pid_t pid = fork ( );
if ( pid == 0 )
{
pid_t pid = fork();
if ( pid == 0 )
{
set_run ( );
r = execlp ( XINIT, XINIT, LDM, 0 );
}
}
if ( r < 0 ) rem_run ( ); <----- вот так
}

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

Объясни плиз зачем нужны эти файлы-флажки,
а то что-то я до конца не понял...

P.S.
Код плиз форматируй в дальнейшем (Performatted text), а то очень напряжно его читать

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

Мне надо что бы после форка в проге начинал работать код QT который без Х-ов бесполеезен, но как дать программе знать что она была запщена, в переменных хранить невозможно. Вот и пришло в голову как казать программе что она запщена - файл флажок в /tmp.

cyclon ★★★★★
() автор топика

Вариант #1:

ln -s ldm /usr/bin/runldm

------------------------------------------------
#define LDM     "/usr/bin/ldm"
#define RUN_LDM "runldm"
#define XINIT   "/usr/X11R6/bin/xinint"

int main(int argc, char *argv[])
  {
  char *name = strrchr(argv[0]);
  name = name ? name + 1 : argv[0];

  if (!strcmp(name, RUN_LDM))
    {
    execlp(XINIT, XINIT, LDM, 0);
    perror(XINIT);
    return 1;
    }

  //Qt stuff here
  }
-------------------------------------------------



Вариант #2:

-------------------------------------------------
#define LDM     "/usr/bin/ldm"
#define XINIT   "/usr/X11R6/bin/xinint"

int main(int argc, char *argv[])
  {
  if (!getenv("DISPLAY"))
    {
    execlp(XINIT, XINIT, LDM, 0);
    perror(XINIT);
    return 1;
    }

  //Qt stuff here
  }
-------------------------------------------------

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

Пардон nobody осмотрелся, там один.

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

А три форка - минимум. Первые два - чтобы стать демоном. Третий - чтобы перезапускать slave программу. Все очень понятно :)

PS: Тов. cyclon, вы когда нам покажете результаты? А то уже совсем ЛОР затерроризировали, а результата не видно :O)

Braindead

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

> PS: Тов. cyclon, вы когда нам покажете результаты? А то уже совсем ЛОР затерроризировали, а результата не видно :O)

см. новый тред.

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