Skip to content

Commit d5f3cd8

Browse files
committed
[file_handler] Bug fixes: GDT overflow, invalid last block. Add ferror
1 parent 2b6283a commit d5f3cd8

File tree

6 files changed

+32
-7
lines changed

6 files changed

+32
-7
lines changed

src/fs/ffs.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,10 @@ int fetch_file_content(
9494

9595
// fetch file entry
9696
int file_size = entry->content.filesize;
97-
int block_count = file_size/FS_BLOCK_SIZE;
97+
int block_count = (file_size+FS_BLOCK_SIZE-1)/FS_BLOCK_SIZE;
9898
if(file_block_id >= block_count) {
99-
return -1;
99+
// zero block read
100+
return 0;
100101
}
101102

102103
int err = partition_read_block(

src/kernel/syscall/file_handler.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ int _file_handler_read(int user_ds, int file_id, char _us_buffer[FILEIO_BUFFER_S
6060
return 0;
6161
}
6262
len = min(len, FILEIO_BUFFER_SIZE); // guard for _us_buffer
63-
63+
len = min(len, FS_BLOCK_SIZE-byte_index_block); // skip already read content of the block
6464
syscall_strncpy_kernel_to_user(user_ds, _us_buffer, block+byte_index_block, len);
6565
return len;
6666
}

src/usr/include/stdio.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ typedef struct FILE {
2222

2323
// 0 => start of file
2424
int cursor;
25+
26+
// store last error code
27+
int err;
2528
} FILE;
2629

2730
// TODO: Add API for reading list of files.
@@ -41,4 +44,7 @@ typedef struct FILE {
4144
FILE *fopen(char *filename, char *mode);
4245
int fgetc(FILE *file);
4346
char *fgets(char *buf, size_t n, FILE *file);
44-
int fclose(FILE *file);
47+
int fclose(FILE *file);
48+
49+
int ferror(FILE *file);
50+
void clearerror(FILE *file);

src/usr/lib/stdio.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ FILE *fopen(char *filename, char *mode) {
131131
handler->file_handler_id = fh_id;
132132
handler->file_id = file_id;
133133
handler->cursor = 0;
134+
handler->err = 0;
134135
return handler;
135136
}
136137

@@ -152,10 +153,15 @@ char *fgets(char *buf, size_t n, FILE *file) {
152153
int count = SYSCALL_A4(SYSCALL_FILE_OP, SYSCALL_FILE_SUB_READBUFFER, file->file_id, _buffer, file->cursor);
153154
if (count < 0) {
154155
// error
156+
file->err = count;
155157
return NULL;
156158
}
157159
if (count == 0) {
158160
// EOF
161+
if(og_buf==buf) {
162+
// no new characters read
163+
return NULL;
164+
}
159165
break;
160166
}
161167

@@ -164,11 +170,11 @@ char *fgets(char *buf, size_t n, FILE *file) {
164170
int found_newline = 0;
165171
for (size_t i = 0; i < max_iterations; i++) {
166172
char_read_count++;
173+
*(buf++)=_buffer[i];
167174
if(_buffer[i]=='\n') {
168175
found_newline = 1;
169176
break;
170177
}
171-
*(buf++)=_buffer[i];
172178
}
173179
file->cursor += char_read_count;
174180
n-=char_read_count;
@@ -181,3 +187,11 @@ char *fgets(char *buf, size_t n, FILE *file) {
181187
int fgetc(FILE *file) {
182188

183189
}
190+
191+
int ferror(FILE *file) {
192+
return file->err;
193+
}
194+
195+
void clearerror(FILE *file) {
196+
file->err=0;
197+
}

src/usr/local/src/cat.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ void process(char filename[]) {
1111
char buffer[80];
1212
while(1) {
1313
if (!fgets(buffer, sizeof(buffer), handler)) {
14+
int err = ferror(handler);
15+
if(err) {
16+
printf("Error: failed to read next chunk, code %d\n", err);
17+
exit(err);
18+
}
1419
break;
1520
}
1621
puts(buffer);
17-
putchar('\n');
1822
}
1923
fclose(handler);
2024
}

tests/app/cat_test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ QEMU_SCREENSHOT_NAME="cat_test.ppm"
77
python3 -m tests.qemu.monitor -p ${MONITOR_PORT:?} -sc cat readme.md
88

99
test_create_screen_dump
10-
test_screen_content $LINENO "Use make to build binaries and image files"
10+
test_screen_content $LINENO "Execute QEMU in debug mode and setup GDB server"

0 commit comments

Comments
 (0)