【问题标题】:BAD FILE DESCRIPTOR after successful open成功打开后的错误文件描述符
【发布时间】:2017-04-23 12:46:03
【问题描述】:

这似乎是一个非常简单的问题,但我真的不知道这里出了什么问题。我编写了一个日志记录函数和一个主函数,它启动一个重复调用该函数的线程。 open 调用成功,并且文件描述符在调用 write 之前没有损坏。仍然没有写入任何字节,并且 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;
}

【问题讨论】:

  • 作为记录,您使用stdarg.h 作为您的参数列表。文件描述符是使用来自fcntl.hopen 函数创建的。然后write 来自unistd.h。打开后你的文件描述符是什么值?通话之间会发生变化吗?当您说它“损坏”时,您的意思是它变得无效还是实际上改变了价值?

标签: c linux


【解决方案1】:

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

int flags = O_CREAT | O_TRUNC | O_APPEND | O_WRONLY;

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

【讨论】:

  • 哦,哇,是的,这是缺少的标志:(循环曾经是正确的,那里还有一个用于 buf 的 malloc,我不得不在发布之前更改一些名称和格式化,然后就溜进去了跨度>
【解决方案2】:

我发现了几个问题。

首先,您从未分配过buf。您计算了它的大小,甚至释放了它,但是当您实际写入它时,它仍然未初始化。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 2011-09-08
    • 2015-03-01
    • 1970-01-01
    相关资源
    最近更新 更多