aboutsummaryrefslogtreecommitdiff
path: root/Source/DOH/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DOH/file.c')
-rw-r--r--Source/DOH/file.c97
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;
}
/* -----------------------------------------------------------------------------