c 同步写入 stdout 和 stderr

c synchronise write to stdout and stderr

我正在执行 ls 程序。除了错误消息和正常输出的同步之外,一切都正常工作。 我将信息存储在大缓冲区 (200kb) 中。 如您所见,子文件夹 2 无权打开。 我的程序递归工作并打开文件夹测试,然后读取所有内容,然后将其写入标准输出。然后它打开文件夹,显示所有内容。与子文件夹 1 相同。当它遇到子文件夹 2 时,它得到 errno 并在 stderr 中写入解释。它在调试器中工作,但在现实中不起作用,因为它将输出放在它想要的地方,而不是最后。 当使用 stdout 时,它可以完美地工作,就像底部的示例一样。

/Users/qhetting/ft_ls/tests
total 0
drwxr-xr-x  3 qhetting 2018 102 Mar 30 14:08 .
drwxr-xr-x 19 qhetting 2018 646 Mar 30 15:04 ..
drwxr-xr-x  4 qhetting 2018 136 Mar 30 14:10 folder

/Users/qhetting/ft_ls/tests/folder
total 0
drwxr-xr-x 4 qhetting 2018 136 Mar 30 14:10 .
drwxr-xr-x 3 qhetting 2018 102 Mar 30 14:08 ..
drwxrwxrwx 2 qhetting 2018  68 Mar 30 14:09 subfolder1
d--------- 2 qhetting 2018  68 Mar 30 14:10 subfolder2

/Users/qhetting/ft_ls/tests/folder/subfolder1
total 0
drwxrwxrwx 2 qhetting 2018  68 Mar 30 14:09 .
drwxr-xr-x 4 qhetting 2018 136 Mar 30 14:10 ..

ft_ls: subfolder2: Permission denied

代码:

 if (!(dir = opendir(fld_name)))
            {
                if (errno)
                    print_error(fld_name, errno, NULL); //gets file name, concatenates it with error message and prints it with write like
write(2, error, strlen(error));
                return;
            }
            errno = 0;
            while ((dirp = readdir(dir)))
            {
                if (!(g_flag & A && dirp->d_name[0] != '.') || g_flag & A)
                {
                    attrib = ft_relink(attrib, dirp->d_name,
                                       get_full_path(fld_name, dirp->d_name));
                    if (first_asign)
                    {
                        holder = attrib;
                        first_asign = false;
                    }
                }
                if (errno)
                {
                    print_error(fld_name, errno, attrib);
                    errno = 0;
                    continue;
                }
            }
            attrib = holder;
            ft_merge_sort(&attrib, comparator_lex);
            print_level(attrib, g_flag); //here all read content is printed in stdout with big buffer.
            if (g_flag & R_BIG)
            {
                while (attrib)
                {
                    if (IS_OK && is_dir(attrib->full_path) && !attrib->error_message)
                        ft_open_folder(attrib->full_path);
                    attrib = attrib->next;
                }
            }
            closedir(dir);

您可以使用 fflush(stdout)fflush(stderr) 刷新输出缓冲区。这样做会立即打印缓冲区中剩余的内容。

Synopsis

int fflush(FILE *stream);

Description

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

https://port70.net/~nsz/c/c11/n1570.html#7.21.5.2