Отправляет email-рассылки с помощью сервиса Sendsay

Программирование и др.

  Все выпуски  

Программирование в Linux с нуля [17.05.2008]


Программирование в Linux с нуля [17.05.2008]

Здравствуйте! Это очередной выпуск рассылки "Программирование в Linux с нуля".

--- новости Lindevel.Ru ---

Книга "Программирование в Linux с нуля" версия 0.094

Tarball: ftp://ftp.lindevel.ru/zlp/zlp-0.094.tar.gz
Online: http://www.lindevel.ru/zlp


Новые материалы книги

6.4. Замена образа процесса

Итак, теперь мы умеем порождать процессы. Научимся теперь заменять образ текущего процесса другой программой. Для этих целей используется системный вызов execve(), который объявлен в заголовочном файле unistd.h вот так:


int execve (const char * path, char const * argv[], char * const envp[]);

Все очень просто: системный вызов execve() заменяет текущий образ процесса программой из файла с именем path, набором аргументов argv и окружением envp. Здесь следует только учитывать, что path - это не просто имя программы, а путь к ней. Иными словами, чтобы запустить ls, нужно в первом аргументе указать "/bin/ls".

Массивы строк argv и envp обязательно должны заканчиваться элементом NULL. Кроме того, следует помнить, что первый элемент массива argv (argv[0]) - это имя программы или что-либо иное. Непосредственные аргументы программы отсчитываются от элемента с номером 1.

В случае успешного завершения execve() ничего не возвращает, поскольку новая программа получает полное и безвозвратное управление текущим процессом. Если произошла ошибка, то по традиции возвращается -1.

Рассмотрим теперь пример программы, которая заменяет свой образ другой программой.


/* execve01.c */
#include <unistd.h>
#include <stdio.h>

int main (void)
{
        printf ("pid=%d\n", getpid ());
        execve ("/bin/cat", NULL, NULL);

        return 0;
}

Итак, данная программа выводит свой PID и передает безвозвратное управление программе cat без аргументов и без окружения. Проверяем:


$ gcc -o execve01 execve01.c
$ ./execve01
pid=30150

Программа вывела идентификатор процесса и замерла в смиренном ожидании. Откроем теперь другое терминальное окно и проверим, что же творится с нашим процессом:


$ ps -e | grep 30150
30150 pts/3    00:00:00 cat

Итак, мы убедились, что теперь процесс 30150 выполняет программа cat. Теперь можно вернуться в исходное окно и нажатием Ctrl+D завершить работу cat.

И, наконец, следующий пример демонстрирует запуск программы в отдельном процессе.


/* forkexec01.c */
#include <unistd.h>
#include <stdio.h>

extern char ** environ;

int main (void)
{
        char * echo_args[] = { "echo", "child", NULL };

        if (!fork ()) {
                execve ("/bin/echo", echo_args, environ);
                fprintf (stderr, "an error occured\n");
                return 1;
        }

        printf ("parent");
        return 0;
}

Проверяем:


$ gcc -o forkexec01 forkexec01.c
$ ./forkexec01
parent
child

Обратите внимание, что поскольку execve() не может возвращать ничего кроме -1, то для обработки возможной ошибки вовсе не обязательно создавать ветвление. Иными словами, если вызов execve() возвратил что-то, то это однозначно ошибка.

Контакты

Сайт проекта Lindevel.Ru (http://www.lindevel.ru) посвящен программированию в Linux. Здесь вы всегда сможете найти последнюю версию книги, а также оставить вопросы и пожелания в форуме (http://forum.lindevel.ru).


Рассылки Subscribe.Ru
FreeBSD

В избранное