2010-04-07 40 views
2

我目前正在爲一些項目編寫一個多進程客戶端和一個多線程服務器。Debian上的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)

任何想法是什麼造成這種情況?

謝謝

+0

在您的應用程序中運行strace -f,幷包含從啓動到第一個accept()失敗的所有內容,希望這些內容會包含一些線索。 – nos 2010-04-07 13:34:15

+0

爲了更好地確定accept(2)返回-1的原因,打印/記錄errno的值可能會有幫助。 – jschmier 2010-04-08 06:08:12

回答

3

的接受(2)用戶手冊說:

EINVAL套接字未監聽 連接,或addrlen中是無效 (例如,是負的)。

可能是你有類似

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

+1看實際的問題。 – 2010-04-09 03:37:16

+0

這正是發生了什麼,非常感謝你。 我之前調試LEN接受有和沒有守護進程調用 沒有它,它是積極的,它是消極的,不知道爲什麼會發生,但設置len地址的大小解決了它! – djTeller 2010-04-10 13:32:56

1

這裏,當父退出:

/* 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");)。

+0

改爲_exit() 加入PERROR( 「接受」), 我越來越 - >接受:無效的參數 – djTeller 2010-04-07 12:53:38

+0

我也調試的接受功能: new_fd =接受(的sockfd,(結構sockaddr *)&地址,&len); new_fd返回-1,和的sockfd始終是4 – djTeller 2010-04-07 13:06:57

3

我可以直接給你現有的庫函數daemon(3)來完成相同的功能嗎?

+1

+2,如果我能.. – 2010-04-07 13:34:11