#include #include #include #include #include #include #include "vfs.h" typedef struct _vfs_mapping_struct { char* mntpnt; uint32_t type; struct _vfs_mapping_struct* next; } vfs_mapping; static const char** drv_names; static fs_drv* drvs; static uint32_t max_drvs; static uint32_t next_drv_indx; static vfs_mapping* head_mapping; static vfs_mapping* tail_mapping; FILE* stdin=NULL; FILE* stdout=NULL; FILE* stderr=NULL; static int vfsstrcmp(const char* s1,const char* s2) { int i; for (i = 0; s1[i] == s2[i]; i++) { if (s1[i] == '\0') return 0; } if (s1[i] == '\0') return 0; return s1[i] - s2[i]; } void init_vfs() { drvs=malloc(sizeof(fs_drv)*32); drv_names=malloc(sizeof(const char**)*32); max_drvs=32; next_drv_indx=0; head_mapping=NULL; tail_mapping=NULL; } uint32_t register_fs(fs_drv drv,const char* type) { if (next_drv_indx==max_drvs) { drvs=realloc(drvs,sizeof(fs_drv)*(max_drvs+32)); drv_names=realloc(drv_names,sizeof(char*)*(max_drvs+32)); max_drvs+=32; } drvs[next_drv_indx]=drv; drv_names[next_drv_indx]=type; next_drv_indx++; return next_drv_indx-1; } char mount(char* mntpnt,char* dev,char* type) { uint32_t i; for (i=0;imntpnt=malloc(sizeof(char)*(strlen(mntpnt)+1)); strcpy(mapping->mntpnt,mntpnt); mapping->type=i; mapping->next=NULL; head_mapping=mapping; tail_mapping=mapping; } else { vfs_mapping* mapping=malloc(sizeof(vfs_mapping)); mapping->mntpnt=malloc(sizeof(char)*(strlen(mntpnt)+1)); strcpy(mapping->mntpnt,mntpnt); mapping->type=i; mapping->next=NULL; tail_mapping->next=mapping; } return 1; } else { return 0; } } FILE* fopen(const char* filename,const char* mode) { vfs_mapping* mnt=head_mapping; vfs_mapping* mntpnt=NULL; const char* path; uint32_t mntpnt_len=0; for (;mnt!=NULL;mnt=mnt->next) { char* root=mnt->mntpnt; if (strlen(root)>mntpnt_len) { if (vfsstrcmp(root,filename)==0) { mntpnt=mnt; mntpnt_len=strlen(root); } } } if (mntpnt) { path=filename+mntpnt_len; FILE* stream=malloc(sizeof(FILE)); stream->mntpnt=mntpnt->mntpnt; stream->path=path; if (strcmp(mode,"w")==0) { stream->wr=1; stream->rd=0; } else if (strcmp(mode,"r+")==0) { stream->wr=1; stream->rd=1; } else { stream->wr=0; stream->rd=1; } stream->type=mntpnt->type; stream->pos=0; stream->eof=0; stream->error=0; char ok=drvs[mntpnt->type](FSOP_OPEN,stream,NULL,NULL); if (ok) { return stream; } else { free(stream); return NULL; } } return NULL; } int fgetc(FILE* stream) { if (!stream->rd) { errno=EBADF; stream->error=1; return EOF; } int c; drvs[stream->type](FSOP_GETC,stream,&c,NULL); return c; } int getc() { return fgetc(stdin); } char* fgets(char* str,int count,FILE* stream) { if (!stream->rd) { errno=EBADF; stream->error=1; return NULL; } int i; for (i=0;ird) { errno=EBADF; stream->error=1; return 0; } char* buffer=(char*)buffer_ptr; size_t bytes=size*count; for (size_t i=0;iwr) { errno=EBADF; stream->error=1; return EOF; } char ok=drvs[stream->type](FSOP_PUTC,stream,&c,NULL); if (ok) { return c; } else { return EOF; } } int putc(int c) { return fputc(c,stdout); } int fputs(const char* s,FILE* stream) { if (!stream->wr) { errno=EBADF; stream->error=1; return EOF; } size_t len=strlen(s); for (size_t i=0;iwr) { errno=EBADF; stream->error=1; return 0; } char* buffer=(char*)buffer_ptr; size_t bytes=size*count; for (size_t i=0;ipos=offset; } if (origin==SEEK_CUR) { stream->pos+=offset; } return 0; } long ftell(FILE* stream) { return stream->pos; } int fclose(FILE* stream) { drvs[stream->type](FSOP_CLOSE,stream,NULL,NULL); free(stream); return 0; } int feof(FILE *stream) { return stream->eof; } int ferror(FILE *stream) { return stream->error; }