void InitStd( void ) { // Initialize standard i/o. #if !defined( __UNIX__ ) && defined( __WATCOMC__ ) // 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 }
static int __iomode( int handle, int amode ) { int flags; int __errno; #if defined(__UNIX__) if( (flags = fcntl( handle, F_GETFL )) == -1 ) { return( -1 ); } __errno = EOK; if( (flags & O_APPEND) && !(amode & _APPEND) ) { __errno = EACCES; } if( (flags & O_ACCMODE) == O_RDONLY ) { if( amode & _WRITE ) __errno = EACCES; } else if( (flags & O_ACCMODE) == O_WRONLY ) { if( amode & _READ ) __errno = EACCES; } #else /* make sure the handle has the same text/binary mode */ flags = __GetIOMode( handle ); __errno = 0; if( ( amode ^ flags ) & (_BINARY|_APPEND) ) __errno = EACCES; if( ( amode & _READ ) && !( flags & _READ ) ) __errno = EACCES; if( ( amode & _WRITE ) && !( flags & _WRITE ) ) __errno = EACCES; #endif if( __errno == EACCES ) { __set_errno( __errno ); return( -1 ); } return(0); }
_WCRTLINK int dup( int old_hid ) { HANDLE new_handle; int hid; HANDLE cprocess; __handle_check( old_hid, -1 ); // First try to get the required slot. // No point in creating a new handle only to not use it. JBS 99/11/01 hid = __allocPOSIXHandle( DUMMY_HANDLE ); if( hid == -1 ) { return( -1 ); } cprocess = GetCurrentProcess(); if( !DuplicateHandle( cprocess, __getOSHandle( old_hid ), cprocess, &new_handle, 0, TRUE, DUPLICATE_SAME_ACCESS ) ) { // Give back the slot we got __freePOSIXHandle( hid ); return( __set_errno_nt() ); } // Now use the slot we got __setOSHandle( hid, new_handle ); // JBS 99/11/01 __SetIOMode( hid, __GetIOMode( old_hid ) ); return( hid ); }
_WCRTLINK int dup2( int handle1, int handle2 ) { tiny_ret_t rc; __handle_check( handle1, -1 ); if( handle1 == handle2 ) { return( handle2 ); } rc = TinyDup2( handle1, handle2 ); if( TINY_ERROR(rc) ) { return( __set_errno_dos( TINY_INFO(rc) ) ); } __SetIOMode( handle2, __GetIOMode( handle1 ) ); return( 0 ); /* indicate success */ }
_WCRTLINK int dup2( int handle1, int handle2 ) { APIRET rc; __handle_check( handle1, -1 ); if( handle1 == handle2 ) { return( handle2 ); } rc = DosDupHandle( handle1, (PHFILE)&handle2 ); if( rc != 0 ) { return( __set_errno_dos( rc ) ); } __SetIOMode( handle2, __GetIOMode( handle1 ) ); return( 0 ); /* indicate success */ }
_WCRTLINK off_t lseek( int handle, off_t offset, int origin ) { #if !defined( __LINUX__ ) unsigned iomode_flags; __handle_check( handle, -1 ); /*** Set the _FILEEXT iomode_flags bit if positive offset ***/ iomode_flags = __GetIOMode( handle ); if( offset > 0 && !(iomode_flags & _APPEND) ) __SetIOMode_nogrow( handle, iomode_flags | _FILEEXT ); #endif return( __lseek( handle, offset, origin ) ); }
_WCRTLINK int setmode( int handle, int mode ) { unsigned iomode_flags; unsigned old_mode; __stream_link *link; FILE *fp; __handle_check( handle, -1 ); iomode_flags = __GetIOMode( handle ); if( iomode_flags == 0 ) { _RWD_errno = EBADF; return( -1 ); } old_mode = (iomode_flags & _BINARY) ? O_BINARY : O_TEXT; if( mode != old_mode ) { if( mode == O_BINARY || mode == O_TEXT ) { iomode_flags &= ~ _BINARY; if( mode == O_BINARY ) { iomode_flags |= _BINARY; } __SetIOMode( handle, iomode_flags ); _AccessFileH( handle ); for( link = _RWD_ostream; link != NULL; link = link->next ) { fp = link->stream; if( fp->_flag != 0 ) { /* if file is open */ if( fileno( fp ) == handle ) { fp->_flag &= ~ _BINARY; if( mode == O_BINARY ) { fp->_flag |= _BINARY; } break; } } } _ReleaseFileH( handle ); } else { _RWD_errno = EINVAL; old_mode = -1; } } return( old_mode ); }
int __qwrite( int handle, const void *buffer, unsigned len ) { int atomic; __file_handle *fh; unsigned len_written; __handle_check( handle, -1 ); fh = (__file_handle*) __getOSHandle( handle ); atomic = 0; if( __GetIOMode( handle ) & _APPEND ) { FILEINFO info; _AccessFileH( handle ); atomic = 1; get_fileinfo(fh->name,&info); fh->offset = info.size; }; if(write_file(fh->name,buffer,fh->offset,len,&len_written)) { if ( len_written == 0) { if( atomic == 1 ) _ReleaseFileH( handle ); return (-1); }; }; fh->offset+=len_written; if( atomic == 1 ) { _ReleaseFileH( handle ); } return( len_written ); }
/* * Return a pointer to a string containing information about currently open * POSIX-level file handles. If _fileinfo is non-zero, this string is * passed to child processes as an environment string. Each handle's data * is of the form "PPPPPPPP:OOOOOOOO:MMMMMMMM*", where the Ps represent the * POSIX-level file number, the Os represent the OS-level file number, and * the Ms represent the file's mode bits. The Ps, Os, and Ms are all hex * strings, without zero padding or 0x prefixes to conserve space. Returns * NULL if there is insufficient memory. The caller is responsible for * freeing the allocated memory. The returned string begins with * "C_FILE_INFO=", and so forms a valid environment string. */ _WCRTLINK CHAR_TYPE *__F_NAME(__FormPosixHandleStr,__wFormPosixHandleStr)( void ) /*******************************************************************************/ { extern unsigned __NFiles; CHAR_TYPE * p; int posixHandle, osHandle, mode; CHAR_TYPE curElem[MAX_ELEM_SIZE+1]; CHAR_TYPE buf[9]; size_t len; /*** Allocate memory for the string ***/ len = (__NFiles*MAX_ELEM_SIZE) + __F_NAME(strlen,wcslen)( STRING( "C_FILE_INFO=" ) ) + 1; p = lib_malloc( len * sizeof( CHAR_TYPE ) ); if( p == NULL ) return( NULL ); __F_NAME(strcpy,wcscpy)( p, STRING( "C_FILE_INFO=" ) ); /*** Process the open files ***/ for( posixHandle=0; posixHandle<__NFiles; posixHandle++ ) { __ChkTTYIOMode( posixHandle ); mode = __GetIOMode( posixHandle ); if( mode & _INITIALIZED ) { /* skip it if it's not open */ osHandle = _os_handle( posixHandle ); /*** Build the element string ***/ curElem[0] = NULLCHAR; __F_NAME(itoa,_itow)( posixHandle, buf, 16 ); /* POSIX handle */ __F_NAME(strcat,wcscat)( curElem, buf ); __F_NAME(strcat,wcscat)( curElem, STRING( ":" ) ); /* separator */ __F_NAME(itoa,_itow)( osHandle, buf, 16 ); /* OS handle */ __F_NAME(strcat,wcscat)( curElem, buf ); __F_NAME(strcat,wcscat)( curElem, STRING( ":" ) ); /* separator */ __F_NAME(itoa,_itow)( mode, buf, 16 ); /* file mode */ __F_NAME(strcat,wcscat)( curElem, buf ); __F_NAME(strcat,wcscat)( curElem, STRING( "*" ) ); /* terminator */ __F_NAME(strcat,wcscat)( p, curElem ); /* append it */ } } return( p ); }
_WCRTLINK int _open_osfhandle( long osfhandle, int flags ) { int posix_handle; #if defined(__NT__) // Under Win32, we get an OS handle argument posix_handle = __allocPOSIXHandle( (HANDLE)osfhandle ); if( posix_handle == -1 ) return( -1 ); #else // Under everything else, we get a POSIX handle argument posix_handle = osfhandle; #endif #if !defined(__NETWARE__) if( check_mode( posix_handle, flags ) ) { return( -1 ); } #if !defined(__UNIX__) { int rwmode; unsigned io_mode; rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR ); io_mode = __GetIOMode( posix_handle ); io_mode &= ~(_READ|_WRITE|_APPEND|_BINARY); if( rwmode == O_RDWR ) io_mode |= _READ | _WRITE; if( rwmode == O_RDONLY) io_mode |= _READ; if( rwmode == O_WRONLY) io_mode |= _WRITE; if( flags & O_APPEND ) io_mode |= _APPEND; if( flags & O_BINARY ) { io_mode |= _BINARY; } __SetIOMode( posix_handle, io_mode ); } #endif #endif return( posix_handle ); }
_WCRTLINK int write( int handle, const void *buffer, unsigned len ) #endif /**********************************************************************/ { unsigned iomode_flags; char *buf; unsigned buf_size; unsigned len_written, i, j; #if defined(__NT__) HANDLE h; LONG cur_ptr_low; LONG cur_ptr_high; DWORD rc1; #else tiny_ret_t rc1; #endif int rc2; __handle_check( handle, -1 ); iomode_flags = __GetIOMode( handle ); if( iomode_flags == 0 ) { #if defined(__WINDOWS__) || defined(__WINDOWS_386__) // How can we write to the handle if we never opened it? JBS return( _lwrite( handle, buffer, len ) ); #else __set_errno( EBADF ); return( -1 ); #endif } if( !(iomode_flags & _WRITE) ) { __set_errno( EACCES ); /* changed from EBADF to EACCES 23-feb-89 */ return( -1 ); } #if defined(__NT__) h = __getOSHandle( handle ); #endif // put a semaphore around our writes _AccessFileH( handle ); if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) ) { #if defined(__NT__) if( GetFileType( h ) == FILE_TYPE_DISK ) { cur_ptr_low = 0; cur_ptr_high = 0; rc1 = SetFilePointer( h, cur_ptr_low, &cur_ptr_high, FILE_END ); if( rc1 == INVALID_SET_FILE_POINTER ) { // this might be OK so if( GetLastError() != NO_ERROR ) { _ReleaseFileH( handle ); return( __set_errno_nt() ); } } } #elif defined(__OS2__) { unsigned long dummy; rc1 = DosChgFilePtr( handle, 0L, SEEK_END, &dummy ); // should we explicitly ignore ERROR_SEEK_ON_DEVICE here? } #else rc1 = TinySeek( handle, 0L, SEEK_END ); #endif #if !defined(__NT__) if( TINY_ERROR( rc1 ) ) { _ReleaseFileH( handle ); return( __set_errno_dos( TINY_INFO( rc1 ) ) ); } #endif } len_written = 0; rc2 = 0; // Pad the file with zeros if necessary if( iomode_flags & _FILEEXT ) { // turn off file extended flag __SetIOMode_nogrow( handle, iomode_flags&(~_FILEEXT) ); // It is not required to pad a file with zeroes on an NTFS file system; // unfortunately it is required on FAT (and probably FAT32). (JBS) rc2 = zero_pad( handle ); } if( rc2 == 0 ) { if( iomode_flags & _BINARY ) { /* if binary mode */ rc2 = os_write( handle, buffer, len, &len_written ); /* end of binary mode part */ } else { /* text mode */ i = stackavail(); if( i < 0x00b0 ) { __STKOVERFLOW(); /* not enough stack space */ } buf_size = 512; if( i < (512 + 48) ) { buf_size = 128; } #if defined(__AXP__) || defined(__PPC__) buf = alloca( buf_size ); #else buf = __alloca( buf_size ); #endif j = 0; for( i = 0; i < len; ) { if( ((const char*)buffer)[i] == '\n' ) { buf[j] = '\r'; ++j; if( j == buf_size ) { rc2 = os_write( handle, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } buf[j] = ((const char*)buffer)[i]; ++i; ++j; if( j == buf_size ) { rc2 = os_write( handle, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } if( j ) { rc2 = os_write( handle, buf, j, &i ); if( rc2 == ENOSPC ) { len_written += i; } else { len_written = len; } } /* end of text mode part */ } } _ReleaseFileH( handle ); if( rc2 == -1 ) { return( rc2 ); } else { return( len_written ); } }
_WCRTLINK int read( int handle, void *buf, unsigned len ) #endif { unsigned read_len, total_len; unsigned reduce_idx, finish_idx; unsigned iomode_flags; char *buffer = buf; #if defined(__NT__) DWORD amount_read; BOOL rc; HANDLE h; #elif defined(__WARP__) ULONG amount_read; #elif defined(__OS2_286__) USHORT amount_read; #else unsigned amount_read; #endif #if !defined(__NT__) tiny_ret_t rc; #endif #ifdef DEFAULT_WINDOWING LPWDATA res; #endif __handle_check( handle, -1 ); __ChkTTYIOMode( handle ); iomode_flags = __GetIOMode( handle ); if( iomode_flags == 0 ) { #if defined( __WINDOWS__ ) || defined( __WINDOWS_386__ ) return( _lread( handle, buffer, len ) ); #else _RWD_errno = EBADF; return( -1 ); #endif } if( !(iomode_flags & _READ) ) { _RWD_errno = EACCES; /* changed from EBADF to EACCES 23-feb-89 */ return( -1 ); } #ifdef __NT__ h = __getOSHandle( handle ); #endif if( iomode_flags & _BINARY ) { /* if binary mode */ #ifdef DEFAULT_WINDOWING if( _WindowsStdin != 0 && (res = _WindowsIsWindowedHandle( handle )) != 0 ) { total_len = _WindowsStdin( res, buffer, len ); rc = 0; } else #endif { #if defined(__NT__) rc = ReadFile( h, buffer, len, &amount_read, NULL ); total_len = amount_read; if( !rc ) { if (GetLastError() == ERROR_BROKEN_PIPE) return total_len; return( __set_errno_nt() ); } #elif defined( __OS2__ ) rc = DosRead( handle, buffer, len, &amount_read ); total_len = amount_read; #else rc = TinyRead( handle, buffer, len ); total_len = TINY_LINFO( rc ); #endif } #if !defined(__NT__) if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } #endif } else { _AccessFileH( handle ); total_len = 0; read_len = len; do { #ifdef DEFAULT_WINDOWING if( _WindowsStdin != 0 && (res = _WindowsIsWindowedHandle( handle )) != 0L ) { amount_read = _WindowsStdin( res, buffer, read_len ); rc = 0; } else #endif { #if defined(__NT__) rc = ReadFile( h, buffer, read_len, &amount_read, NULL ); if( !rc ) { _ReleaseFileH( handle ); if( GetLastError() == ERROR_BROKEN_PIPE ) return total_len; return( __set_errno_nt() ); } #elif defined( __OS2__ ) rc = DosRead( handle, buffer, read_len, &amount_read ); #else rc = TinyRead( handle, buffer, read_len ); amount_read = TINY_LINFO( rc ); #endif } #if !defined(__NT__) if( TINY_ERROR( rc ) ) { _ReleaseFileH( handle ); return( __set_errno_dos( TINY_INFO( rc ) ) ); } #endif if( amount_read == 0 ) { /* EOF */ break; } reduce_idx = 0; finish_idx = reduce_idx; for( ; reduce_idx < amount_read; ++reduce_idx ) { if( buffer[ reduce_idx ] == 0x1a ) { /* EOF */ __lseek( handle, ((long)reduce_idx - (long)amount_read)+1L, SEEK_CUR ); total_len += finish_idx; _ReleaseFileH( handle ); return( total_len ); } if( buffer[ reduce_idx ] != '\r' ) { buffer[ finish_idx++ ] = buffer[ reduce_idx ]; } } total_len += finish_idx; buffer += finish_idx; read_len -= finish_idx; if( iomode_flags & _ISTTY ) { break; /* 04-feb-88, FWC */ } } while( read_len != 0 ); _ReleaseFileH( handle ); } return( total_len ); }
_WCRTLINK int read( int handle, void *buf, unsigned len ) { unsigned read_len, total_len; unsigned reduce_idx, finish_idx; unsigned iomode_flags; char *buffer = buf; BOOL rc; HANDLE h; unsigned amount_read; int err; __file_handle *fh; __handle_check( handle, -1 ); __ChkTTYIOMode( handle ); iomode_flags = __GetIOMode( handle ); if( iomode_flags == 0 ) { __set_errno( EBADF ); return( -1 ); } if( !(iomode_flags & _READ) ) { __set_errno( EACCES ); /* changed from EBADF to EACCES 23-feb-89 */ return( -1 ); } fh = (__file_handle*) __getOSHandle( handle ); if( iomode_flags & _BINARY ) /* if binary mode */ { err=read_file(fh->name,buffer,fh->offset,len,&amount_read); fh->offset+=amount_read; total_len = amount_read; if(err) if ( amount_read == 0) return (-1); } else { total_len = 0; read_len = len; do { err=read_file(fh->name,buffer,fh->offset,len,&amount_read); fh->offset+=amount_read; if( amount_read == 0 ) break; /* EOF */ reduce_idx = 0; finish_idx = reduce_idx; for( ; reduce_idx < amount_read; ++reduce_idx ) { if( buffer[ reduce_idx ] == 0x1a ) /* EOF */ { __lseek( handle, ((long)reduce_idx - (long)amount_read)+1L, SEEK_CUR ); total_len += finish_idx; return( total_len ); } if( buffer[ reduce_idx ] != '\r' ) { buffer[ finish_idx++ ] = buffer[ reduce_idx ]; }; } total_len += finish_idx; buffer += finish_idx; read_len -= finish_idx; if( iomode_flags & _ISTTY ) { break; /* 04-feb-88, FWC */ } } while( read_len != 0 ); } return( total_len ); }
_WCRTLINK int fstat( int handle, struct stat *buf ) #endif { APIRET error; OS_UINT hand_type; OS_UINT device_attr; FF_BUFFER info; unsigned iomode_flags; __handle_check( handle, -1 ); buf->st_mode = 0; iomode_flags = __GetIOMode( handle ); if( iomode_flags & _READ ) { buf->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; } if( iomode_flags & _WRITE ) { buf->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; } error = DosQHandType( handle, &hand_type, &device_attr ); if( error ) { return( __set_errno_dos( error ) ); } if( ( hand_type & ~HANDTYPE_NETWORK ) == HANDTYPE_FILE ) { /* handle file */ error = DosQFileInfo( handle, FF_LEVEL, (PBYTE)&info, sizeof( info ) ); if( error ) { return( __set_errno_dos( error ) ); } buf->st_dev = buf->st_rdev = 0; /* handle timestamps */ buf->st_ctime = _d2ttime( TODDATE( info.fdateCreation ), TODTIME( info.ftimeCreation ) ); buf->st_atime = _d2ttime( TODDATE( info.fdateLastAccess ), TODTIME( info.ftimeLastAccess ) ); buf->st_mtime = _d2ttime( TODDATE( info.fdateLastWrite ), TODTIME( info.ftimeLastWrite ) ); buf->st_btime = buf->st_mtime; #if defined( __INT64__ ) && !defined( _M_I86 ) if( _FILEAPI64() ) { #endif buf->st_attr = info.attrFile; buf->st_mode |= at2mode( info.attrFile ); buf->st_size = info.cbFile; #if defined( __INT64__ ) && !defined( _M_I86 ) } else { buf->st_attr = ((FF_BUFFER_32 *)&info)->attrFile; buf->st_mode |= at2mode( ((FF_BUFFER_32 *)&info)->attrFile ); buf->st_size = ((FF_BUFFER_32 *)&info)->cbFile; } #endif } else { /* handle device */ /* handle attributes */ buf->st_attr = 0; buf->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; if( ( hand_type & ~HANDTYPE_NETWORK ) == HANDTYPE_DEVICE ) { buf->st_mode |= S_IFCHR; } else if( ( hand_type & ~HANDTYPE_NETWORK ) == HANDTYPE_PIPE ) { buf->st_mode |= S_IFIFO; } buf->st_dev = buf->st_rdev = 1; /* handle timestamps */ buf->st_atime = 0; buf->st_ctime = 0; buf->st_mtime = 0; buf->st_btime = 0; /* handle size */ buf->st_size = 0; } buf->st_nlink = 1; buf->st_ino = handle; buf->st_uid = buf->st_gid = 0; buf->st_archivedID = 0; buf->st_updatedID = 0; buf->st_inheritedRightsMask = 0; buf->st_originatingNameSpace = 0; return( 0 ); }
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 handle = -1; rc = 0; while( *name == STRING( ' ' ) ) ++name; #ifdef __WIDECHAR__ /*** If necessary, convert the wide filename to multibyte form ***/ if( wcstombs( mbName, name, sizeof( mbName ) ) == -1 ) { mbName[0] = '\0'; } #endif rwmode = mode & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT ); if( _dos_open( __F_NAME(name,mbName), rwmode | shflag, &handle ) == 0 ) { 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 || _RWD_doserrno != E_nofile ) { return( -1 ); } /* 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 */ if( _dos_creat( __F_NAME(name,mbName), attr, &handle ) ) { return( -1 ); } 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 ) ) ); } if( _dos_open( __F_NAME(name,mbName), rwmode | shflag, &handle ) ) { return( -1 ); } /* 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 ) { if( !__F_NAME(stricmp,wcscmp)( name, STRING( "con" ) ) ) { _WindowsNewWindow( NULL, handle, -1 ); } } #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 ); }
int __qwrite( int handle, const void *buffer, unsigned len ) { int atomic; #if defined(__NT__) DWORD len_written; HANDLE h; int error; #elif defined(__WARP__) ULONG len_written; #elif defined(__OS2_286__) USHORT len_written; #else unsigned len_written; #endif #if !defined(__NT__) tiny_ret_t rc; #endif __handle_check( handle, -1 ); #if defined(__NT__) h = __getOSHandle( handle ); #endif atomic = 0; if( __GetIOMode( handle ) & _APPEND ) { _AccessFileH( handle ); atomic = 1; #if defined(__NT__) if( SetFilePointer( h, 0, NULL, FILE_END ) == -1 ) { error = GetLastError(); _ReleaseFileH( handle ); return( __set_errno_dos( error ) ); } #elif defined(__OS2__) { unsigned long dummy; rc = DosChgFilePtr( handle, 0L, SEEK_END, &dummy ); } #else rc = TinySeek( handle, 0L, SEEK_END ); #endif #if !defined(__NT__) if( TINY_ERROR( rc ) ) { _ReleaseFileH( handle ); return( __set_errno_dos( TINY_INFO( rc ) ) ); } #endif } #ifdef DEFAULT_WINDOWING if( _WindowsStdout != 0 ) { LPWDATA res; res = _WindowsIsWindowedHandle( handle ); if( res ) { int rt; rt = _WindowsStdout( res, buffer, len ); return( rt ); } } #endif #if defined(__NT__) if( !WriteFile( h, buffer, len, &len_written, NULL ) ) { error = GetLastError(); if( atomic == 1 ) { _ReleaseFileH( handle ); } return( __set_errno_dos( error ) ); } #elif defined(__OS2__) rc = DosWrite( handle, (PVOID)buffer, len, &len_written ); #elif defined(__WINDOWS_386__) rc = __TinyWrite( handle, buffer, len ); len_written = TINY_LINFO( rc ); #else rc = TinyWrite( handle, buffer, len ); len_written = TINY_LINFO( rc ); #endif #if !defined(__NT__) if( TINY_ERROR( rc ) ) { if( atomic == 1 ) { _ReleaseFileH( handle ); } return( __set_errno_dos( TINY_INFO( rc ) ) ); } #endif if( len_written != len ) { __set_errno( ENOSPC ); } if( atomic == 1 ) { _ReleaseFileH( handle ); } return( len_written ); }
_WCRTLINK int fstat( int handle, struct stat *buf ) { unsigned iomode_flags; tiny_ret_t rc; __handle_check( handle, -1 ); rc = TinyGetDeviceInfo( handle ); if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } /* isolate drive number */ buf->st_dev = TINY_INFO( rc ) & TIO_CTL_DISK_DRIVE_MASK; buf->st_rdev = buf->st_dev; buf->st_nlink = 1; buf->st_uid = buf->st_gid = 0; buf->st_ino = handle; buf->st_mode = 0; iomode_flags = __GetIOMode( handle ); if( iomode_flags & _READ ) { buf->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; } if( iomode_flags & _WRITE ) { buf->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; } if( TINY_INFO( rc ) & TIO_CTL_DEVICE ) { buf->st_size = 0; buf->st_atime = buf->st_ctime = buf->st_mtime = 0; buf->st_mode |= S_IFCHR; } else { /* file */ #ifdef __WATCOM_LFN__ lfninfo_t lfni; rc = 0; if( _RWD_uselfn && TINY_OK( rc = _getfileinfo_lfn( handle, &lfni ) ) ) { buf->st_mtime = _cvt_stamp2ttime_lfn( &lfni.writetimestamp ); if( lfni.creattimestamp ) { buf->st_ctime = _cvt_stamp2ttime_lfn( &lfni.creattimestamp ); } else { buf->st_ctime = buf->st_mtime; } if( lfni.accesstimestamp ) { buf->st_atime = _cvt_stamp2ttime_lfn( &lfni.accesstimestamp ); } else { buf->st_atime = buf->st_mtime; } buf->st_size = lfni.lfilesize; buf->st_attr = lfni.attributes; } else if( IS_LFN_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } else { #endif long rc1; rc1 = __getfilestamp_sfn( handle ); if( rc1 == -1 ) { return( -1 ); } buf->st_mtime = _d2ttime( rc1 >> 16, rc1 ); buf->st_atime = buf->st_mtime; buf->st_ctime = buf->st_mtime; buf->st_size = filelength( handle ); buf->st_attr = 0; #ifdef __WATCOM_LFN__ } #endif buf->st_mode |= S_IFREG; } buf->st_btime = buf->st_mtime; buf->st_archivedID = 0; buf->st_updatedID = 0; buf->st_inheritedRightsMask = 0; buf->st_originatingNameSpace = 0; return( 0 ); }