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