diff options
Diffstat (limited to 'Source/DOH/file.c')
-rw-r--r-- | Source/DOH/file.c | 97 |
1 files changed, 73 insertions, 24 deletions
diff --git a/Source/DOH/file.c b/Source/DOH/file.c index 5c56771d0..570f84ed5 100644 --- a/Source/DOH/file.c +++ b/Source/DOH/file.c @@ -26,6 +26,73 @@ typedef struct { } DohFile; /* ----------------------------------------------------------------------------- + * open_files_list_instance + * open_files_list_add + * open_files_list_remove + * + * Singleton list containing all the files that have been opened by DohNewFile. + * Open file pointers are held in the list as strings so as to not affect the + * reference count of the underlying DOH objects. + * ----------------------------------------------------------------------------- */ + +static DOHList *open_files_list_instance() { + static DOHList *all_open_files = 0; + if (!all_open_files) + all_open_files = DohNewList(); + return all_open_files; +} + +static void open_files_list_add(DohFile *f) { + DOHList *all_open_files = open_files_list_instance(); + DOHString *sf = NewStringf("%p", f); + Append(all_open_files, sf); + Delete(sf); +} + +static void open_files_list_remove(DohFile *f) { + int i; + int removed = 0; + DOHList *all_open_files = open_files_list_instance(); + DOHString *sf = NewStringf("%p", f); + for (i = 0; i < DohLen(all_open_files); i++) { + DOHString *sf_i = Getitem(all_open_files, i); + if (Strcmp(sf, sf_i) == 0) { + DohDelitem(all_open_files, i); + removed = 1; + break; + } + } + Delete(sf); + assert(removed); +} + +/* ----------------------------------------------------------------------------- + * DohCloseAllOpenFiles() + * + * Close all opened files, to be called on program termination + * ----------------------------------------------------------------------------- */ + +void DohCloseAllOpenFiles() { + int i; + DOHList *all_open_files = open_files_list_instance(); + for (i = 0; i < DohLen(all_open_files); i++) { + DohFile *f = 0; + DOHString *sf = Getitem(all_open_files, i); + int check = sscanf(Char(sf), "%p", (void **)&f); + assert(check == 1); + if (f->closeondel) { + if (f->filep) { + check = fclose(f->filep); + assert(check == 0); + } + f->closeondel = 0; + f->filep = 0; + } + } + DohClear(all_open_files); +} + +/* ----------------------------------------------------------------------------- * DelFile() * ----------------------------------------------------------------------------- */ @@ -40,6 +107,7 @@ static void DelFile(DOH *fo) { close(f->fd); } #endif + open_files_list_remove(f); } DohFree(f); } @@ -166,27 +234,6 @@ static int File_ungetc(DOH *fo, int ch) { return -1; } -/* ----------------------------------------------------------------------------- - * File_close() - * - * Close the file - * ----------------------------------------------------------------------------- */ - -static int File_close(DOH *fo) { - int ret = 0; - DohFile *f = (DohFile *) ObjData(fo); - if (f->filep) { - ret = fclose(f->filep); - f->filep = 0; - } else if (f->fd) { -#ifdef DOH_INTFILE - ret = close(f->fd); - f->fd = 0; -#endif - } - return ret; -} - static DohFileMethods FileFileMethods = { File_read, File_write, @@ -195,7 +242,6 @@ static DohFileMethods FileFileMethods = { File_ungetc, File_seek, File_tell, - File_close, /* close */ }; static DohObjInfo DohFileType = { @@ -231,8 +277,9 @@ static DohObjInfo DohFileType = { * If newfiles is non-zero, the filename is added to the list of new files. * ----------------------------------------------------------------------------- */ -DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) { +DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) { DohFile *f; + DOH *obj; FILE *file; char *filen; @@ -251,7 +298,9 @@ DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) { f->filep = file; f->fd = 0; f->closeondel = 1; - return DohObjMalloc(&DohFileType, f); + obj = DohObjMalloc(&DohFileType, f); + open_files_list_add(f); + return obj; } /* ----------------------------------------------------------------------------- |