Запустите процесс в фоновом режиме в Linux с C

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

int main ( int argc, char** argv, char** env )
{
    int fd;
    if ((fd = open("/dev/console", O_RDWR)) < 0) {
        fd = open("/dev/null", O_RDWR);
    }
    printf("THIS IS A TEST\n");
    dup2(1, fd);
    dup2(2, fd);

    pid_t childpid = fork();

    if(childpid == -1) {
        perror("Failed to fork, logcat not starting");
        return 1;
    }

    if(childpid == 0) {
        //this is the child, exec logcat
        setsid();
        int execReturn = execl("/system/bin/logcat", "logcat", (char *) 0);
    } else {
        //this is the parent do nothing
        close(fd);
        return 0;
    }
    close(fd);
     return 0;
}

Спасибо

8
задан Mike 4 August 2010 в 15:38
поделиться

2 ответа

Команда 'logcat' , похоже, предназначена для разработки под Android - это может объяснить странное расположение команды.

Ключевая операция, которую вы должны исправить, - это убедиться, что вы закрыли текущий стандартный ввод (терминал) и открыли / dev / null / для устройства ввода:

close(0);
if ((fd = open("/dev/null", O_RDONLY)) != 0)
    ...error - failed to open /dev/null!

Это означает, что ваша демонизированная дочерний процесс не будет ничего читать с терминала.


Я думаю, вы хотите сделать следующее:

  1. Запустите программу запуска из командной строки, которая будет иметь стандартный ввод, стандартный вывод и стандартную ошибку, связанную с «терминалом».
  2. Внутри вашей программы вы хотите заменить стандартный ввод, чтобы он поступал из / dev / null .
  3. Вы хотите оставить стандартный вывод в покое - вы хотите, чтобы logcat записывал в текущий стандартный вывод.
  4. Вы, вероятно, тоже захотите оставить в покое стандартную ошибку.

В какой-то момент процедуры вы правильно выполняете демонизацию (заимствуя ссылку из ответа @bstpierre), убедившись, что терминал, к которому вы подключены, не является вашим управляющим терминалом, чтобы прерывания и сообщения, отправленные на терминал, не влияют на работу вашего демона. Сантехника проще, чем то, что вы настроили - вы должны иметь дело со стандартным вводом и оставить стандартный вывод и стандартную ошибку без изменений (вместо того, чтобы изменять выводы и оставлять ввод без изменений).

Теперь вы можете захотеть, чтобы вывод шел на / dev / console ; если это так, то разумно изменить код, чтобы открыть / dev / console .Однако нецелесообразно возвращаться к / dev / null , если вы не можете открыть / dev / console ; ваша программа должна сообщить об ошибке и выйти из строя (потому что нет смысла в том, чтобы logcat записывал в / dev / null !). Убедитесь, что вы открыли консоль с флагом O_NOCTTY , чтобы она не стала управляющим терминалом для демона.

Последний комментарий, который я хотел бы сделать:

  • Вы уверены, что хотите, чтобы на вашем терминале или консоли отображался случайный текст, когда он используется для других целей?

Мне не очень нравится, когда это происходит .


См. Также: SO 958249

4
ответ дан 5 December 2019 в 18:55
поделиться

Как демонизировать в Linux [мертвая ссылка]

Как демонизировать в Linux [машинный архив обратного пути]

суть на github - код взят из ссылки выше

Краткое изложение:

Одна из вещей, с которой я постоянно сталкиваюсь, - это демоны Linux, которые не демонизируют себя должным образом. Чтобы правильно демонизировать, необходимо выполнить следующие шаги.

  • Вызов fork () используется для создания отдельного процесса.
  • Вызов setsid () используется для отделения процесса от родительского (обычно оболочки).
  • Необходимо сбросить маску файла.
  • Текущий каталог следует изменить на что-нибудь безопасное.
  • Необходимо повторно открыть стандартные файлы (stdin, stdout и stderr).

Невыполнение любого из этих шагов приведет к некорректному поведению процесса-демона. Типичные симптомы следующие.

  • Запуск демона и последующий выход из системы приведет к зависанию терминала. Это особенно неприятно с ssh.
  • Каталог, из которого был запущен демон, остается заблокированным.
  • В оболочке, из которой был запущен демон, появляется ложный вывод.
4
ответ дан 5 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: