1 /* loadfile.cc: load a file into a std::string.
3 * Copyright (C) 2006,2010,2012,2015 Olly Betts
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifdef HAVE_POSIX_FADVISE
24 # define _POSIX_C_SOURCE 200112L // for posix_fadvise from fcntl.h
25 # define _DEFAULT_SOURCE 1 // Needed to get lstat() for glibc >= 2.20
26 # define _BSD_SOURCE 1 // Needed to get lstat() for glibc < 2.20
35 #include "safeerrno.h"
36 #include "safefcntl.h"
37 #include <sys/types.h>
38 #include "safesysstat.h"
39 #include "safeunistd.h"
44 load_file_fd(const string
&file_name
, size_t max_to_read
, int flags
,
45 string
&output
, bool &truncated
)
47 (void)flags
; // Avoid possible "unused" warning.
48 mode_t mode
= O_RDONLY
;
49 #if defined O_NOATIME && O_NOATIME != 0
50 if (flags
& NOATIME
) mode
|= O_NOATIME
;
53 int fd
= open(file_name
.c_str(), mode
);
54 #if defined O_NOATIME && O_NOATIME != 0
55 if (fd
< 0 && (mode
& O_NOATIME
)) {
57 fd
= open(file_name
.c_str(), mode
);
60 if (fd
< 0) return -1;
62 #ifdef HAVE_POSIX_FADVISE
64 posix_fadvise(fd
, 0, 0, POSIX_FADV_NOREUSE
); // or POSIX_FADV_SEQUENTIAL
68 if (fstat(fd
, &st
) < 0) {
69 int errno_save
= errno
;
75 if (!S_ISREG(st
.st_mode
)) {
82 size_t n
= st
.st_size
;
83 truncated
= (max_to_read
&& max_to_read
< n
);
92 int c
= read(fd
, blk
, min(n
, sizeof(blk
)));
94 if (c
< 0 && errno
== EINTR
) continue;
97 output
.append(blk
, c
);
101 #ifdef HAVE_POSIX_FADVISE
103 posix_fadvise(fd
, 0, 0, POSIX_FADV_DONTNEED
);
110 load_file(const string
&file_name
, size_t max_to_read
, int flags
,
111 string
&output
, bool &truncated
) {
112 int fd
= load_file_fd(file_name
, max_to_read
, flags
, output
, truncated
);