📄 api.c
字号:
/***************************************************************************
PC_MKDIR - Create a directory.
Description
Create a sudirectory in the path specified by name. Fails if a
file or directory of the same name already exists or if the path
is not found.
Returns
Returns TRUE if it was able to create the directory, otherwise
it returns FALSE.
If pc_mkdir fails, xn_getlasterror() will be set to one of the following:
PENOENT - path to new directory not found
PEEXIST - File or Dir already exists by this name.
PENOSPC - Drectory create failed
****************************************************************************/
BOOLEAN pc_mkdir(char *name) /*__fn__*/
{
DROBJ *pobj;
DROBJ *parent_obj;
char path[EMAXPATH];
char filename[FILENAMESIZE]; /* VFAT */
char fileext[4];
BOOLEAN ret_val;
int driveno;
int p_errno;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
OS_FS_ENTER()
ret_val = FALSE;
parent_obj = 0;
pobj = 0;
p_errno = PENOENT;
/* Get the drive and make sure it is mounted */
driveno = check_drive(name);
if (driveno < 0)
{
OS_FS_EXIT()
return(FALSE);
}
OS_CLAIM_LOGDRIVE(driveno) /* Register drive in use */
/* Get out the filename and d:parent */
if (!pc_parsepath(path,filename,fileext,name))
goto errex;
#if (VFAT)
if (!validate_filename(filename, tc_strlen(filename)))
goto errex;
#else
if (!validate_filename(filename, 8))
goto errex;
if (!validate_filename(fileext, 3))
goto errex;
#endif
/* Find the parent and make sure it is a directory \ */
parent_obj = pc_fndnode(path);
if (!parent_obj)
goto errex;
/* Lock the parent */
if (!pc_isadir(parent_obj) || pc_isavol(parent_obj))
goto errex;
/* Fail if the directory exists */
pobj = pc_get_inode(0, parent_obj, (byte*)filename,(byte*) fileext, FALSE);
if (pobj)
{
p_errno = PEEXIST; /* Exclusive fail */
}
else
{
pobj = pc_mknode( parent_obj, filename, fileext, ADIRENT);
if (pobj)
{
p_errno = 0;
ret_val = TRUE;
}
else
{
p_errno = PENOSPC;
goto errex;
}
}
errex:
if (pobj)
pc_freeobj(pobj);
if (parent_obj)
{
pc_freeobj(parent_obj);
}
OS_RELEASE_LOGDRIVE(driveno)
/* Restore the kernel state */
set_errno(p_errno);
OS_FS_EXIT()
return(ret_val);
}
#endif /* Subdirs */
#endif /* Write */
RTFS_FILE(open.c, po_open)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/****************************************************************************
PO_OPEN - Open a file.
Description
Open the file for access as specified in flag. If creating use mode to
set the access permissions on the file.
Flag values are
PO_BINARY - Ignored. All file access is binary
PO_char - Ignored
PO_RDONLY - Open for read only
PO_RDWR - Read/write access allowed.
PO_WRONLY - Open for write only
PO_CREAT - Create the file if it does not exist. Use mode to
specify the permission on the file.
PO_EXCL - If flag contains (PO_CREAT | PO_EXCL) and the file already
exists fail and set xn_getlasterror() to EEXIST
PO_TRUNC - Truncate the file if it already exists
PO_NOSHAREANY - Fail if the file is already open. If the open succeeds
no other opens will succeed until it is closed.
PO_NOSHAREWRITE- Fail if the file is already open for write. If the open
succeeds no other opens for write will succeed until it
is closed.
Mode values are
PS_IWRITE - Write permitted
PS_IREAD - Read permitted. (Always true anyway)
Returns
Returns a non-negative integer to be used as a file descriptor for
calling read/write/seek/close otherwise it returns -1 and xn_getlasterror() is set to
one of these values
PENOENT - File not found or path to file not found
PEMFILE - No file descriptors available (too many files open)
PEEXIST - Exclusive access requested but file already exists.
PEACCESS - Attempt to open a read only file or a special (directory)
file.
PENOSPC - Create failed
PESHARE - Already open in exclusive mode or we want exclusive
and its already open
****************************************************************************/
PCFD po_open(char *name, word flag, word mode) /*__fn__*/
{
PCFD fd;
PC_FILE *pfile;
CLUSTERTYPE cluster; /* FAT32 */
DROBJ *parent_obj;
DROBJ *pobj;
char path[EMAXPATH];
char filename[FILENAMESIZE]; /* VFAT */
char fileext[4];
int driveno;
BOOLEAN open_for_write;
#if (RTFS_SHARE)
BOOLEAN sharing_error;
#endif
dword ltemp;
int p_errno;
CHECK_MEM(PCFD, -1) /* Make sure memory is initted */
OS_FS_ENTER()
#if (RTFS_SHARE)
sharing_error = FALSE;
#endif
parent_obj = 0;
open_for_write = FALSE;
#if (RTFS_WRITE)
/* We'll need to know this in a few places. */
if(flag & (PO_WRONLY|PO_RDWR))
open_for_write = TRUE;
#endif
/* Get the drive and make sure it is mounted */
driveno = check_drive(name);
if (driveno < 0)
{
OS_FS_EXIT()
return(-1);
}
if ( (fd = pc_allocfile()) < 0 ) /* Grab a file */
{
p_errno = PEMFILE;
goto errex1;
}
/* Get the FILE. This will never fail */
pfile = pc_fd2file(fd, 0);
/* Paranoia. Set the obj to null until we have one */
pfile->pobj = 0;
OS_CLAIM_LOGDRIVE(driveno) /* Register drive in use */
p_errno = PENOENT;
/* Get out the filename and d:parent */
if (!pc_parsepath(path,filename,fileext,name))
goto errex;
#if (VFAT)
if (!validate_filename(filename, tc_strlen(filename)))
goto errex;
#else
if (!validate_filename(filename, 8))
goto errex;
if (!validate_filename(fileext, 3))
goto errex;
#endif
/* Find the parent */
parent_obj = pc_fndnode(path);
if (!parent_obj)
goto errex;
if (!pc_isadir(parent_obj) || pc_isavol(parent_obj))
goto errex;
pobj = pc_get_inode(0, parent_obj,(byte*)filename,(byte*)fileext, FALSE);
if (pobj)
{
/* If we goto exit: we want them linked so we can clean up */
pfile->pobj = pobj; /* Link the file to the object */
#if (RTFS_SHARE)
/* check the sharing conditions */
sharing_error = FALSE;
if (pobj->finode->opencount != 1)
{
/* The file is already open by someone. Lets see if we are
compatible */
/* 1. We don't want to share with anyone */
if (flag & PO_NOSHAREANY)
sharing_error = TRUE;
/* 2. Someone else doesn't want to share */
if (pobj->finode->openflags & OF_EXCLUSIVE)
sharing_error = TRUE;
/* 3. We want exclusive write but already open for write */
if ( open_for_write && (flag & PO_NOSHAREWRITE) &&
(pobj->finode->openflags & OF_WRITE))
sharing_error = TRUE;
/* 4. We want open for write but it's already open for
exclusive */
if ( (open_for_write) &&
(pobj->finode->openflags & OF_WRITEEXCLUSIVE))
sharing_error = TRUE;
/* 5. Open for trunc when already open */
if (flag & PO_TRUNC)
sharing_error = TRUE;
}
if (sharing_error)
{
p_errno = PESHARE;
goto errex;
}
#endif /* RTFS_SHARE */
if( pc_isadir(pobj) || pc_isavol(pobj) )
{
p_errno = PEACCES; /* is a directory */
goto errex;
}
#if (RTFS_WRITE)
if ( (flag & (PO_EXCL|PO_CREAT)) == (PO_EXCL|PO_CREAT) )
{
p_errno = PEEXIST; /* Exclusive fail */
goto errex;
}
if(open_for_write && (pobj->finode->fattribute & ARDONLY) )
{
p_errno = PEACCES; /* read only file */
goto errex;
}
if (flag & PO_TRUNC)
{
cluster = pc_finode_cluster(pobj->pdrive,pobj->finode); /* FAT32 */
ltemp = pobj->finode->fsize;
pc_pfinode_cluster(pobj->pdrive,pobj->finode,0); /* FAT32 */
pobj->finode->fsize = 0L;
/* Convert to native. Overwrite the existing inode.Set archive/date */
/* Bug fix was:
if (!pc_update_inode(pobj, TRUE, TRUE))
*/
if (pc_update_inode(pobj, TRUE, TRUE))
{
/* And clear up the space */
pc_freechain(pobj->pdrive,cluster);
pc_flushfat(pobj->pdrive->driveno);
}
else
{
pc_pfinode_cluster(pobj->pdrive,pobj->finode,cluster); /* FAT32 */
pobj->finode->fsize = ltemp;
p_errno = PEACCES;
goto errex;
}
}
#endif
}
else /* File not found */
{
#if (RTFS_WRITE)
if (!(flag & PO_CREAT))
{
p_errno = PENOENT; /* File does not exist */
goto errex;
}
/* Do not allow create if write bits not set */
if(!open_for_write)
{
p_errno = PEACCES; /* read only file */
goto errex;
}
/* Create for read only if write perm not allowed */
pobj = pc_mknode( parent_obj, filename, fileext, (byte) ((mode == PS_IREAD) ? ARDONLY : 0));
if (!pobj)
{
p_errno = PENOSPC;
goto errex;
}
pfile->pobj = pobj; /* Link the file to the object */
#else /* Write not built in. Get out */
p_errno = PENOENT; /* File does not exist */
goto errex;
#endif
}
/* Set the file sharing flags in the shared finode structure */
/* clear flags if we just opened it . */
if (pobj->finode->opencount == 1)
pobj->finode->openflags = 0;
#if (RTFS_WRITE)
if (open_for_write)
{
pobj->finode->openflags |= OF_WRITE;
if (flag & PO_NOSHAREWRITE)
pobj->finode->openflags |= OF_WRITEEXCLUSIVE;
}
if (flag & PO_NOSHAREANY)
pobj->finode->openflags |= OF_EXCLUSIVE;
#endif
pfile->flag = flag; /* Access flags */
pfile->fptr = 0L; /* File pointer */
/* Set the cluster and block file pointers */
_synch_file_ptrs(pfile);
p_errno = 0;
if (parent_obj)
{
pc_freeobj(parent_obj);
}
OS_RELEASE_LOGDRIVE(driveno)
/* Restore the kernel state */
set_errno(p_errno);
OS_FS_EXIT()
return(fd);
errex:
pc_freefile(fd);
if (parent_obj)
{
pc_freeobj(parent_obj);
}
OS_RELEASE_LOGDRIVE(driveno)
errex1:
/* Restore the kernel state */
set_errno(p_errno);
OS_FS_EXIT()
return(-1);
}
RTFS_FILE(read.c, po_read)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -