2017-04-23 112 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