posopen.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 245 行
C
245 行
/****************************************************************************
*
* 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: POSIX level i/o support
*
****************************************************************************/
#include "ftnstd.h"
#include "fio.h"
#include "posio.h"
#if defined( __RT__ )
#include "rmemmgr.h"
#define MEM_ALLOC RMemAlloc
#define MEM_FREE RMemFree
#else
#include "fmemmgr.h"
#define MEM_ALLOC FMemAlloc
#define MEM_FREE FMemFree
#endif
extern void FSetErr(int,b_file *);
extern void FSetSysErr(b_file *);
extern void IOOk(b_file *);
extern int FSetCC(b_file *,char,char **);
extern int SysWrite(b_file *,char *,uint);
extern int FlushBuffer(b_file *);
extern bool __DevicesCC(void);
extern b_file *FStdIn;
extern b_file *FStdOut;
extern b_file *FStdErr;
static int IOBufferSize = { IO_BUFFER };
#define PERMS (S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP | S_IRUSR | S_IWUSR)
void InitStd( void ) {
//=================
// Initialize standard i/o.
#if ! defined( __UNIX__ )
// don't call setmode() since we don't want to affect higher level
// i/o so that if C function gets called, printf() works ok
// There is no __GetIOMode in the C runtime!
#define __GetIOMode __IOMode
extern unsigned __GetIOMode(int);
extern void __SetIOMode(int,unsigned);
__SetIOMode( STDIN_FILENO, __GetIOMode( STDIN_FILENO ) | _BINARY );
__SetIOMode( STDOUT_FILENO, __GetIOMode( STDOUT_FILENO ) | _BINARY );
__SetIOMode( STDERR_FILENO, __GetIOMode( STDERR_FILENO ) | _BINARY );
#endif
#if defined( __RT__ )
ChkRedirection( FStdIn );
ChkRedirection( FStdOut );
ChkRedirection( FStdErr );
if( __DevicesCC() ) {
FStdOut->attrs |= CC_NOLF;
}
#endif
}
#if defined( __RT__ )
static void ChkRedirection( b_file *fp ) {
//============================================
// Check for redirection of standard i/o devices.
struct stat info;
if( fstat( fp->handle, &info ) == -1 ) return;
if( !S_ISCHR( info.st_mode ) ) {
fp->attrs |= BUFFERED;
}
}
#endif
void SetIOBufferSize( uint buff_size ) {
//=========================================
if( buff_size < MIN_BUFFER ) {
buff_size = MIN_BUFFER;
}
IOBufferSize = buff_size;
}
b_file *_AllocFile( int h, f_attrs attrs, long int fpos ) {
//==========================================================
// Allocate file structure.
b_file *io;
struct stat info;
int buff_size;
if( fstat( h, &info ) == -1 ) {
FSetSysErr( NULL );
return( NULL );
}
attrs &= ~CREATION_MASK;
if( S_ISCHR( info.st_mode ) ) {
io = MEM_ALLOC( sizeof( a_file ) );
// Turn off truncate just in case we turned it on by accident due to
// a buggy NT dos box. We NEVER want to truncate a device.
attrs &= ~TRUNC_ON_WRITE;
attrs |= CHAR_DEVICE;
} else {
attrs |= BUFFERED;
buff_size = IOBufferSize;
io = MEM_ALLOC( sizeof( b_file ) + IOBufferSize - MIN_BUFFER );
if( ( io == NULL ) && ( IOBufferSize > MIN_BUFFER ) ) {
// buffer is too big (low on memory) so use small buffer
buff_size = MIN_BUFFER;
io = MEM_ALLOC( sizeof( b_file ) );
}
}
if( io == NULL ) {
close( h );
FSetErr( IO_NO_MEM, NULL );
} else {
if( attrs & CARRIAGE_CONTROL ) {
attrs |= CC_NOLF;
}
io->attrs = attrs;
io->handle = h;
if( attrs & BUFFERED ) {
io->b_curs = 0;
io->read_len = 0;
io->buff_size = buff_size;
io->high_water = 0;
}
io->phys_offset = fpos;
IOOk( io );
}
return( io );
}
b_file *Openf( char *f, f_attrs attrs ) {
//========================================
// Open a file.
int retc;
long int fpos;
int share;
fpos = 0;
share = SH_COMPAT;
if( attrs & S_DENYRW ) {
share = SH_DENYRW;
} else if( attrs & S_DENYWR ) {
share = SH_DENYWR;
} else if( attrs & S_DENYRD ) {
share = SH_DENYRD;
} else if( attrs & S_DENYNO ) {
share = SH_DENYNO;
}
if( attrs & WRONLY ) {
attrs |= WRITE_ONLY;
if( attrs & APPEND ) {
retc = sopen( f, O_WRONLY | O_BINARY | O_CREAT, share, PERMS );
} else {
retc = sopen( f, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, share, PERMS );
}
} else if( attrs & RDONLY ) {
retc = sopen( f, O_RDONLY | O_BINARY, share, 0 );
} else { // if( attrs & RDWR ) {
retc = sopen( f, O_RDWR | O_BINARY | O_CREAT, share, PERMS );
}
if( retc < 0 ) {
FSetSysErr( NULL );
return( NULL );
}
if( attrs & APPEND ) {
fpos = lseek( retc, 0, SEEK_END );
if( fpos < 0 ) {
FSetSysErr( NULL );
close( retc );
return( NULL );
}
}
return( _AllocFile( retc, attrs, fpos ) );
}
void Closef( b_file *io ) {
//============================
// Close a file.
uint cc_len;
char *cc;
if( io->attrs & CARRIAGE_CONTROL ) {
cc_len = FSetCC( io, ' ', &cc );
if( SysWrite( io, cc, cc_len ) == -1 ) return;
}
if( FlushBuffer( io ) < 0 ) return;
if( close( io->handle ) < 0 ) {
FSetSysErr( io );
return;
}
MEM_FREE( io );
IOOk( NULL );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?