Drop special handling for Compaq C++
[xapian.git] / xapian-applications / omega / loadfile.cc
blobe9abddd5bac412885dad4226cb06e30ec5835712
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
20 #include <config.h>
22 #ifdef HAVE_POSIX_FADVISE
23 # ifdef __linux__
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
27 # endif
28 #endif
30 #include "loadfile.h"
32 #include <algorithm>
33 #include <cerrno>
34 #include <string>
36 #include "safefcntl.h"
37 #include <sys/types.h>
38 #include "safesysstat.h"
39 #include "safeunistd.h"
41 using namespace std;
43 int
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;
51 #endif
53 int fd = open(file_name.c_str(), mode);
54 #if defined O_NOATIME && O_NOATIME != 0
55 if (fd < 0 && (mode & O_NOATIME)) {
56 mode &= ~O_NOATIME;
57 fd = open(file_name.c_str(), mode);
59 #endif
60 if (fd < 0) return -1;
62 #ifdef HAVE_POSIX_FADVISE
63 if (flags & NOCACHE)
64 posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE); // or POSIX_FADV_SEQUENTIAL
65 #endif
67 struct stat st;
68 if (fstat(fd, &st) < 0) {
69 int errno_save = errno;
70 close(fd);
71 errno = errno_save;
72 return -1;
75 if (!S_ISREG(st.st_mode)) {
76 close(fd);
77 errno = EINVAL;
78 return -1;
81 char blk[4096];
82 size_t n = st.st_size;
83 truncated = (max_to_read && max_to_read < n);
84 if (truncated) {
85 n = max_to_read;
86 truncated = true;
89 output.resize(0);
90 output.reserve(n);
91 while (n) {
92 int c = read(fd, blk, min(n, sizeof(blk)));
93 if (c <= 0) {
94 if (c < 0 && errno == EINTR) continue;
95 break;
97 output.append(blk, c);
98 n -= c;
101 #ifdef HAVE_POSIX_FADVISE
102 if (flags & NOCACHE)
103 posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
104 #endif
106 return fd;
109 bool
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);
113 if (fd >= 0)
114 close(fd);
115 return (fd >= 0);