Files
graphene/LibOS/shim/test/regression/dev.c
Dmitrii Kuvaiskii 3e9e0755ab [LibOS] Refactor implementation of /proc and /dev pseudo-FSs
Previously, /proc and /dev pseudo-filesystems were implemented in
completely different ways. This commit introduces a set of generic
functions for all pseudo-FSs (based on previous implementation of
/proc) and refactors both /proc and /dev to use these functions.

This commit also expands a LibOS test `proc` to cover more cases
and pseudo-files, as well as introduces a new LibOS test `dev`.
Several bugs in pseudo-FSs were detected and fixed in the process.
2020-04-01 19:47:50 -07:00

127 lines
2.8 KiB
C

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char** argv) {
int ret;
FILE* f;
DIR* dir;
struct dirent* dirent;
char buf[64];
/* sanity checks that incorrect invocations return errors */
f = fopen("/dummy-pseudo-fs", "r");
if (f != NULL || errno != ENOENT) {
perror("(sanity check) fopen of dummy non-existing pseudo-FS did not fail with ENOENT");
return 1;
}
f = fopen("/dev", "r+");
if (f != NULL || errno != EISDIR) {
perror("(sanity check) fopen of /dev did not fail with EISDIR");
return 1;
}
f = fopen("/dev/dummy", "r");
if (f != NULL || errno != ENOENT) {
perror("(sanity check) fopen of /dev/dummy (non-existing file) did not fail with ENOENT");
return 1;
}
printf("===== Contents of /dev\n");
dir = opendir("/dev");
if (!dir) {
perror("opendir /dev");
return 1;
}
errno = 0;
while ((dirent = readdir(dir))) {
printf("/dev/%s\n", dirent->d_name);
}
if (errno) {
perror("readdir /dev");
return 1;
}
ret = closedir(dir);
if (ret < 0) {
perror("closedir /dev");
return 1;
}
printf("===== Read from /dev/urandom\n");
f = fopen("/dev/urandom", "r");
if (!f) {
perror("fopen /dev/urandom");
return 1;
}
memset(buf, 0, sizeof(buf));
ret = fread(buf, 1, sizeof(buf), f);
if (ferror(f)) {
perror("fread /dev/urandom");
return 1;
}
printf("Four bytes from /dev/urandom: %x:%x:%x:%x\n", buf[0], buf[1], buf[2], buf[3]);
ret = fclose(f);
if (ret) {
perror("fclose /dev/urandom");
return 1;
}
printf("===== Write to /dev/null\n");
f = fopen("/dev/null", "w");
if (!f) {
perror("fopen /dev/null");
return 1;
}
ret = fwrite(buf, 1, sizeof(buf), f);
if (ret < sizeof(buf)) {
perror("fwrite /dev/null");
return 1;
}
ret = fclose(f);
if (ret) {
perror("fclose /dev/null");
return 1;
}
#if 0
/* `/dev/stdout` is a link to `/proc/self/fd/1`; Graphene currently fails, see #1387 */
printf("===== Write to /dev/stdout\n");
f = fopen("/dev/stdout", "w");
if (!f) {
perror("fopen /dev/stdout");
return 1;
}
sprintf(buf, "%s\n", "Hello World written to stdout!");
size_t towrite = strlen(buf) + 1;
ret = fwrite(buf, 1, towrite, f);
if (ret < towrite) {
perror("fwrite /dev/stdout");
return 1;
}
ret = fclose(f);
if (ret) {
perror("fclose /dev/stdout");
return 1;
}
#endif
return 0;
}