成功打开后{B44 FILE DESCRIPTOR}

时间:2017-04-23 12:46:03

标签: c linux

这似乎是一个非常简单的问题,但我真的无法弄清楚这里出了什么问题。我编写了一个日志记录函数和一个主函数来启动一个重复调用该函数的线程。在调用write之前,调用open成功并且文件描述符不会被破坏。仍然没有写入字节,并且errno设置为BAD FILE DESCRIPTOR。 (我已经省略了大多数错误检查的可读性)

记录功能:

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;
}

2 个答案:

答案 0 :(得分:1)

您需要将O_WRONLY添加到open标志,否则您将无法在此文件描述符上进行写入。

int flags = O_CREAT | O_TRUNC | O_APPEND | O_WRONLY;

您还需要修复此代码,例如初始化i(您目前正在执行int i = i)和buf

答案 1 :(得分:0)

我看到了一些问题。

首先,您从未分配过buf。你为它计算了一个大小,甚至把它释放了,但是当你真正写它时,它仍然没有初始化。

其次,当您需要重复使用va_list时,您应该使用va_copy制作副本。第一个va_end后的状态不能保证适合第二个va_start