From 4a81e6e9a21a050f5896d627f2f71dd457d97a71 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Tue, 26 May 2009 18:23:35 +0000 Subject: [PATCH] Let merge_file_changes operate directly on the other SFTs. dos_setfattr with SHARE now closes open SFTs referring to that file in compat mode. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1403 6ac86273-5f31-0410-b378-82cca8765d1b --- kernel/dosfns.c | 6 ++--- kernel/fatfs.c | 69 +++++++++++++++++++++++++------------------------ 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/kernel/dosfns.c b/kernel/dosfns.c index 5c31f84..db4eb55 100644 --- a/kernel/dosfns.c +++ b/kernel/dosfns.c @@ -1211,12 +1211,12 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp) if (IsShareInstalled(TRUE)) { - /* XXX SHARE should ideally close the file if it is opened in + /* SHARE closes the file if it is opened in * compatibility mode, else generate a critical error. - * Here just generate a critical error by opening in "rw compat" - * mode */ + * Here generate a critical error by opening in "rw compat" mode */ if ((result = share_open_check(PriPathName, cu_psp, O_RDWR, 0)) < 0) return result; + /* else dos_setfattr will close the file */ share_close_file(result); } return dos_setfattr(PriPathName, attrp); diff --git a/kernel/fatfs.c b/kernel/fatfs.c index 9b20695..dc3dda5 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -46,9 +46,8 @@ STATIC BOOL find_fname(f_node_ptr, char *, int); /* /// Added - Ron Cemer */ STATIC void merge_file_changes(f_node_ptr fnp, int collect); /* /// Added - Ron Cemer */ -STATIC int is_same_file(f_node_ptr fnp1, f_node_ptr fnp2); +STATIC int is_same_file(f_node_ptr fnp, sft FAR *sftp); /* /// Added - Ron Cemer */ -STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst); STATIC BOOL find_free(f_node_ptr); STATIC int alloc_find_free(f_node_ptr fnp, char *path, char *fcbname); STATIC VOID wipe_out(f_node_ptr); @@ -397,7 +396,7 @@ STATIC unsigned get_f_nodes_cnt(void) } /* /// Added - Ron Cemer */ - /* If more than one f_node has a file open, and a write + /* If more than one SFT has a file open, and a write occurs, this function must be called to propagate the results of that write to the other f_nodes which have that file open. Note that this function only has an @@ -407,7 +406,6 @@ STATIC unsigned get_f_nodes_cnt(void) unless these instances were generated by dup() or dup2(). */ STATIC void merge_file_changes(f_node_ptr fnp, int collect) { - f_node_ptr fnp2; int i, fd; unsigned f_nodes_cnt; @@ -415,19 +413,22 @@ STATIC void merge_file_changes(f_node_ptr fnp, int collect) return; fd = fnp->f_sft_idx; - fnp2 = &fnode[1]; f_nodes_cnt = get_f_nodes_cnt(); for (i = 0; i < f_nodes_cnt; i++) { - if (i != fd && sft_to_fnode(fnp2, i) == SUCCESS && is_same_file(fnp, fnp2)) + sft FAR *sftp = idx_to_sft(i); + if (i != fd && FP_OFF(sftp) != (size_t)-1 && is_same_file(fnp, sftp)) { if (collect) { /* We're collecting file changes from any other - f_node which refers to this file. */ - if (fnp2->f_mode != RDONLY) + SFT which refers to this file. */ + if ((sftp->sft_mode & O_ACCMODE) != RDONLY) { - copy_file_changes(fnp2, fnp); + setdstart(fnp->f_dpb, &fnp->f_dir, sftp->sft_stclust); + fnp->f_dir.dir_size = sftp->sft_size; + fnp->f_dir.dir_date = sftp->sft_date; + fnp->f_dir.dir_time = sftp->sft_time; break; } } @@ -436,36 +437,23 @@ STATIC void merge_file_changes(f_node_ptr fnp, int collect) /* We just made changes to this file, so we are distributing these changes to the other f_nodes which refer to this file. */ - copy_file_changes(fnp, fnp2); - fnode_to_sft(fnp2, i); + sftp->sft_stclust = getdstart(fnp->f_dpb, &fnp->f_dir); + sftp->sft_size = fnp->f_dir.dir_size; + sftp->sft_date = fnp->f_dir.dir_date; + sftp->sft_time = fnp->f_dir.dir_time; } } } } /* /// Added - Ron Cemer */ -STATIC int is_same_file(f_node_ptr fnp1, f_node_ptr fnp2) +STATIC int is_same_file(f_node_ptr fnp, sft FAR *sftp) { - return - (fnp1->f_dpb == fnp2->f_dpb) - && (fcbmatch(fnp1->f_dir.dir_name, fnp2->f_dir.dir_name)) - && ((fnp1->f_dir.dir_attrib & D_VOLID) == 0) - && ((fnp2->f_dir.dir_attrib & D_VOLID) == 0) - && (fnp1->f_diridx == fnp2->f_diridx) - && (fnp1->f_dirsector == fnp2->f_dirsector); -} - - /* /// Added - Ron Cemer */ -STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst) -{ - dst->f_dir.dir_start = src->f_dir.dir_start; -#ifdef WITHFAT32 - dst->f_dir.dir_start_high = src->f_dir.dir_start_high; -#endif - dst->f_dir.dir_size = src->f_dir.dir_size; - dst->f_dir.dir_date = src->f_dir.dir_date; - dst->f_dir.dir_time = src->f_dir.dir_time; - dst->f_dir.dir_attrib = src->f_dir.dir_attrib; + return fnp->f_dpb == sftp->sft_dcb + && (fnp->f_dir.dir_attrib & D_VOLID) == 0 + && (sftp->sft_attrib & D_VOLID) == 0 + && fnp->f_diridx == sftp->sft_diridx + && fnp->f_dirsector == sftp->sft_dirsector; } STATIC COUNT delete_dir_entry(f_node_ptr fnp) @@ -1843,8 +1831,21 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp) fnp->f_dir.dir_attrib |= attrp; /* JPP */ fnp->f_flags |= F_DMOD | F_DDATE; - /* should really close the file instead of merge */ - merge_file_changes(fnp, FALSE); + /* close open files in compat mode, otherwise there was a critical error */ + if (IsShareInstalled(FALSE)) { + int f_nodes_cnt = get_f_nodes_cnt(); + int i; + for (i = 0; i < f_nodes_cnt; i++) + { + sft FAR *sftp = idx_to_sft(i); + if (FP_OFF(sftp) != (size_t)-1 && is_same_file(fnp, sftp)) { + int rc = DosCloseSft(i, FALSE); + if (rc != SUCCESS) + return rc; + } + } + } + dir_write(fnp); dir_close(fnp); return SUCCESS;