mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-23 05:44:41 +02:00
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:
parent
7083b0a4fa
commit
affddaaf64
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user