Handle dos_getfattr and dos_setfattr directly at the directory level, instead

of opening the file, to avoid needing to claim SFTs in later changes.
Clarify and implement parts of the correct SHARE behaviour.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1393 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2009-05-23 02:04:03 +00:00
parent 7083b0a4fa
commit affddaaf64
2 changed files with 43 additions and 58 deletions

View File

@ -1206,34 +1206,6 @@ COUNT DosGetFattr(BYTE FAR * name)
if (result & IS_DEVICE) if (result & IS_DEVICE)
return DE_FILENOTFND; return DE_FILENOTFND;
/* /// Use truename()'s result, which we already have in PriPathName.
I copy it to tmp_name because PriPathName is global and seems
to get trashed somewhere in transit.
The reason for using truename()'s result is that dos_?etfattr()
are very low-level functions and don't handle full path expansion
or cleanup, such as converting "c:\a\b\.\c\.." to "C:\A\B".
- Ron Cemer
*/
/*
memcpy(SecPathName,PriPathName,sizeof(SecPathName));
return dos_getfattr(SecPathName, attrp);
*/
/* no longer true. dos_getfattr() is
A) intelligent (uses dos_open) anyway
B) there are some problems with MAX_PARSE, i.e. if PATH ~= 64
and TRUENAME adds a C:, which leeds to trouble.
the problem was discovered, when VC did something like
fd = DosOpen(filename,...)
jc can't_copy_dialog;
attr = DosGetAttrib(filename);
jc can't_copy_dialog;
and suddenly, the filehandle stays open
shit.
tom
*/
return dos_getfattr(PriPathName); return dos_getfattr(PriPathName);
} }
@ -1254,17 +1226,16 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
if (result & IS_DEVICE) if (result & IS_DEVICE)
return DE_FILENOTFND; return DE_FILENOTFND;
/* /// Use truename()'s result, which we already have in PriPathName. if (IsShareInstalled(TRUE))
I copy it to tmp_name because PriPathName is global and seems {
to get trashed somewhere in transit. /* XXX SHARE should ideally close the file if it is opened in
- Ron Cemer * compatibility mode, else generate a critical error.
*/ * Here just generate a critical error by opening in "rw compat"
/* * mode */
memcpy(SecPathName,PriPathName,sizeof(SecPathName)); if ((result = share_open_check(PriPathName, cu_psp, O_RDWR, 0)) < 0)
return dos_setfattr(SecPathName, attrp); return result;
share_close_file(result);
see DosGetAttr() }
*/
return dos_setfattr(PriPathName, attrp); return dos_setfattr(PriPathName, attrp);
} }

View File

@ -501,6 +501,7 @@ STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst)
dst->f_dir.dir_size = src->f_dir.dir_size; dst->f_dir.dir_size = src->f_dir.dir_size;
dst->f_dir.dir_date = src->f_dir.dir_date; dst->f_dir.dir_date = src->f_dir.dir_date;
dst->f_dir.dir_time = src->f_dir.dir_time; dst->f_dir.dir_time = src->f_dir.dir_time;
dst->f_dir.dir_attrib = src->f_dir.dir_attrib;
} }
STATIC COUNT delete_dir_entry(f_node_ptr fnp) STATIC COUNT delete_dir_entry(f_node_ptr fnp)
@ -1935,21 +1936,28 @@ COUNT dos_getfattr_fd(COUNT fd)
COUNT dos_getfattr(BYTE * name) COUNT dos_getfattr(BYTE * name)
{ {
COUNT result, fd; f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
COUNT result;
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0); /* split the passed dir into components (i.e. - path to */
if (fd < SUCCESS) /* new directory and name of new directory. */
return fd; if ((fnp = split_path(name, fcbname, &fnode[0])) == NULL)
return DE_PATHNOTFND;
result = dos_getfattr_fd(fd); if (find_fname(fnp, fcbname, D_ALL))
dos_close(fd); result = fnp->f_dir.dir_attrib;
else
result = DE_FILENOTFND;
dir_close(fnp);
return result; return result;
} }
COUNT dos_setfattr(BYTE * name, UWORD attrp) COUNT dos_setfattr(BYTE * name, UWORD attrp)
{ {
COUNT fd;
f_node_ptr fnp; f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* JPP-If user tries to set VOLID or RESERVED bits, return error. /* JPP-If user tries to set VOLID or RESERVED bits, return error.
We used to also check for D_DIR here, but causes issues with deltree We used to also check for D_DIR here, but causes issues with deltree
@ -1960,29 +1968,35 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp)
if ((attrp & (D_VOLID | 0xC0)) != 0) if ((attrp & (D_VOLID | 0xC0)) != 0)
return DE_ACCESS; return DE_ACCESS;
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0); /* split the passed dir into components (i.e. - path to */
if (fd < SUCCESS) /* new directory and name of new directory. */
return fd; if ((fnp = split_path(name, fcbname, &fnode[0])) == NULL)
return DE_PATHNOTFND;
fnp = xlt_fd(fd); if (!find_fname(fnp, fcbname, D_ALL)) {
dir_close(fnp);
/* Set the attribute from the fnode and return */ return DE_FILENOTFND;
/* clear all attributes but DIR and VOLID */ }
fnp->f_dir.dir_attrib &= (D_VOLID | D_DIR); /* JPP */
/* if caller tries to set DIR on non-directory, return error */ /* if caller tries to set DIR on non-directory, return error */
if ((attrp & D_DIR) && !(fnp->f_dir.dir_attrib & D_DIR)) if ((attrp & D_DIR) && !(fnp->f_dir.dir_attrib & D_DIR))
{ {
dos_close(fd); dir_close(fnp);
return DE_ACCESS; return DE_ACCESS;
} }
/* Set the attribute from the fnode and return */
/* clear all attributes but DIR and VOLID */
fnp->f_dir.dir_attrib &= (D_VOLID | D_DIR); /* JPP */
/* set attributes that user requested */ /* set attributes that user requested */
fnp->f_dir.dir_attrib |= attrp; /* JPP */ fnp->f_dir.dir_attrib |= attrp; /* JPP */
fnp->f_flags |= F_DMOD | F_DDATE; fnp->f_flags |= F_DMOD | F_DDATE;
/* should really close the file instead of merge */
merge_file_changes(fnp, FALSE); merge_file_changes(fnp, FALSE);
save_far_f_node(fnp); dir_write(fnp);
dos_close(fd); dir_close(fnp);
return SUCCESS; return SUCCESS;
} }
#endif #endif