/*** *chsize.c - OS/2 change size of a file * * Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved. * *Purpose: * contains the _chsize() function - changes the size of a file. * *Revision History: * 03-13-84 RN initial version * 05-17-86 SKS ported to OS/2 * 07-07-87 JCR Added (_doserrno == 5) check that is in DOS 3.2 version * 10-29-87 JCR Multi-thread support; also, re-wrote for efficiency * 12-11-87 JCR Added "_LOAD_DS" to declaration * 05-25-88 PHG Merged DLL and normal versions * 10-03-88 GJF Changed DOSNEWSIZE to SYSNEWSIZE * 10-10-88 GJF Made API names match DOSCALLS.H * 04-13-89 JCR New syscall interface * 05-25-89 JCR 386 OS/2 calls use '_syscall' calling convention * 03-12-90 GJF Replaced _LOAD_DS with _CALLTYPE1, added #include * , removed #include and fixed * the copyright. Also, cleaned up the formatting a bit. * 04-04-90 GJF Added #include , removed #include . * 05-21-90 GJF Fixed stack checking pragma syntax. * 07-24-90 SBM Replaced by , removed '32' * from API names * 09-28-90 GJF New-style function declarator. * 12-03-90 GJF Appended Win32 version of the function. It is based * on the Cruiser version and probably could be merged * in later (much later). * 12-04-90 SRW Changed to include instead of * 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo * 12-28-90 SRW Added _CRUISER_ conditional around check_stack pragma * 01-16-91 GJF ANSI naming. Also, fixed _chsize_lk parameter decls. * 02-07-91 SRW Changed to call _get_osfhandle [_WIN32_] * 04-09-91 PNT Added _MAC_ conditional * 02-13-92 GJF Replaced _nfile by _nhandle for Win32. * 05-01-92 GJF Fixed embarrassing bug (didn't work for Win32)! * *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _CRUISER_ #pragma check_stack(on) /* turn stack probes on */ #endif /* ndef _CRUISER_ */ /*** *int _chsize(filedes, size) - change size of a file * *Purpose: * Change file size. Assume file is open for writing, or we can't do it. * The DOS way to do this is to go to the right spot and write 0 bytes. The * Xenix way to do this is to make a system call. We write '\0' bytes because * DOS won't do this for you if you lseek beyond eof, though Xenix will. * *Entry: * int filedes - file handle to change size of * long size - new size of file * *Exit: * return 0 if successful * returns -1 and sets errno if fails * *Exceptions: * *******************************************************************************/ #ifdef MTHREAD /* define normal version that locks/unlocks, validates fh */ int _CALLTYPE1 _chsize ( REG1 int filedes, long size ) { int r; /* return value */ #ifdef _WIN32_ if ( (unsigned)filedes >= (unsigned)_nhandle ) { #else if (filedes < 0 || filedes >= _nfile) { #endif errno = EBADF; return(-1); } _lock_fh(filedes); r = _chsize_lk(filedes,size); _unlock_fh(filedes); return r; } /* now define version that doesn't lock/unlock, validate fh */ int _CALLTYPE1 _chsize_lk ( REG1 int filedes, long size ) { long filend; long extend; long place; int cnt; char blanks[BUFSIZ]; REG2 char *bl = blanks; int oldmode; int retval = 0; /* assume good return */ #else /* now define normal version */ int _CALLTYPE1 _chsize ( REG1 int filedes, long size ) { long filend; long extend; long place; int cnt; char blanks[BUFSIZ]; REG2 char *bl = blanks; int oldmode; int retval = 0; /* assume good return */ #ifdef _WIN32_ if ( (unsigned)filedes >= (unsigned)_nhandle ) { #else if (filedes < 0 || filedes >= _nfile) { #endif errno = EBADF; return(-1); } #endif assert(size >= 0); /* Get current file position and seek to end */ if ( ((place = _lseek_lk(filedes, 0L, SEEK_CUR)) == -1L) || ((filend = _lseek_lk(filedes, 0L, SEEK_END)) == -1L) ) return -1; extend = size - filend; /* Grow or shrink the file as necessary */ if (extend > 0L) { /* extending the file */ memset(bl, '\0', BUFSIZ); oldmode = _setmode_lk(filedes, _O_BINARY); /* pad out with nulls */ do { cnt = (extend >= (long)BUFSIZ ) ? BUFSIZ : (int)extend; if ( ( cnt = _write_lk( filedes, bl, (extend >= (long)BUFSIZ ) ? BUFSIZ : (int)extend)) == -1 ) { /* Error on write */ if (_doserrno == ERROR_ACCESS_DENIED) errno = EACCES; retval = cnt; break; /* leave write loop */ } } while ((extend -= (long)cnt) > 0L); _setmode_lk(filedes, oldmode); /* retval set correctly */ } else if (extend < 0L) { /* shortening the file */ #ifdef _CRUISER_ retval = ( DOSSETFILESIZE(filedes, size) ? -1 : 0 ); #else /* ndef _CRUISER_ */ #ifdef _WIN32_ /* * Set file pointer to new eof...and truncate it there. */ _lseek_lk(filedes, size, SEEK_SET); if ( (retval = SetEndOfFile((HANDLE)_get_osfhandle(filedes)) ? 0 : -1) == -1 ) { errno = EACCES; _doserrno = GetLastError(); } #else /* ndef _WIN32_ */ #ifdef _MAC_ TBD(); #else /* ndef _MAC_ */ #error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED! #endif /* _MAC_ */ #endif /* _WIN32_ */ #endif /* _CRUISER_ */ } /* else */ /* no file change needed */ /* retval = 0; */ /* Common return code */ _lseek_lk(filedes, place, SEEK_SET); return retval; }