RESTinio
Loading...
Searching...
No Matches
sendfile_defs_posix.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
11#pragma once
12
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16
17#include <iostream>
18
19namespace restinio
20{
21
22#if defined( __FreeBSD__ )
23 #define RESTINIO_FREEBSD_TARGET
24#elif defined(__APPLE__) && defined( __MACH__ )
25 #define RESTINIO_MACOS_TARGET
26#endif
27
32using file_offset_t = std::int64_t;
33using file_size_t = std::uint64_t;
35
43
45[[nodiscard]]
46constexpr file_descriptor_t null_file_descriptor(){ return -1; }
47
49[[nodiscard]]
51open_file( const char * file_path)
52{
53#if defined( RESTINIO_FREEBSD_TARGET ) || defined( RESTINIO_MACOS_TARGET )
54 file_descriptor_t file_descriptor = ::open( file_path, O_RDONLY );
55#else
56 file_descriptor_t file_descriptor = ::open( file_path, O_RDONLY | O_LARGEFILE );
57#endif
58 if( null_file_descriptor() == file_descriptor )
59 {
60 throw exception_t{
61 fmt::format(
62 RESTINIO_FMT_FORMAT_STRING( "unable to openfile '{}': {}" ),
64 strerror( errno ) )
65 };
66 }
67 return file_descriptor;
68}
69
83[[nodiscard]]
85open_file( const std::filesystem::path & file_path )
86{
87 // Use c_str() on POSIX, because it's assumed that
88 // filesystem uses UTF-8.
89 return open_file( file_path.c_str() );
90}
91
93template < typename META >
94[[nodiscard]]
95META
97{
98 if( null_file_descriptor() == fd )
99 {
100 throw exception_t{ "invalid file descriptor" };
101 }
102
103#if defined( RESTINIO_FREEBSD_TARGET ) || defined( RESTINIO_MACOS_TARGET )
104 struct stat file_stat;
105
106 const auto fstat_rc = ::fstat( fd, &file_stat );
107#else
108 struct stat64 file_stat;
109
110 const auto fstat_rc = fstat64( fd, &file_stat );
111#endif
112
113 if( 0 != fstat_rc )
114 {
115 throw exception_t{
116 fmt::format(
117 RESTINIO_FMT_FORMAT_STRING( "unable to get file stat : {}" ),
118 strerror( errno ) )
119 };
120 }
121
122 const std::chrono::system_clock::time_point
124#if defined( RESTINIO_MACOS_TARGET )
125 std::chrono::seconds( file_stat.st_mtimespec.tv_sec ) +
126 std::chrono::microseconds( file_stat.st_mtimespec.tv_nsec / 1000 )
127#else
128 std::chrono::seconds( file_stat.st_mtim.tv_sec ) +
129 std::chrono::microseconds( file_stat.st_mtim.tv_nsec / 1000 )
130#endif
131 };
132
133 return META{ static_cast< file_size_t >( file_stat.st_size ), last_modified };
134}
135
137inline void
139{
140 ::close( fd );
141}
143
144} /* namespace restinio */
#define RESTINIO_FMT_FORMAT_STRING(s)
constexpr file_descriptor_t null_file_descriptor()
Get file descriptor which stands for null.
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
void close_file(file_descriptor_t fd)
Close file by its descriptor.
file_descriptor_t open_file(const char *file_path)
Open file.
std::FILE * file_descriptor_t
std::int64_t file_offset_t
META get_file_meta(file_descriptor_t fd)
Get file size.
std::uint64_t file_size_t