xref: /reactos/sdk/lib/ucrt/lowio/filelength.cpp (revision fe11f7a2)
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