📄 open.c
字号:
/****************************************************************************
*
* 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: DOS implementation of open() and sopen().
*
****************************************************************************/
#include "variety.h"
#include "widechar.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <share.h>
#include "dos.h"
#include "dosfunc.h"
#include "tinyio.h"
#include "rtdata.h"
#include "iomode.h"
#include "seterrno.h"
#include "defwin.h"
#include "extender.h"
#ifdef __WIDECHAR__
#include <mbstring.h>
#include "mbwcconv.h"
#endif
/* file attributes */
_WCRTLINK extern char *_lfntosfn( char *orgname, char *shortname );
_WCRTLINK extern int _islfn( const char *path );
#define _A_RDONLY 0x01
#ifdef __WATCOM_LFN__
static int CTinyOpen( const char *path, int mode )
{
char short_name[128];
union REGS r;
struct SREGS s;
if( _lfntosfn( ( char * )path, short_name ) == NULL ) {
return( -2 );
}
r.w.ax = ( short_name[0] != '\0' ) ?
TinyOpen( short_name, mode ) : -1;
if( TINY_OK( r.w.ax ) ) return ( r.w.ax );
s.ds = FP_SEG( path );
r.w.si = FP_OFF( path );
r.w.bx = mode;
r.w.dx = 0;
r.w.ax = 0x716C;
intdosx( &r, &r, &s );
if( r.x.cflag || r.w.ax == 0x7100 ) return ( TinyOpen( path, mode ) );
return ( ( r.w.ax < 5 ) ? -1 : r.w.ax );
}
static int CTinyCreate( const char *path, int attribs )
{
union REGS r;
struct SREGS s;
s.ds = FP_SEG( path );
r.w.si = FP_OFF( path );
r.w.bx = O_WRONLY;
r.w.cx = attribs;
r.w.dx = 0x12;
r.w.ax = 0x716C;
intdosx( &r, &r, &s );
if( ( r.x.cflag || r.w.ax == 0x7100 ) && !_islfn( path ) )
return ( TinyCreate( path, attribs ) );
else if( _islfn( path ) && ( r.x.cflag || r.w.ax == 0x7100 ) )
return -r.w.ax;
return ( ( r.w.ax < 5 ) ? CTinyOpen( path, O_WRONLY ) : r.w.ax );
}
#undef TinyOpen
#undef TinyCreate
#define TinyOpen CTinyOpen
#define TinyCreate CTinyCreate
#endif
extern unsigned __NFiles;
static int __F_NAME(_sopen,__wsopen)( const CHAR_TYPE *name, int mode,
int shflag, va_list args )
{
int rwmode;
int handle;
int attr;
int permission;
unsigned iomode_flags;
tiny_ret_t rc;
char dummy;
#ifdef __WIDECHAR__
char mbName[MB_CUR_MAX*_MAX_PATH]; /* single-byte char */
#endif
while( *name == ' ' ) ++name;
handle = -1;
/*** If necessary, convert the wide filename to multibyte form ***/
#ifdef __WIDECHAR__
__filename_from_wide( mbName, name );
#endif
/* 05-sep-91 */
rwmode = mode & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT );
#ifdef __WIDECHAR__
rc = TinyOpen( mbName, rwmode | shflag );
#else
rc = TinyOpen( name, rwmode | shflag );
#endif
if( TINY_OK( rc ) ) {
handle = TINY_INFO( rc );
if (handle >= __NFiles) {
TinyClose( handle );
__set_errno(EMFILE);
return -1;
}
}
/* 17-apr-90 05-sep-91 */
if( (mode & (O_RDONLY | O_WRONLY | O_RDWR)) != O_RDONLY ) {
if( handle != -1 ) {
if( ! isatty( handle ) ) { /* if not a device */
#if 0
rc = TinyAccess( name, 0 ); /* check for existence */
if( TINY_ERROR( rc ) ) { /* file does not exist */
TinyClose( handle ); /* close whatever file we got */
handle = -1;
} else if( mode & O_EXCL ) { /* must not exist */
#else
/*
Don't need to do the access check, since the file was opened
and therefore must exist (TinyOpen can't create a file).
We don't want to do the check because there are classes of items
in the file system namespace that are not devices, but the TinyAccess
will fail on (e.g. named pipes).
*/
/* must not exist if O_CREAT specified */
if( mode & O_EXCL && mode & O_CREAT ) {
#endif
TinyClose( handle );
__set_errno( EEXIST );
return( -1 );
} else if( mode & O_TRUNC ) { /* truncate file */
rc = TinyWrite( handle, &dummy, 0 );
if( TINY_ERROR( rc ) ) {
TinyClose( handle );
return( __set_errno_dos( TINY_INFO(rc) ) );
}
}
}
}
}
if( handle == -1 ) { /* could not open */
if(( mode & O_CREAT ) == 0
|| ( TINY_INFO( rc ) != TIO_FILE_NOT_FOUND
&& ( TINY_INFO( rc ) != TINY_INFO( -TIO_FILE_NOT_FOUND ) ) ) ) {
return( __set_errno_dos( TINY_INFO( rc ) ) );
}
/* creating the file */
permission = va_arg( args, int );
va_end( args );
if( permission == 0 ) permission = S_IWRITE | S_IREAD;
permission &= ~_RWD_umaskval; /* 05-jan-95 */
attr = 0;
if(( permission & S_IWRITE) == 0 ) attr = _A_RDONLY;
#if 0
/* remove this support because it is not consistently available */
if( _RWD_osmajor >= 5
#ifdef __DOS_EXT__
&& !_IsFlashTek()
&& !_IsRational()
#endif
) {
/* this function is only available in version DOS 5 and up */
/* this new way was added to handle the case of creating a */
/* new file with read-only access, but with a writeable */
/* file handle */
#ifdef __WIDECHAR__
rc = TinyCreateEx( mbName, rwmode|shflag, attr, TIO_OPEN );
#else
rc = TinyCreateEx( name, rwmode|shflag, attr, TIO_OPEN );
#endif
if( TINY_ERROR( rc ) ) {
return( __set_errno_dos( TINY_INFO( rc ) ) );
}
handle = TINY_INFO( rc );
} else
#endif
{
/* do it the old way */
#ifdef __WIDECHAR__
rc = TinyCreate( mbName, attr );
#else
rc = TinyCreate( name, attr );
#endif
if( TINY_ERROR( rc ) ) {
return( __set_errno_dos( TINY_INFO( rc ) ) );
}
handle = TINY_INFO( rc );
if (handle >= __NFiles)
{
TinyClose(handle);
__set_errno(EMFILE);
return -1;
}
/* 21-nov-90 AFS: the file is created so now the file must be */
/* opened with the correct share permissions */
if( shflag != 0 ) {
rc = TinyClose( handle );
if( TINY_ERROR( rc ) ) {
return( __set_errno_dos( TINY_INFO( rc ) ) );
}
#ifdef __WIDECHAR__
rc = TinyOpen( mbName, rwmode | shflag );
#else
rc = TinyOpen( name, rwmode | shflag );
#endif
if( TINY_ERROR( rc ) ) {
return( __set_errno_dos( TINY_INFO( rc ) ) );
}
handle = TINY_INFO( rc );
/* handle does not equal -1 now */
}
}
}
iomode_flags = __GetIOMode( handle );
iomode_flags &= ~(_READ|_WRITE|_APPEND|_BINARY); /* 11-aug-88 */
if( isatty( handle ) ) iomode_flags |= _ISTTY;
rwmode &= ~O_NOINHERIT;
if( rwmode == O_RDWR ) iomode_flags |= _READ | _WRITE;
if( rwmode == O_RDONLY) iomode_flags |= _READ;
if( rwmode == O_WRONLY) iomode_flags |= _WRITE;
if( mode & O_APPEND ) iomode_flags |= _APPEND;
if( mode & (O_BINARY|O_TEXT) ) {
if( mode & O_BINARY ) {
iomode_flags |= _BINARY;
}
} else {
if( _RWD_fmode == O_BINARY ) {
iomode_flags |= _BINARY;
}
}
__SetIOMode( handle, iomode_flags );
#ifdef DEFAULT_WINDOWING
if( _WindowsNewWindow != 0 ) {
#ifdef __WIDECHAR__
if( !wcscmp( name, L"con" ) ) {
_WindowsNewWindow( NULL, handle, -1 );
}
#else
if( !stricmp( name, "con" ) ) {
_WindowsNewWindow( NULL, handle, -1 );
}
#endif
}
#endif
return( handle );
}
#if 0 /* couldn't find any user; please re-enable if it's necessary */
#ifndef __WIDECHAR__ /* compile one version only */
int __set_binary( int handle )
{
unsigned iomode_flags;
__ChkTTYIOMode( handle );
iomode_flags = __GetIOMode( handle );
iomode_flags |= _BINARY;
__SetIOMode( handle, iomode_flags );
if( iomode_flags & _ISTTY ) {
tiny_ret_t rc;
rc = TinyGetDeviceInfo( handle );
if( TINY_ERROR( rc ) ) {
return( __set_errno_dos( TINY_INFO( rc ) ) );
}
rc = TinySetDeviceInfo( handle, TINY_INFO(rc) | TIO_CTL_RAW );
if( TINY_ERROR( rc ) ) {
return( __set_errno_dos( TINY_INFO( rc ) ) );
}
}
return( 0 );
}
#endif
#endif
_WCRTLINK int __F_NAME(open,_wopen)( const CHAR_TYPE *name, int mode, ... )
{
int permission;
va_list args;
va_start( args, mode );
permission = va_arg( args, int );
va_end( args );
return( __F_NAME(sopen,_wsopen)( name, mode, 0, permission ) );
}
_WCRTLINK int __F_NAME(sopen,_wsopen)( const CHAR_TYPE *name, int mode, int shflag, ... )
{
va_list args;
va_start( args, shflag );
return( __F_NAME(_sopen,__wsopen)( name, mode, shflag, args ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -