Skip to content

Commit 9eca435

Browse files
committed
Add app/cat
1 parent 32e2781 commit 9eca435

File tree

6 files changed

+102
-14
lines changed

6 files changed

+102
-14
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ files : src/BOOTX64.EFI src/LIUMOS.ELF .FORCE
3434
cp src/LIUMOS.ELF mnt/LIUMOS.ELF
3535
mkdir -p mnt/EFI/EFI/
3636
echo 'FS0:\\EFI\\BOOT\\BOOTX64.EFI' > mnt/startup.nsh
37+
cp README.md mnt/
3738

3839
.PHONY : internal_run_loader_test
3940

app/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ APPS=\
44
argstest/argstest.bin \
55
browser-rs/browser-rs.bin \
66
browser/browser.bin \
7+
cat/cat.bin \
78
dig/dig.bin \
89
fizzbuzz/fizzbuzz.bin \
910
guitest/guitest.bin \

app/cat/Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
NAME=cat
2+
TARGET=$(NAME).bin
3+
TARGET_OBJS=$(NAME).o
4+
5+
default: $(TARGET)
6+
7+
include ../liumlib/common.mk

app/cat/cat.c

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "../liumlib/liumlib.h"
2+
3+
int main(int argc, char** argv) {
4+
// Concat
5+
if (argc < 2) {
6+
Print("Usage: ");
7+
Print(argv[0]);
8+
Print(" <file> ...\n");
9+
exit(EXIT_FAILURE);
10+
}
11+
int fd = open(argv[1], 0, 0);
12+
if(fd < 0) {
13+
Print("Failed to open a file\n");
14+
exit(EXIT_FAILURE);
15+
}
16+
char buf[1];
17+
while(read(fd, buf, sizeof(buf)) == 1) {
18+
putchar(buf[0]);
19+
}
20+
}

app/liumlib/liumlib.h

+7
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ static inline int puts(const char *s) {
173173
Println(s);
174174
return strlen(s);
175175
}
176+
static inline int putchar(char c) {
177+
char s[2];
178+
s[0] = c;
179+
s[1] = 0;
180+
Print(s);
181+
return 1;
182+
}
176183

177184

178185
#endif /* GRANDPARENT_H */

src/syscall.cc

+66-14
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ typedef uint32_t socklen_t;
4848
struct PerProcessSyscallData {
4949
Sheet* window_sheet;
5050
int num_getdents64_called;
51+
// for opening normal file: fd = 6
52+
int idx_in_root_files;
53+
uint64_t read_offset;
5154
};
5255

5356
std::unordered_map<Process::PID, PerProcessSyscallData>
@@ -249,19 +252,38 @@ static int sys_bind(int sockfd, sockaddr_in* addr, socklen_t addrlen) {
249252
}
250253

251254
static ssize_t sys_read(int fd, void* buf, size_t count) {
252-
if (fd != 0) {
253-
kprintf("%s: fd %d is not supported yet: only stdin is supported now.\n",
254-
__func__, fd);
255-
return ErrorNumber::kInvalid;
256-
}
257-
if (count < 1)
258-
return ErrorNumber::kInvalid;
259-
auto& proc_stdin = liumos->scheduler->GetCurrentProcess().GetStdIn();
260-
while (proc_stdin.IsEmpty()) {
261-
StoreIntFlagAndHalt();
255+
if (fd == 0) {
256+
if (count < 1)
257+
return ErrorNumber::kInvalid;
258+
auto& proc_stdin = liumos->scheduler->GetCurrentProcess().GetStdIn();
259+
while (proc_stdin.IsEmpty()) {
260+
StoreIntFlagAndHalt();
261+
}
262+
reinterpret_cast<uint8_t*>(buf)[0] = proc_stdin.Pop();
263+
return 1;
264+
}
265+
if (fd == 6) {
266+
auto pid = liumos->scheduler->GetCurrentProcess().GetID();
267+
auto& ppdata = per_process_syscall_data[pid];
268+
LoaderInfo& loader_info = *reinterpret_cast<LoaderInfo*>(
269+
reinterpret_cast<uint64_t>(&GetLoaderInfo()) +
270+
GetKernelStraightMappingBase());
271+
EFIFile& file = loader_info.root_files[ppdata.idx_in_root_files];
272+
uint64_t file_size = file.GetFileSize();
273+
const uint8_t* src = reinterpret_cast<const uint8_t*>(
274+
reinterpret_cast<uint64_t>(file.GetBuf()) +
275+
GetKernelStraightMappingBase());
276+
assert(file_size >= ppdata.read_offset);
277+
uint64_t copy_size = std::min(file_size - ppdata.read_offset, count);
278+
if (copy_size) {
279+
memcpy(buf, src + ppdata.read_offset, copy_size);
280+
ppdata.read_offset += copy_size;
281+
}
282+
return copy_size;
262283
}
263-
reinterpret_cast<uint8_t*>(buf)[0] = proc_stdin.Pop();
264-
return 1;
284+
kprintf("%s: fd %d is not supported yet: only stdin is supported now.\n",
285+
__func__, fd);
286+
return ErrorNumber::kInvalid;
265287
}
266288

267289
static std::optional<Network::EtherAddr> ResolveIPv4WithTimeout(
@@ -453,9 +475,39 @@ __attribute__((ms_abi)) extern "C" void SyscallHandler(uint64_t* args) {
453475
if (idx == kSyscallIndex_sys_open) {
454476
auto pid = liumos->scheduler->GetCurrentProcess().GetID();
455477
auto& ppdata = per_process_syscall_data[pid];
456-
ppdata.num_getdents64_called = 0;
457478

458-
args[0] = 5;
479+
const char* file_name = reinterpret_cast<const char*>(args[1]);
480+
kprintf("file name: %s\n", file_name);
481+
482+
if (IsEqualString(".", file_name)) {
483+
// for getdents64
484+
ppdata.num_getdents64_called = 0;
485+
args[0] = 5;
486+
return;
487+
}
488+
489+
int found_idx = -1;
490+
491+
LoaderInfo& loader_info = *reinterpret_cast<LoaderInfo*>(
492+
reinterpret_cast<uint64_t>(&GetLoaderInfo()) +
493+
GetKernelStraightMappingBase());
494+
kprintf("&GetLoaderInfo(): %p\n", &GetLoaderInfo());
495+
kprintf("&loader_info: %p\n", &loader_info);
496+
for (int i = 0; i < loader_info.root_files_used; i++) {
497+
if (IsEqualString(loader_info.root_files[i].GetFileName(), file_name)) {
498+
found_idx = i;
499+
break;
500+
}
501+
}
502+
if (found_idx == -1) {
503+
kprintf("not found!\n");
504+
*((int64_t*)&args[0]) = -1;
505+
return;
506+
}
507+
kprintf("found at index = %d!\n", found_idx);
508+
ppdata.idx_in_root_files = found_idx;
509+
ppdata.read_offset = 0;
510+
args[0] = 6;
459511
return;
460512
}
461513
if (idx == kSyscallIndex_sys_close) {

0 commit comments

Comments
 (0)