Reputation: 103
i have a c function where i open and close a file. But i want to replace the fgets function for a custom readFile function implemented in MIPS.
According to: When reading file in MIPS, it reads last line twice and http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html i need to pass the syscall the code 14; and file descriptor,address of input buffer and maximum number of characters to read as arguments.
When opening the file in c i get a FILE*, from which i get a fileDescriptor using fileno (according to this How can I convert a file pointer ( FILE* fp ) to a file descriptor (int fd)?).
The problem is the syscall appears to not being executed. The buffer remains unchanged, and even the return register (v0), has the value 14 (the same code), instead of the numbers of characters read.
the MIPS code using to call the syscall is:
li v0, 14 # system call for read from file
lw a0, 40($fp) # file descriptor
lw a1, 32($fp) # address of buffer to which to read
lw a2, 36($fp) # buffer length
syscall # read from file
What could be wrong? Thanks
Upvotes: 3
Views: 1376
Reputation: 103
I could finally solve this. It happens that the syscall code wasn't 14, but 3 (SYS_read macro).
The code in readFile.S to read is:
li v0, SYS_read # system call for read from file
lw a0, 40($fp) # file descriptor
lw a1, 32($fp) # address of buffer to which to read
lw a2, 36($fp) # buffer length
syscall # read from file
the first parameter is a file descriptor, not a file pointer. So i call my custom readFile function from main.c like this:
FILE *fp;
fp = fopen("test-files/test.txt", "r");
int fileDescriptor = fileno(fp);
int bufIncrSize = 10;
char *buffer = (char*) malloc(bufIncrSize);
while (readFile(buffer, bufIncrSize, fileDescriptor)) {
printf("%s",buffer);
}
Disclaimer: This code is incomplete to replace fgets which does:
The C library function char *fgets(char *str, int n, FILE *stream) reads a line from the specified stream and stores it into the string pointed to by str. It stops when either (n-1) characters are read, the newline character is read, or the end-of-file is reached, whichever comes first.
the SYS_read system call doesn't stop at a newline character, so it could read more than one line. So, you should implement this beahivour on your own.
Upvotes: 1