LINUX.ORG.RU

Передача аргументов через execlp в запускаемую программу.


0

0

#include <sys/types.h>
#include <unistd.h>
#include <iostream.h>

#define TEST "/home/alexandr/Documents/Coding/C++/MyProjects/ldm/src/test"
#define T "x"

int main(int argc, char **argv)
{
cout << argc << " " << argv[0] << " ";
if ( argc > 1 )
{
printf ( "Hello!!!" );
}
else
{
pid_t pid = fork();
if ( pid == 0 )
{
pid_t pid = fork();
if ( pid == 0 )
{
execlp ( TEST, T, 0 );
}
}
}
}

Вообщем запуск этой программы показывает что аргумент не был переда иначе бы я увидел строку "Hello!!!". А так я вижу:

bash-2.05b$ ./a.out
1 ./a.out 1 ./a.out bash-2.05b$ 1 ./a.out

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

★★★★★

Вы передаете в программу один параметер (именно T) и проверяете, а "Hello!" печаетается если argc > 1? Чего ж вы хотели? То, что в argv[0] передается имя программы -- это соглашение, не более того, ядро само никак список передаваемых аргументов не меняет. Поэтому правильно писать так: execlp(TEST, TEST, T, 0);

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

> man смотрел но возможно чего то не высмотрел.

Внимательнее читать man надо. Твоих мучений не было бы если бы ты прочитал третий абзац:

[..] The first argument, by convention, should point to the file name associated with the file being executed. The list of arguments must be terminated by a NULL pointer.

Если вдруг маны не помагают, значит надо спросить у google. Если на google ввести слово 'execlp' то на первой же странице будет ссылка на перевод мана, в котором все это написано по-русски.

asso_w
()

kirill@laptop:~ $ cat test.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

#define TEST "/home/kirill/test"
#define T "x"

int main (int argc, char **argv)
{
        pid_t pid; 

        if (argc > 1)
                puts ("Hello!\n");
        else
        if ((pid = fork()) == 0) 
                execl (TEST, TEST, T, NULL);
        else
                wait (NULL);

        return 0;
}

kirill@laptop:~ $ cc -o test test.c
kirill@laptop:~ $ ./test 
Hello!

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

И все же надо было сходить на google и почитать man.  В нем 
есть пример.  Правильно вот так:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <iostream>

#define TEST "./a"
#define T "x"

int main(int argc, char *argv[])
{
    std::cout << argc << " " << argv[0] << " " << std::endl;
    if (argc > 1)
        std::cout << "Hello!!!" << std::endl;
    else {
        pid_t pid = fork();
        if (! pid)
            execlp(TEST, TEST, T, NULL);
        else 
            if (pid > 0)
                waitpid(pid, NULL, 0);
            else
                std::cout << "Can't fork!" << std::endl;
    }
}

[asso@dstation tmp]$ g++ a.cpp -o a
[asso@dstation tmp]$ ./a
1 ./a 
2 ./a 
Hello!!!

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

A если мне надо запустить сразу две проги, как этот бдет выглядеть?!
Так:
pid_t pid = fork();
if ( pid == 0 )
{
execlp ( XINIT, XINIT, NULL );
execlp ( TEST, TEST, TEST, NULL );
}
мне кажется это не заработает ведь execlp заменяет текущий образ программы и по идее второй execlp не выполниться.

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

ну ты, блин, даешь :-) а man fork слабо набрать? fork возвращает 0 если он находится в процессе, им же и порожденным, > 0 (т.е. pid) если находится в родительском процессе и <0 (т.е. ошибку), если не смог породить процесс

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

Второй execlp выполнится только в том случае, когда по какой-либо ошибке не выполнится первый execlp. Возможно, ещё ваша ошибка кроется в том, что вы забываете использовать wait в теле родительского процесса?

P.S: Может быть вам стоит какую-нибудь книжку почитать про взаимодействие процессов в UNIX (Стивенса, например)

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

> Ну так а как быть с двумя программами?

...
if ((pid = fork()) > 0) {
/* Parent process*/
        if ((pid = fork()) > 0) { 
                /* Parent process*/
                ...
        }
        else
              /* 2nd Child process */
                execlp (...);
}
else
        /* 1st Child process */
        execlp (...);

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

Значит два последовательно не получиться, т.е. сначала один а потом через 5 секунд другой?

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

> т.е. сначала один а потом через 5 секунд другой?

Это как? Не совсем понял, что вы имели ввиду под этой фразой. И ещё - что значит последовательно не получится? Дочерний процесс, порожденный форком, выполняется параллельно с родительским. Если нужно, чтобы второй процесс выполнялся после завершения первого, то необходимо дождаться окончания выполнения первого дочернего процесса с помощью wait() в теле родительского процесса, а только после этого делать второй форк и вызывать второй процесс. Надеюсь, понятно выразился? ;)

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

> Значит два последовательно не получиться, т.е. сначала один а потом через 5 секунд другой?

Все получится если маны читать:

man fork

по-прежнему необходимо man exec

man wait

man 3 sleep

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

Я неудачно выразился, я имел ввиду паралельно, т.е. запустить XINIT,а затем спустя 5 секунд вторую программу, LDM. Т.е. XINIT продолжает работать а LDM запускается не сразу.

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

Дык эта функция останавливает текущий процесс, и вроде никак не влияет на запуск нового.

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

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <iostream>

#define TEST "./a"
#define T "x"

pid_t runX()
{
    pid_t pid = fork();
    if (! pid)
        execlp(TEST, TEST, T, NULL);
    else 
        return pid;
}


int main(int argc, char *argv[])
{
    std::cout << getpid() << " started" << std::endl;
    if (argc > 1)
        std::cout << getpid() << " Hello!!!" << std::endl;
    else {
        pid_t pid1 = runX();
        if (pid1 < 0) {
            std::cout << getpid() << " Can't fork 1!" << std::endl;
            return 0;
        }
        
        std::cout << getpid() << " Waiting 5 seconds..." << std::endl;
        sleep(5);
            
        pid_t pid2 = runX();
        
        waitpid(pid1, NULL, 0);
        
        if (pid2 < 0) {
            std::cout << getpid() << " Can't fork 2!" << std::endl;
            return 0;
        }
        
        waitpid(pid2, NULL, 0);
    }

    return 0;
}

[asso@dstation tmp]$ g++ a.cpp -o a
[asso@dstation tmp]$ ./a 
598 started
598 Waiting 5 seconds...
599 started
599 Hello!!!
600 started
600 Hello!!!

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

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

Если бы её не читал то врят ли я бы вообще им занялся. Просто на даче и постоянно отвлекают и никак не могу нормально заняться, только сяду/лягу ... вообщем спасибо, но пожалуй займусь ночью :) может тогда получиться. Ещё раз спасибо :)

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