2014-02-10 49 views
0

我有一個簡單的功能 - 其目的是在覆蓋之前將文件複製到.old。因爲我很懶(這裏提供了一個答案),我分叉並使用cp來完成這項工作。waitpid似乎沒有wating

然後我調用waitpid並檢查返回碼。

調用此函數的代碼調用了我的複製函數,然後立即打開文件進行讀取。不知何故調用代碼似乎在cp調用之前運行 - 新文件是被複制的。 最好的例子是如果既沒有文件也沒有備份。兩者都創建幷包含我保存的調用輸出。

我很努力地看到我出錯的地方,幫助將不勝感激。

copy_old(); 
std::ofstream savefile (SETTINGS_LOCATION); 
if (savefile.is_open()) 
{ 
    savefile << ... 


void settings::copy_old() 
{ 
    int childExitStatus; 
    pid_t pid; 

    pid = fork(); 

    if (pid == 0) { /* child */ 
     execl("/bin/cp", "/bin/cp", "-f", SETTINGS_LOCATION, SETTINGS_LOCATION_B, (char *)0); 
    } 
    else if (pid < 0) { 
     ERR("Could not Backup Previous Settings"); 
    } 
    else { 
     pid_t ws = waitpid(pid, &childExitStatus, WNOHANG); 
     if (ws == -1) 
     { 
      ERR("Could not Backup Previous Settings1"); 
     } 

     if(!WIFEXITED(childExitStatus) || WEXITSTATUS(childExitStatus)) /* exit code in childExitStatus */ 
     { 
      ERR("Settings backup may have been unsuccessful"); 
     } 
    } 
} 
+0

除了'waitpid'的接受答案之外,其他子句中的所有內容都是非常不穩定的編碼。 – Duck

+0

由於應用程序設置的性質,讀取/寫入操作很少,不太可能從默認值更改。因此,在這個極不可能的問題中,代碼不會成爲主要問題。 它可以工作,或者它不會,沒什麼大不了的,將它粘在日誌中。據我所知,上述幾乎涵蓋了所有情況?也許我應該存儲更具體的東西,但這似乎有點矯枉過正。 – Hector

+0

我得到的是(1)如果'waitpid'失敗,childExitStatus是不相關的;和(2)「如果WIFEXITED」陳述有缺陷。如果WIFEXITED評估爲真,則由於短路評估,WEXITSTATUS可能不會被測試。如果WIFEXITED評估爲false,則WEXITSTATUS將被評估,但WIFEXITED爲false時則無意義。從人類(2)等待':只有當WIFEXITED返回true時才應該使用這個宏。 – Duck

回答

2

當然waitpid沒在等待。你告訴它不要:

pid_t ws = waitpid(pid, &childExitStatus, WNOHANG); 

WNOHANG意味着 「不等待」。如果您要waitpid等待,請將WNOHANG更改爲0。

+0

犯了從另一個接受的答案盲目複製代碼的錯誤。我花了40分鐘盯着它抓我的頭。現在感覺非常愚蠢。 謝謝 – Hector

+1

經驗教訓,我希望:總是檢查手冊頁。 –