file.c

来自「smallbasic for linux」· C语言 代码 · 共 844 行 · 第 1/2 页

C
844
字号
/**	file.c - File system**	History:*	28/02/2001 - ndc - created*/#include "str.h"#include "device.h"#include "pproc.h"#if defined(_PalmOS)	#include <FileStream.h>	#include <SerialMgrOld.h>	#define	idSmBa	0x536D4261	#define	idUFST	0x55465354#else	#include <errno.h>	#if defined(_UnixOS)	#include <sys/time.h>	#include <termios.h>	#endif	typedef int FileHand;#endif#if defined(_PalmOS) || defined(_DOS)#define	MAX_OPEN_FILES	16#else#define	MAX_OPEN_FILES	256#endif// FILE TABLEstatic dev_file_t	file_table[MAX_OPEN_FILES];void	err_unsup() SEC(TRASH);void	err_unsup(){ rt_raise("UNSUPPORTED"); }/* ERROR MESSAGES */void	err_file(dword code)		SEC(TRASH);void	err_file(dword code){	#if defined(_PalmOS)	switch ( code )	{	case	fileErrMemError:		rt_raise("FS: OUT OF MEMORY");		break;	case	fileErrInvalidParam:		rt_raise("FS: INVALID PARAMETER");		break;	case	fileErrCorruptFile:		rt_raise("FS: FILE IS CORRUPTED OR INVALID");		break;	case	fileErrNotFound:		rt_raise("FS: COULDN'T FIND FILE");		break;	case	fileErrTypeCreatorMismatch:		rt_raise("FS: TYPE OR CREATOR NOT WHAT WAS SPECIFIED");		break;	case	fileErrReplaceError:		rt_raise("FS: COULDN'T REPLACE EXISTING FILE");		break;	case	fileErrCreateError:		rt_raise("FS: COULDN'T CREATE NEW FILE");		break;	case	fileErrOpenError:		rt_raise("FS: GENERIC OPEN ERROR");		break;	case	fileErrInUse:		rt_raise("FS: FILE IS IN USE");		break;	case	fileErrReadOnly:		rt_raise("FS: FILE IS READONLY");		break;	case	fileErrInvalidDescriptor:		rt_raise("FS: INVALID FILE HANDLE");		break;	case	fileErrCloseError:		rt_raise("FS: ERROR CLOSING FILE");		break;	case	fileErrOutOfBounds:		rt_raise("FS: PAST END OF FILE");		break;	case	fileErrPermissionDenied:		rt_raise("FS: ACCESS DENIED");		break;	case	fileErrIOError:		rt_raise("FS: GENERIC I/O ERROR");		break;	case	fileErrEOF:		rt_raise("FS: END-OF-FILE ERROR!");		break;	case	fileErrNotStream:		rt_raise("FS: FILE IS NOT A STREAM");		}	#else	char	buf[1024], *p;	strcpy(buf, strerror(code));	p = buf;	while ( *p )	{		*p = to_upper(*p);		p ++;		}	rt_raise("FS(%d): %s", code, buf);	#endif}/**	initialize file system*/int		dev_initfs(){	int		i;	for ( i = 0; i < MAX_OPEN_FILES; i ++ )			file_table[i].handle = (FileHand) -1;	return 1;}/**	cleanup file system*/void	dev_closefs(){	int		i;	for ( i = 0; i < MAX_OPEN_FILES; i ++ )	{		if	( file_table[i].handle != (FileHand) -1 )			dev_fclose(i);		}}/**	returns a free file handle for user's commands*/int		dev_freefilehandle(){	int		i;	for ( i = 0; i < MAX_OPEN_FILES; i ++ )	{		if	( file_table[i].handle == (FileHand) -1 )				return i+1;		// Warning: BASIC's handles starting from 1		}	rt_raise("FS: TOO MANY OPEN FILES");	return -1;}/**/dev_file_t*	dev_getfileptr(int handle){	handle --;				// Warning: BASIC's handles starting from 1	if	( handle < 0 || handle >= MAX_OPEN_FILES )	{		rt_raise("FS: INVALID USER HANDLE");		return NULL;				}	return &file_table[handle];}/**	returns true if the file is opened*/int		dev_fstatus(int handle){	dev_file_t *f;	if	( (f = dev_getfileptr(handle)) == NULL )		return 0;	return (f->handle != (FileHand) -1);}#if defined(_UnixOS) && !defined(_Win32)int		select_unix_serial_speed(int n){	switch ( n )	{	case	300:		return B300;	case	600:		return B600;	case	1200:		return B1200;	case	2400:		return B2400;	case	4800:		return B4800;	case	9600:		return B9600;	case	19200:		return B19200;	case	38400:		return B38400;		}	return B9600;}#endif/**	opens a file**	returns true on success*/int		dev_fopen(int sb_handle, const char *name, int flags){	dev_file_t *f;	int			i;	if	( (f = dev_getfileptr(sb_handle)) == NULL )		return 0;	memset(f, 0, sizeof(dev_file_t));	f->handle = (FileHand) -1;	f->open_flags = flags;	strcpy(f->name, name);	f->type = ft_stream;	// special devices	if	( strchr(f->name, ':') && strlen(f->name) > 4 )	{		for ( i = 0; i < 5; i ++ )			f->name[i] = to_upper(f->name[i]);		if	( strncmp(f->name, "MEMO:", 5) == 0 )			f->type = ft_memo_t;		else if	( strncmp(f->name, "PDOC:", 5) == 0 )			f->type = ft_pdoc_t;		else if	( strncmp(f->name, "COM1:", 5) == 0 )	{			f->type = ft_serial_port1;			f->port = 0;			if	( strlen(f->name) > 5 )				f->devspeed = xstrtol(f->name+5);			else				f->devspeed = 9600;			#if defined(_UnixOS) && !defined(_Win32)			f->devspeed = select_unix_serial_speed(f->devspeed);			#endif			}		else if	( strncmp(f->name, "COM2:", 5) == 0 )	{			f->type = ft_serial_port2;			f->port = 1;			if	( strlen(f->name) > 5 )				f->devspeed = xstrtol(name+5);			else				f->devspeed = 9600;			#if defined(_UnixOS) && !defined(_Win32)			f->devspeed = select_unix_serial_speed(f->devspeed);			#endif			}		else if	( strncmp(f->name, "IRDA:", 5) == 0 )			f->type = ft_irda_port;		} // device	#if defined(_PalmOS)	{		dword	osflags;		switch ( f->type )	{		case	ft_stream:			//////////////////////////////////////////////////////////			//			//	PALMOS: SERIAL FILE OPEN			//			osflags = fileModeAnyTypeCreator;				if	( flags == DEV_FILE_OUTPUT )	{				if	( DmFindDatabase(0, (char*) name) != 0 )					FileDelete(0, (char*) name);				}			if	( flags & DEV_FILE_APPEND )					osflags |= fileModeAppend;			else if	( flags & DEV_FILE_OUTPUT )				 	osflags |= fileModeReadWrite;			else if	( flags & DEV_FILE_INPUT )				 	osflags |= fileModeReadOnly;			else			 	osflags |= (fileModeReadWrite | fileModeDontOverwrite);			if	( flags & DEV_FILE_EXCL )				osflags |= fileModeExclusive;			f->handle = FileOpen(0, (char *) name, idUFST, idSmBa, osflags, &f->last_error);			if	( f->last_error )				err_file(f->last_error);			break;		case	ft_serial_port2:		case	ft_serial_port1:			//////////////////////////////////////////////////////////			//			//	PALMOS: SERIAL PORT			//			SysLibFind("Serial Library", &f->libHandle);			f->last_error = SerOpen(f->libHandle, f->port, f->devspeed);			f->handle = (FileHand) 1;			if	( f->last_error )				rt_raise("SEROPEN() ERROR %d", f->last_error);						break;		default:			err_unsup();			}		return (f->last_error == 0);	}	#else	{		int		osflags, osshare;		#if defined(_Win32)		osflags = O_BINARY;		#else		osflags = 0;		#endif		switch ( f->type )	{		#if !defined(_Win32) && defined(_UnixOS)		//////////////////////////////////////////////////////////		//		//	UNIX: SERIAL PORT		//		case	ft_serial_port2:			if	( f->type == ft_serial_port2 )				strcpy(f->name, "/dev/ttyS1");		case	ft_serial_port1:			if	( f->type == ft_serial_port1 )				strcpy(f->name, "/dev/ttyS0");			f->handle = open(f->name, O_RDWR | O_NOCTTY);			if	( f->handle < 0 )					err_file((f->last_error = errno));			tcgetattr(f->handle, &f->oldtio); /* save current port settings */			bzero(&f->newtio, sizeof(f->newtio));			f->newtio.c_cflag = f->devspeed | CRTSCTS | CS8 | CLOCAL | CREAD;	        f->newtio.c_iflag = IGNPAR;	        f->newtio.c_oflag = 0;	        /* set input mode (non-canonical, no echo,...) */			f->newtio.c_lflag = 0;			f->newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */			f->newtio.c_cc[VMIN]     = 1;   /* blocking read until 1 char received */			tcflush(f->handle, TCIFLUSH);			tcsetattr(f->handle, TCSANOW, &f->newtio);			break;		#endif		//////////////////////////////////////////////////////////		//		//	C: SERIAL FILE OPEN		//		case	ft_stream:			if	( flags == DEV_FILE_OUTPUT )					remove(name);			if	( flags & DEV_FILE_EXCL )				osshare = 0;			else				osshare = S_IREAD|S_IWRITE;			osflags |= O_RDWR;				// there is no reason to use O_RDONLY or O_WRONLY (warning: bcc changes the file attributes on O_RDONLY)			if	( flags & DEV_FILE_OUTPUT )				osflags |= O_CREAT;			if	( flags & DEV_FILE_APPEND )					osflags |= O_APPEND;			f->handle = open(name, osflags, osshare);			if	( f->handle < 0 )					err_file((f->last_error = errno));			break;		default:			err_unsup();			};	}	return (f->handle >= 0);	#endif}/**	returns true on success*/int		dev_fclose(int sb_handle){	dev_file_t *f;	if	( (f = dev_getfileptr(sb_handle)) == NULL )		return 0;#if defined(_PalmOS)	switch ( f->type )	{	case	ft_stream:		f->last_error = FileClose(f->handle);		f->handle = (FileHand) -1;		if	( f->last_error )			err_file(f->last_error);		break;	case	ft_serial_port2:	case	ft_serial_port1:		f->last_error = SerClose(f->libHandle);		f->handle = (FileHand) -1;		if	( f->last_error )			rt_raise("SERCLOSE() ERROR %d", f->last_error);		break;	default:		err_unsup();		};	return (f->last_error == 0);#else	switch ( f->type )	{	#if !defined(_Win32) && defined(_UnixOS)	case	ft_serial_port2:	case	ft_serial_port1:		tcsetattr(f->handle, TCSANOW, &f->oldtio);		close(f->handle);

⌨️ 快捷键说明

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