Skip to content

Commit

Permalink
Adding a file reading example
Browse files Browse the repository at this point in the history
  • Loading branch information
darleybarreto authored and windelbouwman committed Jan 31, 2021
1 parent 7c12948 commit aacfd18
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 1 deletion.
15 changes: 15 additions & 0 deletions examples/linux64/file-reading/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# One can run this file inside this folder as $make clean && make all

CC = python -m ppci cc --freestanding -I ../../../librt/libc/include
CFLAGS = -O1

all: reading_file

reading_file: reading_file.o
python -m ppci ld --entry main --layout ../linux64.mmap $^ -o $@

reading_file.o:
$(CC) reading_file.c ../../../librt/libc/src/*.c ../../../librt/libc/src/*/*.c -o reading_file.o

clean:
rm -f *.o *.S reading_file
6 changes: 6 additions & 0 deletions examples/linux64/file-reading/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
The PPCI (Pure Python Compiler Infrastructure) project is a compiler
written entirely in the Python programming
language. It contains front-ends for various programming languages as
well as machine code generation functionality. With this library you can
generate (working!) machine code using Python (and thus very easy to
explore, extend, etc.)!
48 changes: 48 additions & 0 deletions examples/linux64/file-reading/reading_file.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

// In this example we will be using some low level functions to open, read and close a file from the system

int main(int argc, char **argv){
// The function open and the flag O_RDONLY are defined in fcntl.h
// It is a thin wrapper around a bare syscall
int fd = open("example.txt",O_RDONLY);

if (fd == -1){
printf("ERROR: Could not open the file");
exit(1);
}

// f_size is a helper function defined in sys/stat.h for this libc
// It is a wrapper around the fstat syscall to get the size in bytes of the file
long buffer_size = f_size(fd);

if (buffer_size == -1){
printf("Error while getting the file size");
exit(1);
}

// Malloc also uses syscalls to get memory from the system
void *buffer = malloc(buffer_size);

// Both read and close are defined in unistd.h
// Both are wrappers around bare syscalls
ssize_t size = read(fd, buffer, (size_t)buffer_size);

if (size == -1){
printf("Error while reading file to buffer");
exit(1);
}

if (close(fd) == -1){
printf("Error while closing the file");
exit(1);
}

printf("%s",(char*)buffer);

exit(0);
}
6 changes: 6 additions & 0 deletions librt/libc/include/fcntl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#define O_RDONLY 0x0000 /* open for reading only */
#define O_WRONLY 0x0001 /* open for writing only */
#define O_RDWR 0x0002 /* open for reading and writing */
#define O_ACCMODE 0x0003 /* mask for above modes */

int open(const char *filename, int mode);
3 changes: 2 additions & 1 deletion librt/libc/include/stddef.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@


typedef int wchar_t;
typedef int size_t;
typedef unsigned int size_t;
typedef int ssize_t;

#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)

Expand Down
3 changes: 3 additions & 0 deletions librt/libc/include/sys/stat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
void fstat(int fd, void * statstruct);

inline int f_size(int fd);
5 changes: 5 additions & 0 deletions librt/libc/include/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ int isatty(int fd);
char *getcwd(char *buf, size_t size);
char *getwd(char *buf);

ssize_t read(int, void *, size_t);
ssize_t write(int, const void *, size_t);

int close(int);

#endif

6 changes: 6 additions & 0 deletions librt/libc/src/fcntl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "stdlib.h"
#include "fcntl.h"

int open(const char *filename, int mode){
return syscall(2, filename, mode, 0);
}
22 changes: 22 additions & 0 deletions librt/libc/src/stat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "stdlib.h"
#include "sys/stat.h"

void fstat(int fd, void * statstruct){
syscall(5, fd, (long) statstruct, 0);
}

inline int f_size(int fd){
// needs to inform the size of kernel linux stat struct size
// which is 144 bytes in x86_64 systems
char buffer[144];

void * statstruct = (void*)(&buffer);

fstat(fd, statstruct);

// from the begin to the size part, we have
// 8 + 8 + 8 + 8 + 4 + 4 + 8 = 48 bytes
long size = *((long*)(statstruct + 48));

return size;
}
10 changes: 10 additions & 0 deletions librt/libc/src/unistd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "stdlib.h"
#include "unistd.h"

ssize_t read(int fd, void *buf, size_t count){
return (size_t) syscall(0, fd, buf, count);
}

int close(int fd){
return syscall(3, fd, 0, 0);
}

0 comments on commit aacfd18

Please sign in to comment.