Состояния ошибки поблочного тестирования - EINTR

Особенности нарезки Python довольно обширны.
синтаксис выглядит так: SOME_STRING[start:stop:step].
Таким образом, в основном вы можете использовать его в значительной степени, как вам нравится.

Я хотел бы прокомментировать это в вашем комментарии, но, к сожалению, мне не хватает rep:)

7
задан Michael Smith 6 October 2008 в 22:47
поделиться

7 ответов

В данном случае не безопасно назвать fclose () снова, поскольку в стандарте C говорится, что поток разъединен из файла (и становится неопределенным), даже если вызов перестал работать.

4
ответ дан 6 December 2019 в 12:56
поделиться

Я не думаю, что существует простой способ на самом деле протестировать это по желанию.

EINTR будет сгенерирован, если fclose операция будет прервана сигналом. Это подразумевает, что fclose был в фоновом потоке, который получил сигнал, поскольку он обрабатывал близкий запрос.

Удача, пытающаяся воспроизвести то стечение обстоятельств.

2
ответ дан 6 December 2019 в 12:56
поделиться

Используйте структуру указателей функции к краткому обзору системные функции. Замените вызов к flcose (fp) с чем-то как sys-> fclose (fp). В Вашем модульном тесте создайте реализацию fclose, который всегда возвращается, EINTR затем устанавливают sys-> fclose к той версии.

3
ответ дан 6 December 2019 в 12:56
поделиться

Смотря на исходный код ядра Linux, я не могу найти любые драйверы, которые даже возвращают EINTR на файл близко.

Если Вы, absosmurfly должен был воспроизвести этот случай, Вы могли бы записать свой собственный драйвер в Linux для возврата-EINTR на .release методе. Смотрите на пример кода из книги Драйверов устройств Linux O'Reilly. Проект весла является одним из самых простых. Вы изменили бы его, чтобы быть похожими на это:

int scull_release(struct inode *inode, struct file *filp)
{
    return -EINTR;
}

Снова, хотя, держа через исходное дерево Linux, я не могу найти драйвер, который возвратил бы EINTR на завершении.

РЕДАКТИРОВАНИЕ - хорошо это похоже на предохранитель - файловая система пространства пользователя смогла. Это используется для вещей как sshfs. Все еще пограничный случай все же.

3
ответ дан 6 December 2019 в 12:56
поделиться

Как Крис предполагает, временно замените вызовы к "реальному" fclose() с Вашей собственной реализацией, определенной в Вашем коде модульного теста. Ваша реализация могла сделать что-то столь же простое как:

int my_fclose(FILE *fp)
{
  errno = EINTR;
  return EOF;
}

Но, как вызов в суд указывает, Вы не должны звонить fclose() снова, поскольку поведение не определено, таким образом, Вы не должны потрудиться даже проверять на условие.

Другой вопрос спросить состоит в том, необходимо ли действительно волноваться об этом; если Ваш код приложения должен был заблокировать все возможные сигналы (кроме SIGKILL и SIGSTOP) во время Вашего fclose() затем Вы не получили бы EINTR и не должны будете волноваться вообще.

1
ответ дан 6 December 2019 в 12:56
поделиться

Вот то, как я протестировал бы его, только ради тестирования, так как вызов в суд напомнил нам вызов fclose() дважды небезопасно.

Возможно переопределить fclose() (или любая другая функция libc) в Вашей программе с Вашим собственным поведением. В подобных Unix системах компоновщик не жалуется - никогда не примерял Windows, но с cygwin. Конечно, это предотвращает Ваши другие тесты для использования реального fclose(), поэтому такой тест должен быть помещен в отдельный тестовый исполняемый файл.

Вот единый пример с minunit.

#include <errno.h>
#include <stdio.h>
#include <stdbool.h>

/* from minunit.h : http://www.jera.com/techinfo/jtns/jtn002.html */
 #define mu_assert(message, test) do { if (!(test)) return message; } while (0)
 #define mu_run_test(test) do { char *message = test(); tests_run++; \
                                if (message) return message; } while (0)

int tests_run = 0;
bool fclose_shall_fail_on_EINTR = false;

//--- our implemention of fclose()
int fclose(FILE *fp) {
    if (fclose_shall_fail_on_EINTR) {
        errno = EINTR;
        fclose_shall_fail_on_EINTR = false;   //--- reset for next call 
        return EOF;
    } else { return 0; }
}

//--- this is the "production" function to be tested 
void uninterruptible_close(FILE *fp) {
    // Given an open FILE *fp
     while (fclose(fp)==EOF && errno==EINTR) {
        errno = 0;
     }
}

char *test_non_interrupted_fclose(void) {
    FILE *theHandle = NULL;   //--- don't care here
    uninterruptible_close(theHandle);
    mu_assert("test fclose wo/ interruption", 0 == errno);
    return 0;
}

char *test_interrupted_fclose(void) {
    FILE *theHandle = NULL;   //--- don't care here
    fclose_shall_fail_on_EINTR = true;

    uninterruptible_close(theHandle);
    mu_assert("test fclose wo/ interruption", 0 == errno);
    return 0;
}

char *test_suite(void)
{
    mu_run_test(test_non_interrupted_fclose);
    mu_run_test(test_interrupted_fclose);
    return 0;
}

int main(int ac, char **av)
{
  char *result = test_suite();

  printf("number of tests run: %d\n", tests_run);
  if (result) { printf("FAIL: %s\n", result); } 

  return 0 != result;
}
1
ответ дан 6 December 2019 в 12:56
поделиться

Хм, я думаю, все вы игнорируют кое-что очень важное.

fclose () не может вернуть EINTR. Не могут ни fopen (), fwrite (), fread (), ни какие-либо стандартные функции CI / O.

Это только тогда, когда вы балуетесь низкоуровневыми вызовами ввода-вывода, такими как open (2), write ( 2) и выберите (2), который вам нужен для обработки EINTR.

Прочтите [смешные] страницы руководства

1
ответ дан 6 December 2019 в 12:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: