ladybird/VirtualFileSystem/test.cpp
2018-10-17 10:57:23 +02:00

232 lines
6.7 KiB
C++

#include "Ext2FileSystem.h"
#include "FileBackedDiskDevice.h"
#include "VirtualFileSystem.h"
#include "FileHandle.h"
#include "SyntheticFileSystem.h"
#include "ZeroDevice.h"
#include "NullDevice.h"
#include "FullDevice.h"
#include "RandomDevice.h"
#include <cstring>
#include <AK/SimpleMalloc.h>
#include <AK/StdLib.h>
#include <AK/kmalloc.h>
#include <AK/ktime.h>
static RetainPtr<FileSystem> makeFileSystem(const char* imagePath);
int main(int c, char** v)
{
const char* filename = "small.fs";
if (c >= 2)
filename = v[1];
VirtualFileSystem vfs;
auto zero = make<ZeroDevice>();
vfs.registerCharacterDevice(1, 5, *zero);
auto null = make<NullDevice>();
vfs.registerCharacterDevice(1, 3, *null);
auto full = make<FullDevice>();
vfs.registerCharacterDevice(1, 7, *full);
auto random = make<RandomDevice>();
vfs.registerCharacterDevice(1, 8, *random);
if (!vfs.mountRoot(makeFileSystem(filename))) {
printf("Failed to mount root :(\n");
return 1;
}
#if 0
auto newFile = vfs.create("/empty");
printf("vfs.create: %p\n", newFile.ptr());
#endif
#if 1
auto newDir = vfs.mkdir("/mydir");
printf("vfs.mkdir: %p\n", newDir.ptr());
#endif
//return 0;
if (!strcmp(v[0], "./vcat")) {
auto handle = vfs.open(v[2]);
if (!handle) {
printf("failed to open %s inside fs image\n", v[2]);
return 1;
}
auto contents = handle->readEntireFile();
FILE* fout = fopen(v[3], "w");
if (!fout) {
printf("failed to open %s for output\n", v[3]);
return 1;
}
fwrite(contents.pointer(), sizeof(char), contents.size(), fout);
fclose(fout);
return 0;
}
auto synthfs = SyntheticFileSystem::create();
bool success = static_cast<FileSystem&>(*synthfs).initialize();
printf("synth->initialize(): returned %u\n", success);
vfs.mount(std::move(synthfs), "/syn");
vfs.listDirectory("/");
printf("list /syn:\n");
vfs.listDirectory("/syn");
#if 0
auto handle = vfs.open("/home/andreas/../../home/./andreas/./file2");
printf("handle = %p\n", handle.ptr());
ASSERT(handle);
auto contents = handle->readEntireFile();
ASSERT(contents);
printf("contents: '%s'\n", contents->pointer());
#endif
String currentDirectory = "/";
while (true) {
char cmdbuf[256];
printf("::>");
fflush(stdout);
fgets(cmdbuf, sizeof(cmdbuf), stdin);
if (cmdbuf[strlen(cmdbuf) - 1] == '\n')
cmdbuf[strlen(cmdbuf) - 1] = '\0';
String command = cmdbuf;
auto parts = command.split(' ');
if (parts.isEmpty())
continue;
String cmd = parts[0];
if (cmd == "q")
break;
if (cmd == "pwd") {
printf("%s\n", currentDirectory.characters());
continue;
}
if (cmd == "ls") {
vfs.listDirectory(currentDirectory);
continue;
}
if (cmd == "lr") {
vfs.listDirectoryRecursively(currentDirectory);
continue;
}
if (cmd == "cd" && parts.size() > 1) {
char buf[1024];
sprintf(buf, "%s/%s", currentDirectory.characters(), parts[1].characters());
if (vfs.isDirectory(buf)) {
currentDirectory = buf;
} else {
printf("No such directory: %s\n", buf);
}
continue;
}
if (cmd == "mt" && parts.size() > 1) {
char buf[1024];
sprintf(buf, "%s/%s", currentDirectory.characters(), parts[1].characters());
vfs.touch(buf);
continue;
}
if (cmd == "stat" && parts.size() > 1) {
char buf[1024];
sprintf(buf, "%s/%s", currentDirectory.characters(), parts[1].characters());
auto handle = vfs.open(buf);
if (!handle) {
printf("Can't open '%s' :(\n", buf);
continue;
}
Unix::stat st;
int rc = handle->stat(&st);
if (rc < 0) {
printf("stat failed: %d\n", rc);
continue;
}
printf("st_dev: %u\n", st.st_dev);
printf("st_ino: %u\n", st.st_ino);
printf("st_mode: %o\n", st.st_mode);
printf("st_nlink: %u\n", st.st_nlink);
printf("st_uid: %u\n", st.st_uid);
printf("st_gid: %u\n", st.st_gid);
printf("st_rdev: %u\n", st.st_rdev);
printf("st_size: %lld\n", st.st_size);
printf("st_blksize: %u\n", st.st_blksize);
printf("st_blocks: %u\n", st.st_blocks);
printf("st_atime: %u - %s", st.st_atime, ctime(&st.st_atime));
printf("st_mtime: %u - %s", st.st_mtime, ctime(&st.st_mtime));
printf("st_ctime: %u - %s", st.st_ctime, ctime(&st.st_ctime));
continue;
}
if (cmd == "cat" && parts.size() > 1) {
char pathbuf[1024];
sprintf(pathbuf, "%s/%s", currentDirectory.characters(), parts[1].characters());
auto handle = vfs.open(pathbuf);
if (!handle) {
printf("failed to open %s\n", pathbuf);
continue;
}
auto contents = handle->readEntireFile();
fwrite(contents.pointer(), sizeof(char), contents.size(), stdout);
continue;
}
if (cmd == "kat" && parts.size() > 1) {
char pathbuf[1024];
sprintf(pathbuf, "%s/%s", currentDirectory.characters(), parts[1].characters());
auto handle = vfs.open(pathbuf);
if (!handle) {
printf("failed to open %s\n", pathbuf);
continue;
}
ssize_t nread;
byte buffer[512];
for (;;) {
nread = handle->read(buffer, sizeof(buffer));
if (nread <= 0)
break;
fwrite(buffer, 1, nread, stdout);
}
if (nread < 0)
printf("ERROR: %d\n", nread);
continue;
}
if (cmd == "ma") {
SimpleMalloc::dump();
continue;
}
}
return 0;
}
RetainPtr<FileSystem> makeFileSystem(const char* imagePath)
{
auto fsImage = FileBackedDiskDevice::create(imagePath, 512);
if (!fsImage->isValid()) {
fprintf(stderr, "Failed to open fs image file '%s'\n", imagePath);
exit(1);
}
auto ext2 = Ext2FileSystem::create(std::move(fsImage));
bool success = static_cast<FileSystem&>(*ext2).initialize();
printf("ext2->initialize(): returned %u\n", success);
return ext2;
}