Проблемы с Daemonize () в Debian - PullRequest
2 голосов
/ 07 апреля 2010

В настоящее время я пишу многопроцессный клиент и многопоточный сервер для моего проекта.

Сервер - это демон. Для этого я использую следующий код daemonize ():

static void daemonize(void)
{
    pid_t pid, sid;

    /* already a daemon */
    if ( getppid() == 1 ) return;

    /* Fork off the parent process */
    pid = fork();
    if (pid < 0) {
        exit(EXIT_FAILURE);
    }
    /* If we got a good PID, then we can exit the parent process. */
    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

    /* At this point we are executing as the child process */

    /* Change the file mode mask */
    umask(0);

    /* Create a new SID for the child process */
    sid = setsid();
    if (sid < 0) {
        exit(EXIT_FAILURE);
    }

    /* Change the current working directory.  This prevents the current
       directory from being locked; hence not being able to remove it. */
    if ((chdir("/")) < 0) {
        exit(EXIT_FAILURE);
    }

    /* Redirect standard files to /dev/null */
    freopen( "/dev/null", "r", stdin);
    freopen( "/dev/null", "w", stdout);
    freopen( "/dev/null", "w", stderr);
}

int main( int argc, char *argv[] ) {
    daemonize();

    /* Now we are a daemon -- do the work for which we were paid */
    return 0;
}

У меня странный побочный эффект при тестировании сервера в Debian (Ubuntu).

Функция accept () всегда не может принимать соединения, pid возвращается -1

Понятия не имею, что вызвало это, поскольку в RedHat & CentOS это работает хорошо.

Когда я удаляю вызов daemonize (), все работает хорошо в Debian, когда я добавляю его обратно, появляется такая же ошибка accept ().

Я следил за / proc // fd, все выглядит хорошо.

Что-то в daemonize () и выпуске Debian, похоже, просто не работает. (Debian GNU / Linux 5.0, Linux 2.6.26-2-286 # 1 SMP)

Есть идеи, что вызвало это?

Спасибо

Ответы [ 3 ]

3 голосов
/ 07 апреля 2010

Могу ли я направить вас к существующей функции библиотеки daemon(3), чтобы выполнить то же самое?

3 голосов
/ 07 апреля 2010

На странице accept (2) написано:

EINVAL Socket не слушает соединения, или адрес недействителен (например, отрицательно).

Скорее всего, у вас есть что-то вроде

struct sockaddr_in;
socklen_t len;
...

new_fd = new_fd = accept(sockfd,(struct sockaddr *)&addr,&len);

Однако вам нужно установить len для размера адреса, который вы передаете:

struct sockaddr_in addr;
socklen_t len;
len = sizeof(addr);
...
new_fd = new_fd = accept(sockfd,(struct sockaddr *)&addr,&len);

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

1 голос
/ 07 апреля 2010

Здесь, когда родитель выходит:

/* If we got a good PID, then we can exit the parent process. */
if (pid > 0) {
    exit(EXIT_SUCCESS);
}

Вы должны звонить _exit(), а не exit(). (Я не уверен, что это вызывает вашу проблему, но это возможно).

Что означает errno, когда accept() возвращает -1? (Вы можете вставить туда код perror("accept");).

...