Reactos
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.
16template <typename Integer>
17_Success_(return != -1)
18static 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
55extern "C" long __cdecl _filelength(int const fh)
56{
57 return common_filelength<long>(fh);
58}
59
60extern "C" __int64 __cdecl _filelengthi64(int const fh)
61{
62 return common_filelength<__int64>(fh);
63}