2017-04-23 126 views
1

這看起來像是一個非常簡單的問題,但我真的無法弄清楚這裏出了什麼問題。我寫了一個日誌函數和一個主函數來啓動一個重複調用該函數的線程。在寫入調用之前打開調用成功並且文件描述符不會損壞。仍然沒有字節被寫入,並且errno被設置爲不良文件描述符。 (我省略了大部分的錯誤檢查readbility)成功打開後的不良文件描述符

記錄功能:

static pthread_once_t once = PTHREAD_ONCE_INIT; 
static int logfd; 

static void _log_init(void) 
{ 
    int flags = O_CREAT | O_TRUNC | O_APPEND; 
    int perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 

    logfd = open("log.txt", flags, perms); 
} 

void log_data(const char *fmt, ...) 
{ 
    int bufsize; 
    char *buf; 

    pthread_once(&once, _log_init); 

    va_list va; 

    va_start(va, fmt); 
    bufsize = vsnprintf(NULL, 0, fmt, va) + 1; 
    va_end(va); 

    va_start(va, fmt); 
    vsnprintf(buf, bufsize, fmt, va); 
    va_end(va); 

    if (write(logfd, buf, bufsize) == -1) 
     perror("write"); 

    free(buf); 
} 

主要功能:

static void *thread_log(void *arg) 
{ 
    int thread = *((int *)arg); 
    free(arg); 

    for (int i = i; i < 10; ++i) 
     log_data("thread %d\n", thread); 

    return (void *) NULL; 
} 

int main() 
{ 
    pthread_t t; 
    int *arg; 

    arg = malloc(sizeof(int)); 
    *arg = 1; 
    pthread_create(&t, NULL, thread_log, (void *) arg); 

    pthread_join(t, NULL); 

    return 0; 
} 
+0

爲了記錄,您使用'stdarg.h'作爲您的參數列表。文件描述符是使用'fcntl.h'中的'open'函數創建的。然後''從'unistd.h'寫入。 打開後文件描述符的值是多少?它在呼叫之間改變嗎?當你說它是「損壞的」時,你的意思是它變成無效的,還是它實際上改變了價值? – starturtle

回答

1

您需要將O_WRONLY添加到open標誌,否則您將無權寫入此文件描述符。

int flags = O_CREAT | O_TRUNC | O_APPEND | O_WRONLY;

也有幾個你需要修復這些代碼的,比如初始i(你正在做int i = i)和buf事情。

+0

哦,哇,是的,這是失蹤的旗幟:( 循環曾經是正確的,也有一個malloc buf那裏, 我不得不改變一些名稱和形成之前發佈和 滑入 – Peter

0

我看到一對夫婦的問題。

首先,你從來沒有分配過buf。你爲它計算了一個大小,甚至釋放了它,但是當你真正寫入它時,它仍然是未初始化的。

其次,當您需要重新使用va_list時,您應該複製va_copy。第一個va_end之後的狀態不能保證適合第二個va_start