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 + -
显示快捷键?