From a73bea0da80d2a1abd8c9641fd9209dab8995105 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sun, 10 Feb 2008 14:10:44 +0000 Subject: [PATCH] Clib chsize, fstat, setmode. set_file_size: watcom-specific implementation git-svn-id: svn://kolibrios.org@727 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../open watcom/trunk/clib/h/kolibri.h | 76 +++++++++- .../trunk/clib/handleio/chsizklbr.c | 82 +++++++++++ .../open watcom/trunk/clib/handleio/fstat.c | 135 ++++++++++++++++++ .../trunk/clib/handleio/openklbr.c | 34 +++-- .../open watcom/trunk/clib/handleio/oshdl.c | 54 +++++++ .../open watcom/trunk/clib/handleio/qread.c | 12 +- .../open watcom/trunk/clib/handleio/read.c | 31 ++-- .../open watcom/trunk/clib/handleio/setmd.c | 91 ++++++++++++ .../open watcom/trunk/clib/handleio/write.c | 10 +- 9 files changed, 481 insertions(+), 44 deletions(-) create mode 100644 programs/develop/open watcom/trunk/clib/handleio/chsizklbr.c create mode 100644 programs/develop/open watcom/trunk/clib/handleio/fstat.c create mode 100644 programs/develop/open watcom/trunk/clib/handleio/oshdl.c create mode 100644 programs/develop/open watcom/trunk/clib/handleio/setmd.c diff --git a/programs/develop/open watcom/trunk/clib/h/kolibri.h b/programs/develop/open watcom/trunk/clib/h/kolibri.h index 5b1b707392..4185fda394 100644 --- a/programs/develop/open watcom/trunk/clib/h/kolibri.h +++ b/programs/develop/open watcom/trunk/clib/h/kolibri.h @@ -99,18 +99,63 @@ void _stdcall write_text(int x,int y,int color,char* text,int len); #endif +#pragma pack(push, 1) +typedef struct +{ + char sec; + char min; + char hour; + char rsv; +}detime_t; +#pragma pack(pop) + +#pragma pack(push, 1) +typedef struct +{ + char day; + char month; + short year; +}dedate_t; +#pragma pack(pop) + +#pragma pack(push, 1) typedef struct { unsigned attr; unsigned flags; - unsigned cr_time; - unsigned cr_date; - unsigned acc_time; - unsigned acc_date; - unsigned mod_time; - unsigned mod_date; + union + { + detime_t ctime; + unsigned cr_time; + }; + union + { + dedate_t cdate; + unsigned cr_date; + }; + union + { + detime_t atime; + unsigned acc_time; + }; + union + { + dedate_t adate; + unsigned acc_date; + }; + union + { + detime_t mtime; + unsigned mod_time; + }; + union + { + dedate_t mdate; + unsigned mod_date; + }; unsigned size; unsigned size_high; } FILEINFO; +#pragma pack(pop) unsigned init_heap(void); @@ -118,7 +163,8 @@ void *user_alloc(unsigned size); unsigned user_free(void *); int create_file(const char *name); -int get_fileinfo(const char *name,FILEINFO* pinfo); +int set_file_size(const char *name, unsigned size); +int get_fileinfo(const char *name,FILEINFO *info); int read_file (const char *name,void *buff, unsigned offset, unsigned count,unsigned *reads); int write_file(const char *name,const void *buff,unsigned offset,unsigned count,unsigned *writes); @@ -159,6 +205,22 @@ int write_file(const char *name,const void *buff,unsigned offset,unsigned count, parm [EAX] value [EAX] \ modify [ EBX ]; +#pragma aux set_file_size = \ + "push 0" \ + "push 0" \ + "mov [esp+1], eax" \ + "push 0" \ + "push 0" \ + "push 0" \ + "push ebx" \ + "push 4" \ + "mov ebx, esp" \ + "mov eax, 70" \ + "int 0x40" \ + "add esp, 28" \ + parm [EAX] [EBX] value [EAX] \ + modify [ EBX ]; + #pragma aux get_fileinfo = \ "push 0" \ "push 0" \ diff --git a/programs/develop/open watcom/trunk/clib/handleio/chsizklbr.c b/programs/develop/open watcom/trunk/clib/handleio/chsizklbr.c new file mode 100644 index 0000000000..a0d14e2af5 --- /dev/null +++ b/programs/develop/open watcom/trunk/clib/handleio/chsizklbr.c @@ -0,0 +1,82 @@ +/**************************************************************************** +* +* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE +* DESCRIBE IT HERE! +* +****************************************************************************/ + + +#include "variety.h" +#include +#include +#include "iomode.h" +#include "fileacc.h" +#include "rtcheck.h" +#include "seterrno.h" +#include "lseek.h" +#include "kolibri.h" + +typedef struct +{ + char *name; + unsigned int offset; +}__file_handle; + +_WCRTLINK int chsize( int hid, long size ) +{ + long curOffset; + long rc; + __file_handle *fh; + + __handle_check( hid, -1 ); + fh = (__file_handle*) __getOSHandle( hid ); + + _AccessFileH( hid ); + + curOffset = __lseek( hid, 0L, SEEK_CUR ); /* get current offset */ + + rc = set_file_size(fh->name, size); + + if(rc !=0 ) + { + _ReleaseFileH( hid ); + if(rc==8) + __set_errno( ENOSPC ); + else + __set_errno( EACCES ); + return -1; + }; + + if( curOffset > size ) curOffset = size; + curOffset = __lseek( hid, curOffset, SEEK_SET ); + _ReleaseFileH( hid ); + if( curOffset == -1 ) { + __set_errno(ENOSPC); + return( -1 ); + } + return( 0 ); +} diff --git a/programs/develop/open watcom/trunk/clib/handleio/fstat.c b/programs/develop/open watcom/trunk/clib/handleio/fstat.c new file mode 100644 index 0000000000..f835cd45e3 --- /dev/null +++ b/programs/develop/open watcom/trunk/clib/handleio/fstat.c @@ -0,0 +1,135 @@ +/**************************************************************************** +* +* 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: OS/2 implementation of fstat(). +* +****************************************************************************/ + + +#include "variety.h" +#include "widechar.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "iomode.h" +#include "rtcheck.h" +#include "seterrno.h" +#include "kolibri.h" + +typedef struct +{ + char *name; + unsigned int offset; +}__file_handle; + + +static unsigned short at2mode( int attr ) +/***************************************/ + { + register unsigned short mode; + + if( attr & 0x10 ) { + mode = S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; + } else { + mode = S_IFREG; + } + mode |= S_IRUSR | S_IRGRP | S_IROTH; + if( !(attr & (0x04 | 0x01 ) ) ) { + mode |= S_IWUSR | S_IWGRP | S_IWOTH; + } + return( mode ); + } + + +#ifdef __WIDECHAR__ +_WCRTLINK int _wfstat( int handle, struct _stat *buf ) +#else +_WCRTLINK int fstat( int handle, struct stat *buf ) +#endif + { + __file_handle *fh; + FILEINFO info; + int err; + struct tm time; + + __handle_check( handle, -1 ); + + fh = (__file_handle*) __getOSHandle(handle); + err = get_fileinfo(fh->name,&info); + + if(err) + return (-1); + + buf->st_mode = at2mode(info.attr); + + time.tm_sec = info.ctime.sec; + time.tm_min = info.ctime.min; + time.tm_hour = info.ctime.hour; + time.tm_mday = info.cdate.day; + time.tm_mon = info.cdate.month; + time.tm_year = info.cdate.year - 1900; + time.tm_isdst = -1; + buf->st_ctime = mktime(&time); + + time.tm_sec = info.atime.sec; + time.tm_min = info.atime.min; + time.tm_hour = info.atime.hour; + time.tm_mday = info.adate.day; + time.tm_mon = info.adate.month; + time.tm_year = info.adate.year - 1900; + time.tm_isdst = -1; + buf->st_atime = mktime(&time); + + time.tm_sec = info.mtime.sec; + time.tm_min = info.mtime.min; + time.tm_hour = info.mtime.hour; + time.tm_mday = info.mdate.day; + time.tm_mon = info.mdate.month; + time.tm_year = info.mdate.year - 1900; + time.tm_isdst = -1; + buf->st_mtime = mktime(&time); + + buf->st_size = info.size; + buf->st_dev = buf->st_rdev = 0; + buf->st_attr = info.attr; + buf->st_nlink = 1; + buf->st_ino = handle; + buf->st_uid = buf->st_gid = 0; + + buf->st_btime = buf->st_mtime; + buf->st_archivedID = 0; + buf->st_updatedID = 0; + buf->st_inheritedRightsMask = 0; + buf->st_originatingNameSpace = 0; + + return( 0 ); +}; + diff --git a/programs/develop/open watcom/trunk/clib/handleio/openklbr.c b/programs/develop/open watcom/trunk/clib/handleio/openklbr.c index 8681837251..167e377557 100644 --- a/programs/develop/open watcom/trunk/clib/handleio/openklbr.c +++ b/programs/develop/open watcom/trunk/clib/handleio/openklbr.c @@ -67,7 +67,11 @@ char* getfullpath(const char* path) int len=0, depth=0, i; char* buff; char c; - + + + buff = (char*)lib_malloc(strlen(path)+2); + strcpy(buff, path); + if(*path == '/') { buff = (char*)lib_malloc(strlen(path)+1); @@ -127,6 +131,7 @@ char* getfullpath(const char* path) }; }; buff[len]= '\0'; + return buff; }; @@ -170,11 +175,20 @@ static HANDLE __openFileHandle(const CHAR_TYPE *name, int mode) int err; path = getfullpath(name); + + err=get_fileinfo(path,&info); - if(err=get_fileinfo(path,&info)) + if( mode & O_EXCL && mode & O_CREAT ) + { + if( !err) + { + __set_errno( EEXIST ); + return (HANDLE)-1; + }; + } + + if(err) { -// printf("failed getfileinfo %s\n\r", path); - if(mode & O_CREAT) err=create_file(path); @@ -184,9 +198,12 @@ static HANDLE __openFileHandle(const CHAR_TYPE *name, int mode) return (HANDLE)-1; }; }; - + if( mode & O_TRUNC ) + set_file_size(path, 0); + if ( !(handle=(__file_handle*)lib_malloc(sizeof( __file_handle) ))) - { lib_free(path); + { + lib_free(path); return (HANDLE)-1; }; @@ -211,8 +228,7 @@ static int __F_NAME(_sopen,__wsopen)( const CHAR_TYPE *name, int mode, int share return( -1 ); } - rwmode = mode; - + rwmode = mode & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT ); /*** Open the file ***/ @@ -225,11 +241,11 @@ static int __F_NAME(_sopen,__wsopen)( const CHAR_TYPE *name, int mode, int share } // Now use the slot we got. + __setOSHandle( hid, handle ); // JBS 99/11/01 iomode_flags = 0; - if( rwmode == O_RDWR ) iomode_flags |= _READ | _WRITE; else if( rwmode == O_RDONLY) iomode_flags |= _READ; else if( rwmode == O_WRONLY) iomode_flags |= _WRITE; diff --git a/programs/develop/open watcom/trunk/clib/handleio/oshdl.c b/programs/develop/open watcom/trunk/clib/handleio/oshdl.c new file mode 100644 index 0000000000..054026150e --- /dev/null +++ b/programs/develop/open watcom/trunk/clib/handleio/oshdl.c @@ -0,0 +1,54 @@ +/**************************************************************************** +* +* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE +* DESCRIBE IT HERE! +* +****************************************************************************/ + + +#include "variety.h" +#include +#include +#include "iomode.h" +#include "rtcheck.h" +#include "seterrno.h" + +// Note: there are no OS handles under anything other than Win32 + +_WCRTLINK long _get_osfhandle( int posix_handle ) +{ + long os_handle; + + __handle_check( posix_handle, -1 ); + os_handle = (long) __getOSHandle( posix_handle ); + return( os_handle ); +} + +_WCRTLINK int _os_handle( int posix_handle ) +{ + return( (int) _get_osfhandle( posix_handle ) ); +} diff --git a/programs/develop/open watcom/trunk/clib/handleio/qread.c b/programs/develop/open watcom/trunk/clib/handleio/qread.c index 456dd3819b..13db288086 100644 --- a/programs/develop/open watcom/trunk/clib/handleio/qread.c +++ b/programs/develop/open watcom/trunk/clib/handleio/qread.c @@ -46,19 +46,19 @@ typedef struct int __qread( int handle, void *buffer, unsigned len ) { + int err; + __file_handle *fh; unsigned amount_read=0; __handle_check( handle, -1 ); fh = (__file_handle*) __getOSHandle( handle ); - - if(read_file(fh->name,buffer,fh->offset,len,&amount_read)) - { + + err = read_file(fh->name,buffer,fh->offset,len,&amount_read); + fh->offset+=amount_read; + if(err) if ( amount_read == 0) return (-1); - - } - fh->offset+=amount_read; return( amount_read ); }; diff --git a/programs/develop/open watcom/trunk/clib/handleio/read.c b/programs/develop/open watcom/trunk/clib/handleio/read.c index a41d654950..09bb971caf 100644 --- a/programs/develop/open watcom/trunk/clib/handleio/read.c +++ b/programs/develop/open watcom/trunk/clib/handleio/read.c @@ -41,6 +41,7 @@ #include "rtdata.h" #include "seterrno.h" #include "lseek.h" +#include "kolibri.h" typedef struct { @@ -48,9 +49,6 @@ typedef struct unsigned int offset; }__file_handle; - -int _stdcall read_file (const char *name,char *buff,unsigned offset, unsigned count,unsigned *reads); - _WCRTLINK int read( int handle, void *buf, unsigned len ) { unsigned read_len, total_len; @@ -60,8 +58,11 @@ _WCRTLINK int read( int handle, void *buf, unsigned len ) BOOL rc; HANDLE h; unsigned amount_read; + int err; + __file_handle *fh; + __handle_check( handle, -1 ); __ChkTTYIOMode( handle ); iomode_flags = __GetIOMode( handle ); @@ -82,13 +83,14 @@ _WCRTLINK int read( int handle, void *buf, unsigned len ) if( iomode_flags & _BINARY ) /* if binary mode */ { - if(read_file(fh->name,buffer,fh->offset,len,&amount_read)) - { - if ( amount_read == 0) - return (-1); - } + 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 { @@ -96,13 +98,12 @@ _WCRTLINK int read( int handle, void *buf, unsigned len ) read_len = len; do { - if(read_file(fh->name,buffer,fh->offset,len,&amount_read)) - { - if( amount_read == 0 ) - { /* EOF */ - break; - } - } + 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 ) diff --git a/programs/develop/open watcom/trunk/clib/handleio/setmd.c b/programs/develop/open watcom/trunk/clib/handleio/setmd.c new file mode 100644 index 0000000000..0adcf5ca5f --- /dev/null +++ b/programs/develop/open watcom/trunk/clib/handleio/setmd.c @@ -0,0 +1,91 @@ +/**************************************************************************** +* +* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE +* DESCRIBE IT HERE! +* +****************************************************************************/ + + +#include "variety.h" +#include +#include +#if defined(__NT__) + // #include +#endif +#include +#include "fcntl.h" +#include "dos.h" +#include "dosfunc.h" +#include "fileacc.h" +#include "rtcheck.h" +#include "rtdata.h" +#include "iomode.h" +#include "seterrno.h" + +_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 ) { + __set_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 { + __set_errno( EINVAL ); + old_mode = -1; + } + } + return( old_mode ); +} diff --git a/programs/develop/open watcom/trunk/clib/handleio/write.c b/programs/develop/open watcom/trunk/clib/handleio/write.c index 7c77b48b31..ecf565c200 100644 --- a/programs/develop/open watcom/trunk/clib/handleio/write.c +++ b/programs/develop/open watcom/trunk/clib/handleio/write.c @@ -44,6 +44,7 @@ #include "rtdata.h" #include "seterrno.h" #include "lseek.h" +#include "kolibri.h" /* The _lwrite function writes data to the specified file. @@ -142,8 +143,6 @@ typedef struct unsigned int offset; }__file_handle; -int _stdcall write_file (const char *name,const void* buff,unsigned offset, unsigned count,unsigned *reads); - static int os_write( int handle, const void *buffer, unsigned len, unsigned *amt ) /********************************************************************************/ { @@ -154,11 +153,8 @@ static int os_write( int handle, const void *buffer, unsigned len, unsigned *amt fh = (__file_handle*) __getOSHandle( handle ); - if(write_file(fh->name,buffer,fh->offset,len,amt)) - { - rc = __set_errno_nt(); - }; - + rc = write_file(fh->name,buffer,fh->offset,len,amt); + fh->offset+= *amt; if( *amt != len ) {