2012-03-24 82 views
4

爲一門課程製作一個簡單的cgi服務器。要做到這一點,我必須做一個fork/exec來啓動cgi處理程序,問題是exec繼續返回errno 14.我已經在獨立版本中嘗試了下面的代碼,它可以使用和不使用絕對路徑。調用exec爲絕對路徑返回errno 14(壞地址)

下面的代碼:

static void _process_cgi(int fd, http_context_t* ctx) 
{ 
    pid_t childProcess; 
    int ret; 
    char returnValue[1024]; 
    log(LOG, "calling cgi", &ctx->uri[1], 0); 

    if((childProcess = fork()) != 0) 
    { 
     /// 
     /// Set the CGI standard output to the socket. 
     /// 
     dup2(fd, STANDARD_OUTPUT); 
      //ctx->uri = "/simple.cgi" 

     execl("/home/dvd/nwebdir/simple.cgi",&ctx->uri[1]); 
     sprintf(returnValue,"%d",errno); 

     log(LOG, "exec returned ", returnValue, 0); 
     return -1; 
    } 

    ret = waitpid(childProcess,NULL,0); 
    sprintf(returnValue,"%d",ret); 
    log(LOG, "cgi returned", returnValue, 0); 
} 

這裏是SYS列表調用服務器達到了我的代碼(按順序)之前經過: - CHDIR - 叉 - setpqrp - 叉 我不不知道這是否相關,但在我的測試程序中,我沒有chdir和setpqrp。

測試代碼如下:

pid_t pid; 

    if ((pid = fork()) != 0) 
    { 
     execl("simple.cgi","simple"); 
     //execl("/home/dvd/nwebdir/simple.cgi","simple"); 
     return 0; 
    } 
    printf("waiting\n"); 
    waitpid(pid, NULL, 0); 
    printf("Parent exiting\n"); 

注意我已經試過在服務器代碼都EXECL和execlp。

您可以找到基本的服務器實現(無CGI)在這裏,只有我所做的更改是在網絡funcion: http://www.ibm.com/developerworks/systems/library/es-nweb/index.html

問候

回答

13
execl("simple.cgi","simple", NULL); 

需要空,因爲EXECL( )是可變參數函數。

+0

這樣做的伎倆,但它爲什麼在測試版本,而不是在服務器版本? – DVD 2012-03-24 19:53:17

+1

調用未定義的行爲導致未定義(讀取不穩定)行爲,包括有時看起來工作。 – 2012-03-24 19:54:38

+0

C XD的奇蹟感謝喬納森 – DVD 2012-03-24 19:58:28

4
execl("/home/dvd/nwebdir/simple.cgi", &ctx->uri[1], (char *)0); 

的最後一個參數execl()必須是空char *。您通常可以通過編寫NULL而不是(char *)0,但如果您有#define NULL 0並且您位於sizeof(int) != sizeof(char *)(例如64位系統)的計算機上,可能無法產生正確的結果。

+2

如果你#define NULL 0,你應該得到糟糕的行爲 – tomsmeding 2015-08-19 09:01:02

2

順便說一句,要麼你錯誤地複製了代碼,或者它有邏輯錯誤。 Fork()向父進程返回非零值,而不是子進程,所以條件將被恢復。 (在這裏沒有評論按鈕,所以作出回答。)