rtsysutl.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 615 行 · 第 1/2 页
C
615 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: system dependent I/O support.
*
****************************************************************************/
#include "ftnstd.h"
#include "rundat.h"
#include "errcod.h"
#include "sdfile.h"
#include "units.h"
#include "fio.h"
#include "posio.h"
#include "fapptype.h"
#include "rmemmgr.h"
#include <string.h>
#include <ctype.h>
#include <errno.h>
#if defined( __IS_WINDOWED__ )
#ifndef __SW_BW
#define __SW_BW
#include <wdefwin.h>
#undef __SW_BW
#else
#include <wdefwin.h>
#endif
#endif
extern void ChkIOErr(ftnfile *);
extern bool GetIOErr(ftnfile *);
extern void SetEOF(void);
extern char *JmpBlanks(char *);
extern void IOErr(int,...);
extern file_handle Openf(char *,int);
extern void Closef(file_handle);
extern void FPutRec(file_handle,char *,int);
extern int FGetRec(file_handle,char *,int);
extern void FSeekRec(file_handle,unsigned_32,int);
extern void Scratchf(char *);
extern int Errorf(file_handle);
extern void FSetErr(int,file_handle);
extern void FSetSysErr(file_handle);
extern void FSetEof(file_handle);
extern void IOOk(file_handle);
extern char *ErrorMsg(file_handle);
extern void FTruncate(file_handle);
extern void FBackspace(file_handle,int);
extern void FRewind(file_handle);
extern char GetStdChar(void);
extern void SetIOBufferSize(uint);
extern int FlushBuffer(file_handle);
extern int FSkipLogical(file_handle);
extern int FCheckLogical(file_handle);
extern file_handle FStdIn;
extern file_handle FStdOut;
extern file_handle FStdErr;
#define SYS_DFLT_RECSIZE 1024;
#define INFO_DEV 0x80 // indicates file is a device
#define INFO_VALID_DRIVE 0x40 // indicates valid drive letter
#define INFO_DRIVE 0x3f // mask for drive number
void GetSysIOInfo( ftnfile *fcb ) {
//====================================
// Get system file information for an open file.
SysIOInfo( fcb );
// if standard output device is carriage control (/cc option)
if( fcb->cctrl == CC_YES ) {
((a_file *)(fcb->fileptr))->attrs |= CARRIAGE_CONTROL;
}
}
void GetSysFileInfo( ftnfile *fcb ) {
//======================================
// Get system file information for a file name.
if( access( fcb->filename, F_OK ) == 0 ) {
fcb->flags |= FTN_FSEXIST;
} else {
fcb->flags &= ~FTN_FSEXIST;
}
SysIOInfo( fcb );
}
bool IsDevice( ftnfile *fcb ) {
//================================
// Make sure that the file is a disk file.
return( ( fcb->device & INFO_DEV ) != 0 );
}
static char *GetSysName( ftnfile *fcb ) {
//===========================================
// Return a system file name given a user name and a file structure.
char buff[MAX_FILE];
char *p;
#if defined( __DOS__ ) || defined( __WINDOWS__ ) || (defined( __OS2__ ) && defined( M_I86 ))
p = JmpBlanks( fcb->filename );
if( IsDevice( fcb ) ) {
strcpy( buff, p );
} else
#endif
{
p = _fullpath( buff, fcb->filename, MAX_FILE );
}
if( p != NULL ) {
p = RMemAlloc( strlen( buff ) + sizeof( char ) );
strcpy( p, buff );
}
return( p );
}
static void SysIOInfo( ftnfile *fcb ) {
//=========================================
// Get system file information.
struct stat info;
char *sys_name;
bool exist = TRUE;
if( fcb->bufflen == 0 ) {
fcb->bufflen = SYS_DFLT_RECSIZE;
}
if( fcb->blocksize == 0 ) {
fcb->blocksize = IO_BUFFER;
}
fcb->device = 0;
if( fcb->fileptr != NULL ) { // file is open
#if defined( __NETWARE__ )
if( ( ((a_file *)(fcb->fileptr))->handle == STDIN_FILENO ) ||
( ((a_file *)(fcb->fileptr))->handle == STDOUT_FILENO ) ||
( ((a_file *)(fcb->fileptr))->handle == STDERR_FILENO ) ) {
fcb->device |= INFO_DEV;
} else {
#endif
// for stdin, don't use file name "CON" since information will always
// indicate it's a device even if stdin is redirected
if( fstat( ((a_file *)(fcb->fileptr))->handle, &info ) == -1 ) {
FSetSysErr( fcb->fileptr );
IOErr( IO_FILE_PROBLEM );
return;
}
if( S_ISCHR( info.st_mode ) ) {
fcb->device |= INFO_DEV;
#if defined( __DOS__ ) || defined( __WINDOWS__ )
} else {
fcb->device |= INFO_VALID_DRIVE;
#endif
}
#if defined( __NETWARE__ )
}
#endif
} else {
if( stat( fcb->filename, &info ) == -1 ) {
// if we are trying to open a file in a non-existent
// directory we don't want to issue an error
if( fcb->flags & FTN_FSEXIST ) {
FSetSysErr( fcb->fileptr );
IOErr( IO_FILE_PROBLEM );
return;
}
exist = FALSE;
} else if( S_ISCHR( info.st_mode ) ) {
fcb->device |= INFO_DEV;
// devices always exist
fcb->flags |= FTN_FSEXIST;
#if !defined( __UNIX__ )
} else {
fcb->device |= INFO_VALID_DRIVE;
#endif
}
}
if( ( fcb->flags & FTN_FSEXIST ) && !IsDevice( fcb ) ) {
#if !defined( __UNIX__ )
// Assume the two most significant bits contain no useful information
fcb->device = INFO_DRIVE & info.st_dev; // save drive letter
#endif
if( ( info.st_mode & S_IRUSR ) && ( info.st_mode & S_IWUSR ) ) {
fcb->action = ACTION_RW;
} else if( info.st_mode & S_IRUSR ) {
fcb->action = ACTION_READ;
} else if( info.st_mode & S_IWUSR ) {
fcb->action = ACTION_WRITE;
} else {
// if none of the above are set,
// assume read/write
fcb->action = ACTION_RW;
}
}
sys_name = GetSysName( fcb );
if( sys_name == NULL ) {
if( exist ) {
FSetSysErr( fcb->fileptr );
IOErr( IO_FILE_PROBLEM );
}
return;
}
RMemFree( fcb->filename );
fcb->filename = sys_name;
}
void OpenAction( ftnfile *fcb ) {
//==================================
// Open a file.
SetIOBufferSize( fcb->blocksize );
fcb->fileptr = Openf( fcb->filename, _FileAttrs( fcb ) );
if( fcb->fileptr != NULL ) {
if( ((a_file *)(fcb->fileptr))->attrs & CHAR_DEVICE ) {
// In dos box under NT we do not get correct information
// about a device until we actually open it (a bug in the NT
// dos box
fcb->device = INFO_DEV;
}
}
}
int DfltRecType( ftnfile *fcb ) {
//===================================
if( fcb->formatted == FORMATTED_IO ) {
return( REC_TEXT );
} else {
if( fcb->accmode == ACCM_DIRECT ) {
return( REC_FIXED );
} else {
return( REC_VARIABLE );
}
}
}
int _FileAttrs( ftnfile *fcb ) {
//==================================
int attrs;
attrs = 0;
if( fcb->recfm == RECFM_DEFAULT ) {
attrs |= DfltRecType( fcb );
} else if( fcb->recfm == RECFM_VARIABLE ) {
attrs |= REC_VARIABLE;
} else if( fcb->recfm == RECFM_TEXT ) {
attrs |= REC_TEXT;
} else {
attrs |= REC_FIXED;
}
if( fcb->share == SHARE_DENYRW ) {
attrs |= S_DENYRW;
} else if( fcb->share == SHARE_DENYWR ) {
attrs |= S_DENYWR;
} else if( fcb->share == SHARE_DENYRD ) {
attrs |= S_DENYRD;
} else if( fcb->share == SHARE_DENYNO ) {
attrs |= S_DENYNO;
}
if( fcb->cctrl == CC_YES ) {
attrs |= CARRIAGE_CONTROL;
}
if( (fcb->accmode == ACCM_SEQUENTIAL) || (fcb->accmode == ACCM_APPEND) ) {
if( !IsDevice( fcb ) ) {
attrs |= TRUNC_ON_WRITE;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?