1 // 2 // filelength.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Defines _filelength(), which computes the length of a file. 7 // 8 #include <corecrt_internal_lowio.h> 9 #include <stddef.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 13 14 15 // Computes the length, in bytes, of the given file. Returns -1 on failure. 16 template <typename Integer> 17 _Success_(return != -1) 18 static Integer __cdecl common_filelength(int const fh) throw() 19 { 20 typedef __crt_integer_traits<Integer> traits; 21 22 _CHECK_FH_CLEAR_OSSERR_RETURN(fh, EBADF, -1); 23 _VALIDATE_CLEAR_OSSERR_RETURN(fh >= 0 && (unsigned)fh < (unsigned)_nhandle, EBADF, -1); 24 _VALIDATE_CLEAR_OSSERR_RETURN(_osfile(fh) & FOPEN, EBADF, -1); 25 26 __acrt_lowio_lock_fh(fh); 27 Integer end = -1; 28 __try 29 { 30 if ((_osfile(fh) & FOPEN) == 0) 31 { 32 errno = EBADF; 33 _doserrno = 0; 34 _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread", 0)); 35 __leave; 36 } 37 38 // Seek to the end to get the length: 39 Integer const here = traits::lseek_nolock(fh, 0, SEEK_CUR); 40 if (here == -1) 41 __leave; 42 43 end = traits::lseek_nolock(fh, 0, SEEK_END); 44 if (here != end) 45 traits::lseek_nolock(fh, here, SEEK_SET); 46 } 47 __finally 48 { 49 __acrt_lowio_unlock_fh(fh); 50 } 51 __endtry 52 return end; 53 } 54 55 extern "C" long __cdecl _filelength(int const fh) 56 { 57 return common_filelength<long>(fh); 58 } 59 60 extern "C" __int64 __cdecl _filelengthi64(int const fh) 61 { 62 return common_filelength<__int64>(fh); 63 } 64