Ошибка чтения файла при ошибке с номером ошибки EBADF - PullRequest
0 голосов
/ 30 июня 2018

Я пытался написать тестовую программу для проверки правильности работы блокировки файлов. Но один из тестов провалился. Я пытаюсь получить блокировку чтения файла, но проверка не удалась. Когда я попытался напечатать номер ошибки, он напечатал 9, что указывало EBADF, то есть неверный номер файла (или дескриптор файла). Я также попытался напечатать значение дескриптора файла, оно напечатало 3, который кажется допустимым дескриптором файла. Я использую Netbeans IDE и ее функциональность Simple Test.

Файл для чтения находится в той же папке, что и файл исходного кода.

Вот мой код:

#include <stdlib.h>
#include <iostream>
#include <sys/file.h>
#include <sys/unistd.h>
using namespace std;
/*
 * Simple C++ Test Suite
 */
int acquireRLock(int fd, struct flock &lock) {
    lock.l_len = 0;
    lock.l_start = 0;
    lock.l_whence = SEEK_SET;
    lock.l_type = F_RDLCK;
    struct flock temp_lock = lock;
    fcntl(fd, F_GETLK, &temp_lock);
    if(temp_lock.l_type == F_WRLCK) {
        return -1;
    }
    else {
        int ret_val = fcntl(fd, F_SETLK, &lock);
        if(ret_val == -1) cout << "Failed here errno = " << errno << " fd = " << fd << endl;
        return ret_val;
    }
}
int acquireWLock(int fd, struct flock &lock) {
    lock.l_len = 0;
    lock.l_start = 0;
    lock.l_whence = SEEK_SET;
    lock.l_type = F_WRLCK;
    struct flock temp_lock = lock;
    fcntl(fd, F_GETLK, &temp_lock);
    if(temp_lock.l_type == F_RDLCK || temp_lock.l_type == F_WRLCK)
        return -1;
    else
        return fcntl(fd, F_SETLK, &lock);
}
int FileOpenTest() {
    int fd = open("test_file.txt", O_WRONLY);
    if(fd == -1) {
        cout << "%TEST_FAILED% time=0 testname=FileOPenTest (newsimpletest) message=file open failed" << endl;
    }
    return fd;
}
void FileReadLockTest(int fd) {
    struct flock lock;
    if(acquireRLock(fd, lock) < 0) {
        cout << "%TEST_FAILED% time=0 testname=FileReadLockTest (newsimpletest) message=file read lock acquire failed" << endl;
    }
}
void FileWriteLockTest(int fd) {
    struct flock lock;
    if(acquireWLock(fd, lock) < 0) {
        cout << "%TEST_FAILED% time=0 testname=FileWriteLockTest (newsimpletest) message=file write lock acquire failed" << endl;
    }
}
void FileWriteTest(int fd) {
    if(write(fd, (void*) "I am a ball", 13) <= 0) {
        cout << "%TEST_FAILED% time=0 testname=FileWriteTest (newsimpletest) message=file write failed" << endl;
    }
}
void FileCloseTest(int fd) {
    if(close(fd) < 0) {
        cout << "%TEST_FAILED% time=0 testname=FileCloseTest (newsimpletest) message=file close failed" << endl;
    }
}
int main(int argc, char** argv) {
    std::cout << "%SUITE_STARTING% newsimpletest" << std::endl;
    std::cout << "%SUITE_STARTED%" << std::endl;

    std::cout << "%TEST_STARTED% FileOpenTest (newsimpletest)" << std::endl;
    int fd = FileOpenTest();
    std::cout << "%TEST_FINISHED% time=0 FileOpenTest (newsimpletest)" << std::endl;

    std::cout << "%TEST_STARTED% FileReadLockTest (newsimpletest)\n" << std::endl;
    FileReadLockTest(fd);
    std::cout << "%TEST_FINISHED% time=0 FileReadLockTest (newsimpletest)" << std::endl;

//    std::cout << "%TEST_STARTED% FileWriteLockTest (newsimpletest)\n" << std::endl;
//    FileWriteLockTest(fd);
//    std::cout << "%TEST_FINISHED% time=0 FileWriteLockTest (newsimpletest)" << std::endl;
//    
//    std::cout << "%TEST_STARTED% FileWriteTest (newsimpletest)\n" << std::endl;
//    FileWriteTest(fd);
//    std::cout << "%TEST_FINISHED% time=0 FileWriteTest (newsimpletest)" << std::endl;

    std::cout << "%TEST_STARTED% FileCloseTest (newsimpletest)\n" << std::endl;
    FileCloseTest(fd);
    std::cout << "%TEST_FINISHED% time=0 FileCloseTest (newsimpletest)" << std::endl;

    std::cout << "%SUITE_FINISHED% time=0" << std::endl;

    return (EXIT_SUCCESS);
}

Показывает следующий вывод:

Output

При отмене комментариев кода для получения блокировки записи блокируется запись, и файл записывается, и блокировка чтения по-прежнему не выполняется, как показано в выходных данных ниже. Но фактическое поведение должно быть успешным для блокировки чтения и неудачным для блокировки записи:

enter image description here

Пожалуйста, помогите мне выяснить, почему тест не пройден.

1 Ответ

0 голосов
/ 30 июня 2018

На справочной странице для fcntl мы можем прочитать

Чтобы установить блокировку чтения, fd должен быть открыт для чтения. С целью чтобы установить блокировку записи, fd должен быть открыт для записи. Разместить оба типы блокировки, открыть файл для чтения-записи.

Вы открываете файл с

int fd = open("test_file.txt", O_WRONLY);

Из справочной страницы для открытия

O_RDONLY Открыть только для чтения.

O_WRONLY Открыто только для записи.

O_RDWR Открыто для чтения и письма. Результат не определен, если этот флаг применяется к FIFO.

Чтобы установить блокировки чтения и записи, откройте файл с помощью

int fd = open("test_file.txt", O_RDWR);
...