mirror of https://github.com/FDOS/kernel.git
Made the main fnodes far so they can be in UMBs.
Internally the kernel uses two near fnodes though, to save on codesize and fmemcpy's if necessary. Having memory management on two fnodes is a little silly but I just want to make sure with the panic message that we never accidentally try to use three near fnodes at the same time. (two are used at the same time by rename, commit, and merge_file_changes). This can be cleaned up later. Anyway. 644736 bytes free conv memory isn't bad. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@821 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
13ab8971fd
commit
f63eea565a
|
@ -80,7 +80,7 @@ struct lol {
|
||||||
unsigned char os_major; /* 6d major DOS version */
|
unsigned char os_major; /* 6d major DOS version */
|
||||||
unsigned char rev_number; /* 6e minor DOS version */
|
unsigned char rev_number; /* 6e minor DOS version */
|
||||||
unsigned char version_flags; /* 6f DOS version flags */
|
unsigned char version_flags; /* 6f DOS version flags */
|
||||||
f_node_ptr f_nodes; /* 70 pointer to the array */
|
struct f_node FAR *f_nodes; /* 70 pointer to the array */
|
||||||
unsigned short f_nodes_cnt; /* 72 number of allocated f_nodes */
|
unsigned short f_nodes_cnt; /* 74 number of allocated f_nodes */
|
||||||
char *os_release; /* 74 near pointer to os_release string */
|
char *os_release; /* 76 near pointer to os_release string */
|
||||||
};
|
};
|
||||||
|
|
|
@ -267,7 +267,7 @@ typedef void config_sys_func_t(BYTE * pLine);
|
||||||
|
|
||||||
struct table {
|
struct table {
|
||||||
BYTE *entry;
|
BYTE *entry;
|
||||||
BYTE pass;
|
signed char pass;
|
||||||
config_sys_func_t *func;
|
config_sys_func_t *func;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -365,11 +365,8 @@ void PreConfig(void)
|
||||||
DynAlloc("DPBp", blk_dev.dh_name[0], sizeof(struct dpb));
|
DynAlloc("DPBp", blk_dev.dh_name[0], sizeof(struct dpb));
|
||||||
|
|
||||||
/* Initialize the file table */
|
/* Initialize the file table */
|
||||||
/* f_nodes = (f_node_ptr)
|
LoL->f_nodes =
|
||||||
KernelAlloc(Config.cfgFiles * sizeof(struct f_node));*/
|
KernelAlloc(Config.cfgFiles * sizeof(struct f_node), 'F', 0);
|
||||||
|
|
||||||
LoL->f_nodes = (f_node_ptr)
|
|
||||||
DynAlloc("f_nodes", Config.cfgFiles, sizeof(struct f_node));
|
|
||||||
|
|
||||||
LoL->f_nodes_cnt = Config.cfgFiles;
|
LoL->f_nodes_cnt = Config.cfgFiles;
|
||||||
LoL->sfthead = MK_FP(FP_SEG(LoL), 0xcc); /* &(LoL->firstsftt) */
|
LoL->sfthead = MK_FP(FP_SEG(LoL), 0xcc); /* &(LoL->firstsftt) */
|
||||||
|
@ -384,7 +381,7 @@ void PreConfig(void)
|
||||||
LoL->CDSp = KernelAlloc(sizeof(struct cds) * LoL->lastdrive, 'L', 0);
|
LoL->CDSp = KernelAlloc(sizeof(struct cds) * LoL->lastdrive, 'L', 0);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Preliminary:\n f_node 0x%x", LoL->f_nodes);
|
printf("Preliminary:\n f_node 0x%p\n", LoL->f_nodes);
|
||||||
/* printf(" FCB table 0x%p\n",LoL->FCBp);*/
|
/* printf(" FCB table 0x%p\n",LoL->FCBp);*/
|
||||||
printf(" sft table 0x%p\n", LoL->sfthead);
|
printf(" sft table 0x%p\n", LoL->sfthead);
|
||||||
printf(" CDS table 0x%p\n", LoL->CDSp);
|
printf(" CDS table 0x%p\n", LoL->CDSp);
|
||||||
|
@ -405,13 +402,6 @@ void PreConfig2(void)
|
||||||
|
|
||||||
/* initialize NEAR allocated things */
|
/* initialize NEAR allocated things */
|
||||||
|
|
||||||
/* Initialize the file table */
|
|
||||||
DynFree(LoL->f_nodes);
|
|
||||||
LoL->f_nodes = (f_node_ptr)
|
|
||||||
DynAlloc("f_nodes", Config.cfgFiles, sizeof(struct f_node));
|
|
||||||
|
|
||||||
LoL->f_nodes_cnt = Config.cfgFiles; /* and the number of allocated files */
|
|
||||||
|
|
||||||
/* Initialize the base memory pointers from last time. */
|
/* Initialize the base memory pointers from last time. */
|
||||||
/*
|
/*
|
||||||
if the kernel could be moved to HMA, everything behind the dynamic
|
if the kernel could be moved to HMA, everything behind the dynamic
|
||||||
|
@ -488,6 +478,11 @@ void PostConfig(void)
|
||||||
sp->sftt_next = (sfttbl FAR *) - 1;
|
sp->sftt_next = (sfttbl FAR *) - 1;
|
||||||
sp->sftt_count = Config.cfgFiles - 8;
|
sp->sftt_count = Config.cfgFiles - 8;
|
||||||
|
|
||||||
|
/* Initialize the file table */
|
||||||
|
LoL->f_nodes = KernelAlloc(Config.cfgFiles * sizeof(struct f_node), 'F',
|
||||||
|
Config.cfgFilesHigh);
|
||||||
|
LoL->f_nodes_cnt = Config.cfgFiles; /* and the number of allocated files */
|
||||||
|
|
||||||
LoL->CDSp = KernelAlloc(sizeof(struct cds) * LoL->lastdrive, 'L', Config.cfgLastdriveHigh);
|
LoL->CDSp = KernelAlloc(sizeof(struct cds) * LoL->lastdrive, 'L', Config.cfgLastdriveHigh);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
147
kernel/fatfs.c
147
kernel/fatfs.c
|
@ -39,6 +39,7 @@ BYTE *RcsId = "$Id$";
|
||||||
/* */
|
/* */
|
||||||
f_node_ptr xlt_fd(COUNT);
|
f_node_ptr xlt_fd(COUNT);
|
||||||
COUNT xlt_fnp(f_node_ptr);
|
COUNT xlt_fnp(f_node_ptr);
|
||||||
|
STATIC f_node_ptr get_near_f_node(void);
|
||||||
STATIC f_node_ptr split_path(char *, char *);
|
STATIC f_node_ptr split_path(char *, char *);
|
||||||
BOOL find_fname(f_node_ptr, char *, int);
|
BOOL find_fname(f_node_ptr, char *, int);
|
||||||
/* /// Added - Ron Cemer */
|
/* /// Added - Ron Cemer */
|
||||||
|
@ -253,6 +254,7 @@ long dos_open(char *path, unsigned flags, unsigned attrib)
|
||||||
fnp->f_cluster = getdstart(fnp->f_dpb, &fnp->f_dir);
|
fnp->f_cluster = getdstart(fnp->f_dpb, &fnp->f_dir);
|
||||||
fnp->f_cluster_offset = 0;
|
fnp->f_cluster_offset = 0;
|
||||||
|
|
||||||
|
save_far_f_node(fnp);
|
||||||
return xlt_fnp(fnp) | ((long)status << 16);
|
return xlt_fnp(fnp) | ((long)status << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +283,7 @@ COUNT dos_close(COUNT fd)
|
||||||
/* If the fd was invalid because it was out of range or the */
|
/* If the fd was invalid because it was out of range or the */
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return DE_INVLDHNDL;
|
return DE_INVLDHNDL;
|
||||||
|
|
||||||
if (fnp->f_flags.f_dmod)
|
if (fnp->f_flags.f_dmod)
|
||||||
|
@ -310,15 +312,19 @@ COUNT dos_commit(COUNT fd)
|
||||||
/* If the fd was invalid because it was out of range or the */
|
/* If the fd was invalid because it was out of range or the */
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return DE_INVLDHNDL;
|
return DE_INVLDHNDL;
|
||||||
fnp2 = get_f_node();
|
fnp2 = get_f_node();
|
||||||
if (fnp2 == (f_node_ptr) 0)
|
if (fnp2 == (f_node_ptr) 0)
|
||||||
|
{
|
||||||
|
release_near_f_node(fnp);
|
||||||
return DE_INVLDHNDL;
|
return DE_INVLDHNDL;
|
||||||
|
}
|
||||||
|
|
||||||
/* a copy of the fnode is closed meaning that the directory info
|
/* a copy of the fnode is closed meaning that the directory info
|
||||||
is updated etc, but we keep our old info */
|
is updated etc, but we keep our old info */
|
||||||
memcpy(fnp2, fnp, sizeof(*fnp));
|
memcpy(fnp2, fnp, sizeof(*fnp));
|
||||||
|
release_near_f_node(fnp);
|
||||||
return dos_close(xlt_fnp(fnp2));
|
return dos_close(xlt_fnp(fnp2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,15 +464,18 @@ COUNT remove_lfn_entries(f_node_ptr fnp)
|
||||||
STATIC void merge_file_changes(f_node_ptr fnp, int collect)
|
STATIC void merge_file_changes(f_node_ptr fnp, int collect)
|
||||||
{
|
{
|
||||||
f_node_ptr fnp2;
|
f_node_ptr fnp2;
|
||||||
int i;
|
int i, fd;
|
||||||
|
|
||||||
if (!IsShareInstalled())
|
if (!IsShareInstalled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
fd = xlt_fnp(fnp);
|
||||||
|
fnp2 = get_near_f_node();
|
||||||
for (i = 0; i < f_nodes_cnt; i++)
|
for (i = 0; i < f_nodes_cnt; i++)
|
||||||
{
|
{
|
||||||
fnp2 = (f_node_ptr) & f_nodes[i];
|
fmemcpy(fnp2, &f_nodes[i], sizeof(*fnp2));
|
||||||
if ((fnp != (f_node_ptr) 0)
|
if ((fnp != (f_node_ptr) 0)
|
||||||
&& (fnp != fnp2)
|
&& (i != fd)
|
||||||
&& (fnp->f_count > 0) && (is_same_file(fnp, fnp2)))
|
&& (fnp->f_count > 0) && (is_same_file(fnp, fnp2)))
|
||||||
{
|
{
|
||||||
if (collect)
|
if (collect)
|
||||||
|
@ -485,9 +494,11 @@ STATIC void merge_file_changes(f_node_ptr fnp, int collect)
|
||||||
distributing these changes to the other f_nodes
|
distributing these changes to the other f_nodes
|
||||||
which refer to this file. */
|
which refer to this file. */
|
||||||
copy_file_changes(fnp, fnp2);
|
copy_file_changes(fnp, fnp2);
|
||||||
|
fmemcpy(&f_nodes[i], fnp2, sizeof(*fnp2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_near_f_node(fnp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /// Added - Ron Cemer */
|
/* /// Added - Ron Cemer */
|
||||||
|
@ -889,13 +900,14 @@ COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp)
|
||||||
/* If the fd was invalid because it was out of range or the */
|
/* If the fd was invalid because it was out of range or the */
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return DE_INVLDHNDL;
|
return DE_INVLDHNDL;
|
||||||
|
|
||||||
/* Get the date and time from the fnode and return */
|
/* Get the date and time from the fnode and return */
|
||||||
*dp = fnp->f_dir.dir_date;
|
*dp = fnp->f_dir.dir_date;
|
||||||
*tp = fnp->f_dir.dir_time;
|
*tp = fnp->f_dir.dir_time;
|
||||||
|
|
||||||
|
release_near_f_node(fnp);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,7 +925,7 @@ COUNT dos_setftime(COUNT fd, date dp, time tp)
|
||||||
/* If the fd was invalid because it was out of range or the */
|
/* If the fd was invalid because it was out of range or the */
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return DE_INVLDHNDL;
|
return DE_INVLDHNDL;
|
||||||
|
|
||||||
/* Set the date and time from the fnode and return */
|
/* Set the date and time from the fnode and return */
|
||||||
|
@ -922,6 +934,7 @@ COUNT dos_setftime(COUNT fd, date dp, time tp)
|
||||||
fnp->f_flags.f_dmod = TRUE; /* mark file as modified */
|
fnp->f_flags.f_dmod = TRUE; /* mark file as modified */
|
||||||
fnp->f_flags.f_ddate = TRUE; /* set this date upon closing */
|
fnp->f_flags.f_ddate = TRUE; /* set this date upon closing */
|
||||||
|
|
||||||
|
save_far_f_node(fnp);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,10 +952,11 @@ ULONG dos_getfsize(COUNT fd)
|
||||||
/* If the fd was invalid because it was out of range or the */
|
/* If the fd was invalid because it was out of range or the */
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return (ULONG)-1l;
|
return (ULONG)-1l;
|
||||||
|
|
||||||
/* Return the file size */
|
/* Return the file size */
|
||||||
|
release_near_f_node(fnp);
|
||||||
return fnp->f_dir.dir_size;
|
return fnp->f_dir.dir_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,13 +974,14 @@ BOOL dos_setfsize(COUNT fd, LONG size)
|
||||||
/* If the fd was invalid because it was out of range or the */
|
/* If the fd was invalid because it was out of range or the */
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Change the file size */
|
/* Change the file size */
|
||||||
fnp->f_dir.dir_size = size;
|
fnp->f_dir.dir_size = size;
|
||||||
|
|
||||||
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
|
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
|
||||||
|
save_far_f_node(fnp);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1535,7 +1550,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
/* If the fd was invalid because it was out of range or the */
|
/* If the fd was invalid because it was out of range or the */
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1547,8 +1562,11 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
fnp->f_flags.f_ddate = FALSE; /* set date not valid any more */
|
fnp->f_flags.f_ddate = FALSE; /* set date not valid any more */
|
||||||
|
|
||||||
if (dos_extend(fnp) != SUCCESS)
|
if (dos_extend(fnp) != SUCCESS)
|
||||||
|
{
|
||||||
|
save_far_f_node(fnp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Test that we are really about to do a data transfer. If the */
|
/* Test that we are really about to do a data transfer. If the */
|
||||||
/* count is zero and the mode is XFR_READ, just exit. (Any */
|
/* count is zero and the mode is XFR_READ, just exit. (Any */
|
||||||
|
@ -1570,6 +1588,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
fnp->f_dir.dir_size = fnp->f_offset;
|
fnp->f_dir.dir_size = fnp->f_offset;
|
||||||
shrink_file(fnp);
|
shrink_file(fnp);
|
||||||
}
|
}
|
||||||
|
save_far_f_node(fnp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1589,6 +1608,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
/* but only for regular files. */
|
/* but only for regular files. */
|
||||||
if (mode == XFR_READ && !(fnp->f_flags.f_ddir) && (fnp->f_offset >= fnp->f_dir.dir_size))
|
if (mode == XFR_READ && !(fnp->f_flags.f_ddir) && (fnp->f_offset >= fnp->f_dir.dir_size))
|
||||||
{
|
{
|
||||||
|
save_far_f_node(fnp);
|
||||||
return ret_cnt;
|
return ret_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1619,6 +1639,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
#endif
|
#endif
|
||||||
if (map_cluster(fnp, mode) != SUCCESS)
|
if (map_cluster(fnp, mode) != SUCCESS)
|
||||||
{
|
{
|
||||||
|
save_far_f_node(fnp);
|
||||||
return ret_cnt;
|
return ret_cnt;
|
||||||
}
|
}
|
||||||
if (mode == XFR_WRITE)
|
if (mode == XFR_WRITE)
|
||||||
|
@ -1690,6 +1711,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
mode == XFR_READ ? DSKREAD : DSKWRITE))
|
mode == XFR_READ ? DSKREAD : DSKWRITE))
|
||||||
{
|
{
|
||||||
fnp->f_offset = startoffset;
|
fnp->f_offset = startoffset;
|
||||||
|
save_far_f_node(fnp);
|
||||||
return DE_ACCESS;
|
return DE_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1714,6 +1736,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
#endif
|
#endif
|
||||||
if (bp == NULL) /* (struct buffer *)0 --> DS:0 !! */
|
if (bp == NULL) /* (struct buffer *)0 --> DS:0 !! */
|
||||||
{
|
{
|
||||||
|
save_far_f_node(fnp);
|
||||||
return ret_cnt;
|
return ret_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1766,6 +1789,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||||
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
|
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
save_far_f_node(fnp);
|
||||||
return ret_cnt;
|
return ret_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1783,29 +1807,34 @@ LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin)
|
||||||
/* requested file was not open, tell the caller and exit */
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
|
|
||||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return (LONG) DE_INVLDHNDL;
|
return (LONG) DE_INVLDHNDL;
|
||||||
|
|
||||||
/* now do the actual lseek adjustment to the file poitner */
|
/* now do the actual lseek adjustment to the file poitner */
|
||||||
|
|
||||||
switch (origin)
|
switch (origin)
|
||||||
{
|
{
|
||||||
/* offset from beginning of file */
|
/* offset from beginning of file */
|
||||||
case 0:
|
case 0:
|
||||||
return fnp->f_offset = (ULONG) foffset;
|
fnp->f_offset = (ULONG) foffset;
|
||||||
|
break;
|
||||||
|
|
||||||
/* offset from current location */
|
/* offset from current location */
|
||||||
case 1:
|
case 1:
|
||||||
return fnp->f_offset += foffset;
|
fnp->f_offset += foffset;
|
||||||
|
break;
|
||||||
|
|
||||||
/* offset from eof */
|
/* offset from eof */
|
||||||
case 2:
|
case 2:
|
||||||
return fnp->f_offset = fnp->f_dir.dir_size + foffset;
|
fnp->f_offset = fnp->f_dir.dir_size + foffset;
|
||||||
|
break;
|
||||||
|
|
||||||
/* default to an invalid function */
|
/* default to an invalid function */
|
||||||
default:
|
default:
|
||||||
|
release_near_f_node(fnp);
|
||||||
return (LONG) DE_INVLDFUNC;
|
return (LONG) DE_INVLDFUNC;
|
||||||
}
|
}
|
||||||
|
save_far_f_node(fnp);
|
||||||
|
return fnp->f_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns the number of unused clusters */
|
/* returns the number of unused clusters */
|
||||||
|
@ -1867,18 +1896,46 @@ int dos_cd(char * PathName)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* try to allocate a near f_node */
|
||||||
|
/* (there are just two of them, in the SDA) */
|
||||||
|
|
||||||
|
f_node_ptr get_near_f_node(void)
|
||||||
|
{
|
||||||
|
f_node_ptr fnp = fnode;
|
||||||
|
|
||||||
|
if (fnp->f_count == 0)
|
||||||
|
fnp->f_count++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fnp++;
|
||||||
|
if (fnp->f_count == 0)
|
||||||
|
fnp->f_count++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fnp = (f_node_ptr) 0;
|
||||||
|
panic("more than two near fnodes requested at the same time!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fnp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to allocate an f_node from the available files array */
|
/* Try to allocate an f_node from the available files array */
|
||||||
|
|
||||||
f_node_ptr get_f_node(void)
|
f_node_ptr get_f_node(void)
|
||||||
{
|
{
|
||||||
REG int i;
|
REG int i;
|
||||||
|
f_node_ptr fnp = get_near_f_node();
|
||||||
|
|
||||||
|
if (fnp != (f_node_ptr)0)
|
||||||
|
{
|
||||||
for (i = 0; i < f_nodes_cnt; i++)
|
for (i = 0; i < f_nodes_cnt; i++)
|
||||||
{
|
{
|
||||||
if (f_nodes[i].f_count == 0)
|
if (f_nodes[i].f_count == 0)
|
||||||
{
|
{
|
||||||
++f_nodes[i].f_count;
|
++f_nodes[i].f_count;
|
||||||
return &f_nodes[i];
|
fnode_fd[fnp - fnode] = i;
|
||||||
|
return fnp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (f_node_ptr) 0;
|
return (f_node_ptr) 0;
|
||||||
|
@ -1886,10 +1943,13 @@ f_node_ptr get_f_node(void)
|
||||||
|
|
||||||
VOID release_f_node(f_node_ptr fnp)
|
VOID release_f_node(f_node_ptr fnp)
|
||||||
{
|
{
|
||||||
if (fnp->f_count > 0)
|
struct f_node FAR *fp = &f_nodes[xlt_fnp(fnp)];
|
||||||
--fnp->f_count;
|
|
||||||
|
if (fp->f_count > 0)
|
||||||
|
--fp->f_count;
|
||||||
else
|
else
|
||||||
fnp->f_count = 0;
|
fp->f_count = 0;
|
||||||
|
release_near_f_node(fnp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef IPL
|
#ifndef IPL
|
||||||
|
@ -1902,15 +1962,13 @@ COUNT dos_getfattr_fd(COUNT fd)
|
||||||
{
|
{
|
||||||
f_node_ptr fnp = xlt_fd(fd);
|
f_node_ptr fnp = xlt_fd(fd);
|
||||||
|
|
||||||
|
/* If the fd was invalid because it was out of range or the */
|
||||||
|
/* requested file was not open, tell the caller and exit */
|
||||||
/* note: an invalid fd is indicated by a 0 return */
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
if (fnp == (f_node_ptr) 0)
|
if (fnp == (f_node_ptr) 0)
|
||||||
return DE_TOOMANY;
|
return DE_TOOMANY;
|
||||||
|
|
||||||
/* If the fd was invalid because it was out of range or the */
|
release_near_f_node(fnp);
|
||||||
/* requested file was not open, tell the caller and exit */
|
|
||||||
if (fnp->f_count <= 0)
|
|
||||||
return DE_FILENOTFND;
|
|
||||||
|
|
||||||
return fnp->f_dir.dir_attrib;
|
return fnp->f_dir.dir_attrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1950,6 +2008,7 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp)
|
||||||
fnp->f_dir.dir_attrib |= attrp; /* JPP */
|
fnp->f_dir.dir_attrib |= attrp; /* JPP */
|
||||||
fnp->f_flags.f_dmod = TRUE;
|
fnp->f_flags.f_dmod = TRUE;
|
||||||
fnp->f_flags.f_ddate = TRUE;
|
fnp->f_flags.f_ddate = TRUE;
|
||||||
|
save_far_f_node(fnp);
|
||||||
dos_close(fd);
|
dos_close(fd);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2112,16 +2171,42 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* translate the fd into an f_node pointer */
|
|
||||||
f_node_ptr xlt_fd(COUNT fd)
|
|
||||||
{
|
|
||||||
return fd >= f_nodes_cnt ? (f_node_ptr) 0 : &f_nodes[fd];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* translate the f_node pointer into an fd */
|
/* translate the f_node pointer into an fd */
|
||||||
COUNT xlt_fnp(f_node_ptr fnp)
|
COUNT xlt_fnp(f_node_ptr fnp)
|
||||||
{
|
{
|
||||||
return (COUNT) (fnp - f_nodes);
|
return fnode_fd[fnp - fnode];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate a near fnode and copy the far fd fnode to it */
|
||||||
|
f_node_ptr xlt_fd(int fd)
|
||||||
|
{
|
||||||
|
f_node_ptr fnp = (f_node_ptr) 0;
|
||||||
|
|
||||||
|
/* If the fd was invalid because it was out of range or the */
|
||||||
|
/* requested file was not open, tell the caller and exit */
|
||||||
|
/* note: an invalid fd is indicated by a 0 return */
|
||||||
|
if (fd < f_nodes_cnt)
|
||||||
|
{
|
||||||
|
fnp = get_near_f_node();
|
||||||
|
if (fnp != (f_node_ptr)0)
|
||||||
|
{
|
||||||
|
fmemcpy(fnp, &f_nodes[fd], sizeof(*fnp));
|
||||||
|
if (fnp->f_count <= 0)
|
||||||
|
{
|
||||||
|
release_near_f_node(fnp);
|
||||||
|
fnp = (f_node_ptr) 0;
|
||||||
|
} else
|
||||||
|
fnode_fd[fnp - fnode] = fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fnp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy a near fnode to the corresponding far one and release it */
|
||||||
|
void save_far_f_node(f_node_ptr fnp)
|
||||||
|
{
|
||||||
|
fmemcpy(&f_nodes[xlt_fnp(fnp)], fnp, sizeof(*fnp));
|
||||||
|
release_near_f_node(fnp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TE
|
/* TE
|
||||||
|
|
|
@ -349,7 +349,7 @@ GLOBAL WORD dump_regs; /* dump registers of bad call */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern f_node_ptr ASM f_nodes; /* pointer to the array */
|
extern struct f_node FAR * ASM f_nodes; /* pointer to the array */
|
||||||
extern UWORD ASM f_nodes_cnt; /* number of allocated f_nodes */
|
extern UWORD ASM f_nodes_cnt; /* number of allocated f_nodes */
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
@ -436,3 +436,5 @@ void ASMCFUNC spawn_int23(void); /* procsupt.asm */
|
||||||
|
|
||||||
GLOBAL BYTE ReturnAnyDosVersionExpected;
|
GLOBAL BYTE ReturnAnyDosVersionExpected;
|
||||||
|
|
||||||
|
GLOBAL struct f_node fnode[2];
|
||||||
|
GLOBAL int fnode_fd[2];
|
||||||
|
|
|
@ -348,7 +348,7 @@ _rev_number db 0
|
||||||
global _version_flags
|
global _version_flags
|
||||||
_version_flags db 0
|
_version_flags db 0
|
||||||
global _f_nodes
|
global _f_nodes
|
||||||
_f_nodes dw 0
|
_f_nodes dd 0
|
||||||
global _f_nodes_cnt
|
global _f_nodes_cnt
|
||||||
_f_nodes_cnt dw 0
|
_f_nodes_cnt dw 0
|
||||||
global os_release
|
global os_release
|
||||||
|
|
|
@ -177,6 +177,7 @@ int dos_cd(char * PathName);
|
||||||
|
|
||||||
f_node_ptr get_f_node(void);
|
f_node_ptr get_f_node(void);
|
||||||
VOID release_f_node(f_node_ptr fnp);
|
VOID release_f_node(f_node_ptr fnp);
|
||||||
|
#define release_near_f_node(fnp) ((fnp)->f_count = 0)
|
||||||
VOID dos_setdta(BYTE FAR * newdta);
|
VOID dos_setdta(BYTE FAR * newdta);
|
||||||
COUNT dos_getfattr_fd(COUNT fd);
|
COUNT dos_getfattr_fd(COUNT fd);
|
||||||
COUNT dos_getfattr(BYTE * name);
|
COUNT dos_getfattr(BYTE * name);
|
||||||
|
|
Loading…
Reference in New Issue