⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fio.c

📁 嵌入式系统中文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*************************************************************
File Name: FIO.C (RAMDisk 4.1)				     *
**************************************************************
Programmer: MSC
Last Modified Date: 2000/02/26
Compiler : GNU Cross-compiler/SDS
Platform : X86 protection mode, MIPS, Dragonball
Usage :
*************************************************************/

/*************************************************************
                      History
**************************************************************/
/*
 * Version: 4.1
 * Date 2000/10/30
 *
 */

/*************************************************************
                      Global Definitions
**************************************************************/

/*************************************************************
 		  	Header Files
**************************************************************/
#include <sys/syscall.h>

//#include <ansi_c/stdio.h>
#include <stdio.h>

// added by chilong 03/07/2002
#include <time.h>

//#include "myansi.h"
#include <ramdisk.h>
#include <dskblk.h>
#include "..\..\FileSys\include\FileSys.h"

// added by chilong 01/31/2002
//#include "piece.h"

#ifdef RAMDISK_ID



/*************************************************************
			Global Variables
   Notes : 1.	To be thread safe, global variables had better
		not be changed once assigned
           2. 	Global variables are for convenient use,
		eliminating the passing of many common
		parameters
           3. 	Global variables should be used as less as
		possible, and any modification on global
		variables should be marked as side-effect in
		function descriptions
**************************************************************/
struct RD_FILE **RD_HandleTable;

#ifdef CURRENT_DIR_ENABLE
	unsigned char RD_CurrentPathname[MAX_PATH_LENGTH];
#endif


/* basic.c */
extern int		InitRD;
//extern int		RDerrno;

extern void		*RD_BootBegin;


extern unsigned long 	RD_DiskSize;

extern int		RD_SemaphoreID;

#ifdef RAMDISK_DEBUG
	extern int	RDOutput;
#endif

/* dskblk.c */
extern struct diskBlock *RD_FirstFreeBlock;

/* piece.c */
extern void **RD_PLT;
extern unsigned long RDPieceSize;

/*======================[ Functions ]========================*/
extern void memoryCopy(void *source, void *dest, unsigned int size);
extern void memoryZero(void *source, unsigned int size);
extern struct dLinkList *tcbSearch(int searchID);

/*************************************************************
Function: RD_open
Description:
	Open a file, it will:
	(1) Construct a file structure
	(2) Set up an file table entry pointing to the above
	structure
Input:
	filename: may contains directories in path flag:
        flag: /Open Only/Create/Truncate/Append
Output:
	file handle is returned
	-1 if the file is not exist, and O_CREATE flag is not set
**************************************************************/
int RD_open(unsigned char *string, int flag)
{
  int fd;
#ifdef RAMDISK_DEBUG
  char tempString[80];
#endif

  if (InitRD == FALSE)
  {
	RDerrno = ERROR_FILE_SYSTEM_NOT_INIT;
	return -1;
  }

#ifdef RAMDISK_DEBUG
  if (RDOutput == TO_SERIAL_PORT)
  {
	sprintf(tempString, "opening %s", string);
	SprintStringLn(tempString);
  }
#endif

  RDerrno = 0;

  if (myStrLen(string) >= MAX_PATH_LENGTH)
  {
	RDerrno = ERROR_PATHNAME_TOO_LONG;

#ifdef RAMDISK_DEBUG
	if (RDOutput == TO_SERIAL_PORT)
	{
		sprintf(tempString, "Failed: %x", RDerrno);
		SprintStringLn(tempString);
	}
#endif

	return -1;
  }

  if (sc_waitSemaphore(RD_SemaphoreID) == -1)
  {
	RDerrno = ERROR_WAIT_SEMAPHORE;

#ifdef RAMDISK_DEBUG
	if (RDOutput == TO_SERIAL_PORT)
	{
		sprintf(tempString, "Failed: %x", RDerrno);
		SprintStringLn(tempString);
	}
#endif

	return -1;
  }

  fd = RD_open_r(string, flag);

#ifdef RAMDISK_STAT_LOG
  if (fd != -1)
  {
	struct signature *boot = (struct signature *)RD_BootBegin;

	boot->openCount++;
  }
#endif

  if (sc_signalSemaphore(RD_SemaphoreID) == -1)
  {
	RDerrno = ERROR_SIGNAL_SEMAPHORE;

#ifdef RAMDISK_DEBUG
	if (RDOutput == TO_SERIAL_PORT)
	{
		sprintf(tempString, "Failed: %x", RDerrno);
		SprintStringLn(tempString);
	}
#endif

	if (fd != -1)
		RD_close(fd);
	return -1;
  }

#ifdef RAMDISK_DEBUG
  if (RDOutput == TO_SERIAL_PORT)
  {
	sprintf(tempString, "handle: %d", fd);
	SprintStringLn(tempString);
  }
#endif

  return fd;
}


int RD_open_r(unsigned char *string, int flag)
{
  struct RD_FILE 	*pfile;
  int 			result;
  int 			availHandler;
  unsigned char		attrib;
#ifdef CURRENT_DIR_ENABLE
  unsigned char		*completeName = NULL;
#endif
#ifdef RAMDISK_DEBUG
  char tempString[80];
#endif

#ifdef CURRENT_DIR_ENABLE

  completeName = (unsigned char *)ap_malloc(MAX_PATH_LENGTH);
  if (completeName == NULL)
  {
	RDerrno = ERROR_ALLOC_MEM;
	return -1;
  }

  // get the complete pathname
  if (RD_getCompletePathname(string, completeName) == -1)
  {
	ap_free(completeName);

#ifdef RAMDISK_DEBUG
	if (RDOutput == TO_SERIAL_PORT)
	{
		sprintf(tempString, "Failed1: %x", RDerrno);
		SprintStringLn(tempString);
	}
#endif

	return -1;
  }

  string = completeName;
#endif

  // initialize the file's structure
  pfile = (struct RD_FILE *)ap_malloc(sizeof(struct RD_FILE));
  if (pfile == NULL)
  {
#ifdef CURRENT_DIR_ENABLE
	ap_free(completeName);
#endif
	RDerrno = ERROR_ALLOC_MEM;

#ifdef RAMDISK_DEBUG
	if (RDOutput == TO_SERIAL_PORT)
	{
		sprintf(tempString, "Failed2: %x", RDerrno);
		SprintStringLn(tempString);
	}
#endif

	return -1;
  }
  memoryZero((void *)pfile, (unsigned int)sizeof(struct RD_FILE));

  availHandler			= findFreeHandle();
  pfile->fhandle		= availHandler;
  RD_HandleTable[availHandler] 	= pfile;

  if (availHandler == -1)
  {
	ap_free(pfile);

#ifdef CURRENT_DIR_ENABLE
	ap_free(completeName);
#endif
	RDerrno = ERROR_NO_HANDLE_AVAIL;

#ifdef RAMDISK_DEBUG
	if (RDOutput == TO_SERIAL_PORT)
	{
		sprintf(tempString, "Failed3: %x", RDerrno);
		SprintStringLn(tempString);
	}
#endif

	return -1;
  }

  result = RD_f_search(pfile, string);

  pfile->fileFlag = flag;
  
  // If the file does not exist, create it if O_CREATE is set
  if (result == -1)
  {
	if ((flag & O_CREATE) != O_CREATE)
	{
		// file not found and the O_CREATE flag is off
		ap_free(pfile);

#ifdef CURRENT_DIR_ENABLE
		ap_free(completeName);
#endif

		RD_HandleTable[availHandler] = NULL;

#ifdef RAMDISK_DEBUG
		if (RDOutput == TO_SERIAL_PORT)
		{
			sprintf(tempString, "Failed4: %x", RDerrno);
			SprintStringLn(tempString);
		}
#endif

		return -1;
	}
	else
	{
		attrib = DA_ARCHIVE;

#ifdef RAMDISK_COMPRESS_USE_ZLIB
		if ((flag & O_COMPRESS) == O_COMPRESS)
			attrib |= DA_COMPRESS;
#endif

		result = RD_f_create(pfile, string, attrib);

		if (result == -1)
		{
			ap_free(pfile);

#ifdef CURRENT_DIR_ENABLE
			ap_free(completeName);
#endif

			RD_HandleTable[availHandler] = NULL;

#ifdef RAMDISK_DEBUG
			if (RDOutput == TO_SERIAL_PORT)
			{
				sprintf(tempString, "Failed5: %x", RDerrno);
				SprintStringLn(tempString);
			}
#endif

			return -1;
		}
	}
  }
  else
  {
	// name found, check if it is a file
	if (((pfile->dirEntry)->attribute & DA_DIR) == DA_DIR)
	{
		// this is a directory, cannot open
		RDerrno = ERROR_DIR_ALREADY_EXIST;

		ap_free(pfile);

#ifdef CURRENT_DIR_ENABLE
		ap_free(completeName);
#endif

		RD_HandleTable[availHandler] = NULL;

#ifdef RAMDISK_DEBUG
		if (RDOutput == TO_SERIAL_PORT)
		{
			sprintf(tempString, "Failed6: %x", RDerrno);
			SprintStringLn(tempString);
		}
#endif

		return -1;
	}

	// file found, open it
	if ((flag & O_TRUNC) == O_TRUNC)
	{
		// truncate the file
		(pfile->dirEntry)->fsize = 0;

		RD_freeCurrentBlocks((pfile->dirEntry)->startBlock);

		RD_freeBlockLink((pfile->dirEntry)->startBlock);

		(pfile->dirEntry)->startBlock = NULL;
	}
	else if ((flag & O_APPEND) == O_APPEND)
		pfile->fpos = (pfile->dirEntry)->fsize;
  }

  pfile->deviceID = RAMDISK_ID;
  pfile->currentBlock = NULL;
  pfile->ownerID = sc_getThreadID();

  pfile->fDupFromHandle = -1;
  
#ifdef CURRENT_DIR_ENABLE
  ap_free(completeName);
#endif


  return(availHandler);
  
}



/*************************************************************
Function: RD_close
Description:
	Close a file specified by the file handle
Input:
	file handle
Output:
	0:  Success
	-1: Failure
**************************************************************/
int RD_close(int fHandle)
{
  int ret;
#ifdef RAMDISK_DEBUG
  char tempString[80];
#endif

  if (InitRD == FALSE)
  {
	RDerrno = ERROR_FILE_SYSTEM_NOT_INIT;
	return -1;
  }

  RDerrno = 0;

#ifdef RAMDISK_DEBUG
  if (RDOutput == TO_SERIAL_PORT)
  {
	struct directory *dirEntry;

	if (RD_HandleTable[fHandle]->deviceID == RAMDISK_ID)
	{
		dirEntry = RD_HandleTable[fHandle]->dirEntry;
		sprintf(tempString, "closing %d [%s]", fHandle, dirEntry->name);
		SprintStringLn(tempString);
	}
	else
	{
		sprintf(tempString, "Wrong device (handle %d)", fHandle);
		SprintStringLn(tempString);
	} 
  }
#endif

  if ((fHandle < 0) || (fHandle >= MAX_OPEN_FILE) || (RD_HandleTable[fHandle] == NULL))
  {
	RDerrno = ERROR_INVALID_HANDLE;
	return -1;
  }

  if (RD_HandleTable[fHandle]->deviceID != RAMDISK_ID)
  {
	RDerrno = ERROR_INVALID_DEVICE;
	return -1;
  }

  if (sc_waitSemaphore(RD_SemaphoreID) == -1)
  {
	RDerrno = ERROR_WAIT_SEMAPHORE;
	return -1;
  }

  ret = RD_close_r(RD_HandleTable[fHandle]);

  RD_HandleTable[fHandle] = NULL;

#ifdef RAMDISK_STAT_LOG
  if (ret != -1)
  {
	struct signature *boot = (struct signature *)RD_BootBegin;

	boot->closeCount++;
  }
#endif

  if (sc_signalSemaphore(RD_SemaphoreID) == -1)
  {
	RDerrno = ERROR_SIGNAL_SEMAPHORE;
	return -1;
  }

  return ret;
}

int
RD_close_r(struct RD_FILE *pfile)
{

#ifdef RAMDISK_COMPRESS_USE_ZLIB
  if (pfile->currentBlock != NULL)
  {
	compressCurrentBlock(pfile);
	// one less file handle is using this block
	(pfile->currentBlock)->userCount--;
  }
#endif

  ap_free(pfile);

  return 0;
}



#ifdef RAMDISK_COMPRESS_USE_ZLIB
/*************************************************************
Function: compressCurrentBlock
Description:
	Compress the current block of a file handle
Input:
	file handle
Output:
	0:  Success
	-1: Failure
**************************************************************/
int compressCurrentBlock(struct RD_FILE *pfile)
{
  int *src;
//  int *des;
  int *buf;
  struct diskBlock *curBlock;
  struct diskBlock *newBlock;
  unsigned long loop;
  long newSize;
  int i;
  sysTime now;
  int returnValue = 0;

  curBlock = pfile->currentBlock;

  // check if the current block should be compressed

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -