occlum/test/readdir/main.c
LI Qing b610e5b8b8 Fix getdents when the next dir entry cannot fit into the output buffer
The output buffer given to getdents may not be large enough for the next directory
entry. If no directory entries has been loaded into the buffer, just return
EINVAL. Otherwise, return the total length of the directory entries already
loaded in the buffer
2020-01-23 04:40:54 +00:00

90 lines
2.2 KiB
C

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "test.h"
// ============================================================================
// The test case of readdir
// ============================================================================
static int test_readdir() {
struct dirent *dp;
DIR* dirp;
dirp = opendir("/");
if (dirp == NULL) {
THROW_ERROR("failed to open directory");
}
while (1) {
errno = 0;
dp = readdir(dirp);
if (dp == NULL) {
if (errno != 0) {
closedir(dirp);
THROW_ERROR("faild to call readdir");
}
break;
}
}
closedir(dirp);
return 0;
}
static int test_getdents_with_big_enough_buffer() {
int fd, len;
char buf[64];
fd = open("/", O_RDONLY | O_DIRECTORY);
if (fd < 0) {
THROW_ERROR("failed to open directory");
}
while (1) {
len = getdents(fd, (struct dirent *)buf, sizeof(buf));
if (len < 0) {
close(fd);
THROW_ERROR("failed to call getdents");
} else if (len == 0) {
// On end of directory, 0 is returned
break;
}
}
close(fd);
return 0;
}
static int test_getdents_with_too_small_buffer() {
int fd, len;
char buf[4];
fd = open("/", O_RDONLY | O_DIRECTORY);
if (fd < 0) {
THROW_ERROR("failed to open directory");
}
len = getdents(fd, (struct dirent *)buf, sizeof(buf));
if (len >= 0 || errno != EINVAL) {
close(fd);
THROW_ERROR("failed to call getdents with small buffer");
}
close(fd);
return 0;
}
// ============================================================================
// Test suite main
// ============================================================================
static test_case_t test_cases[] = {
TEST_CASE(test_readdir),
TEST_CASE(test_getdents_with_big_enough_buffer),
TEST_CASE(test_getdents_with_too_small_buffer),
};
int main() {
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
}