c синхронизировать запись в stdout и stderr - PullRequest
1 голос
/ 30 марта 2019

Я реализую программу ls.Все работает нормально, кроме синхронизации сообщений об ошибках и нормального вывода.Я храню информацию в больших буферах (200 КБ).Как видите, подпапка2 не имеет прав на открытие.Моя программа работает рекурсивно и открывает папку тестов, затем читает весь ее контент, а затем записывает его в стандартный вывод.Затем он открывает папку, отображает весь контент.То же самое с подпапкой1.Когда он встречает подпапку 2, он получает ошибку и пишет объяснение в stderr.Он работает в отладчике и не работает в реальности, потому что он размещает вывод там, где хочет, а не в конце.И он прекрасно работает, когда использует стандартный вывод, как на примере внизу.

/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);

1 Ответ

1 голос
/ 30 марта 2019

Вы можете использовать fflush(stdout) и fflush(stderr) для очистки выходных буферов. При этом сразу же будет напечатано все, что осталось в буфере.

Синопсис

int fflush(FILE *stream);

Описание

Если поток указывает на выходной поток или поток обновления, в который не была введена самая последняя операция, функция fflush заставляет любые неписанные данные для этого потока быть доставленными в хост-среду для записи в файл; в противном случае поведение не определено.

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

...