42 #include <sys/types.h>
46 #include <boost/shared_array.hpp>
47 #include <boost/shared_ptr.hpp>
61 char *buf = file_to_buffer(fname, &len);
63 contents.append(buf, len);
79 if ((nread = ::read(fd, ptr, nleft)) < 0) {
82 else if (errno == EAGAIN)
105 if ((nread = ::pread(fd, ptr, nleft, offset)) < 0) {
108 else if (errno == EAGAIN)
125 int fd = open(fname.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
127 int saved_errno = errno;
128 HT_ERRORF(
"Unable to open file \"%s\" for writing - %s", fname.c_str(),
129 strerror(saved_errno));
133 ssize_t rval = write(fd, contents);
144 ptr = (
const char *)vptr;
147 if ((nwritten = ::write(fd, ptr, nleft)) <= 0) {
150 else if (errno == EAGAIN)
164 while ((nwritten = ::writev(fd, vector, count)) <= 0) {
167 else if (errno == EAGAIN) {
179 const sockaddr *to, socklen_t tolen) {
184 ptr = (
const char *)vptr;
187 if ((nsent = ::sendto(fd, ptr, nleft, 0, to, tolen)) <= 0) {
190 else if (errno == EAGAIN || errno == ENOBUFS)
208 ptr = (
const char *)vptr;
211 if ((nsent = ::send(fd, ptr, nleft, 0)) <= 0) {
214 else if (errno == EAGAIN || errno == ENOBUFS)
228 socklen_t *fromlen) {
231 if ((nread = ::recvfrom(fd, vptr, n, 0, from, fromlen)) < 0) {
245 if ((nread = ::recv(fd, vptr, n, 0)) < 0) {
260 if ((val = fcntl(fd, F_GETFL, 0)) < 0) {
261 int saved_errno = errno;
262 HT_ERROR_OUT <<
"fcnt(F_GETFL) failed : " << ::strerror(saved_errno)
270 if (fcntl(fd, F_SETFL, val) < 0) {
271 int saved_errno = errno;
272 HT_ERROR_OUT <<
"fcnt(F_SETFL) failed : " << ::strerror(saved_errno)
288 if ((fd = open(fname.c_str(), O_RDONLY)) < 0) {
289 int saved_errno = errno;
290 HT_ERRORF(
"open(\"%s\") failure - %s", fname.c_str(),
291 strerror(saved_errno));
296 if (fstat(fd, &statbuf) < 0) {
297 int saved_errno = errno;
298 HT_ERRORF(
"fstat(\"%s\") failure - %s", fname.c_str(),
299 strerror(saved_errno));
304 *lenp = statbuf.st_size;
306 char *rbuf =
new char [*lenp + 1];
312 if (nread == (ssize_t)-1) {
313 int saved_errno = errno;
314 HT_ERRORF(
"read(\"%s\") failure - %s", fname.c_str(),
315 strerror(saved_errno));
323 HT_WARNF(
"short read (%d of %d bytes)", (
int)nread, (
int)*lenp);
336 char *contents = file_to_buffer(fname, &len);
337 str = (contents == 0) ?
"" : contents;
348 if (::stat(fname.c_str(), &statbuf) != 0)
349 HT_FATALF(
"Unable determine length of '%s' for memory mapping - %s",
350 fname.c_str(), strerror(errno));
351 *lenp = (off_t)statbuf.st_size;
353 if ((fd = ::open(fname.c_str(), O_RDONLY)) == -1)
354 HT_FATALF(
"Unable to open '%s' for memory mapping - %s", fname.c_str(),
357 if ((map = ::mmap(0, *lenp, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)
358 HT_FATALF(
"Unable to memory map file '%s' - %s", fname.c_str(),
368 boost::shared_array<char> tmp_dir(
new char [dirname.length() + 1]);
369 char *tmpdir = tmp_dir.get();
370 char *ptr = tmpdir + 1;
372 strcpy(tmpdir, dirname.c_str());
374 while ((ptr = strchr(ptr,
'/')) != 0) {
376 if (stat(tmpdir, &statbuf) != 0) {
377 if (errno == ENOENT) {
378 if (mkdir(tmpdir, 0755) != 0) {
379 int saved_errno = errno;
380 HT_ERRORF(
"Problem creating directory '%s' - %s", tmpdir,
381 strerror(saved_errno));
387 int saved_errno = errno;
388 HT_ERRORF(
"Problem stat'ing directory '%s' - %s", tmpdir,
389 strerror(saved_errno));
397 if (stat(tmpdir, &statbuf) != 0) {
398 if (errno == ENOENT) {
399 if (mkdir(tmpdir, 0755) != 0) {
400 int saved_errno = errno;
401 HT_ERRORF(
"Problem creating directory '%s' - %s", tmpdir,
402 strerror(saved_errno));
408 int saved_errno = errno;
409 HT_ERRORF(
"Problem stat'ing directory '%s' - %s", tmpdir,
410 strerror(saved_errno));
422 if (stat(fname.c_str(), &statbuf) != 0)
428 if (::unlink(fname.c_str()) == -1) {
429 int saved_errno = errno;
430 HT_ERRORF(
"unlink(\"%s\") failed - %s", fname.c_str(),
431 strerror(saved_errno));
439 if (::rename(oldpath.c_str(), newpath.c_str()) == -1) {
440 int saved_errno = errno;
441 HT_ERRORF(
"rename(\"%s\", \"%s\") failed - %s",
442 oldpath.c_str(), newpath.c_str(), strerror(saved_errno));
452 if (stat(fname.c_str(), &statbuf) != 0)
454 return statbuf.st_size;
460 if (stat(fname.c_str(), &statbuf) != 0)
462 return statbuf.st_size;
467 if (path.find(
'/', path.length() - 1) == string::npos)
477 lock_guard<mutex> lock(ms_mutex);
480 struct passwd *prbuf;
483 if (fname.length() == 1 || fname[1] ==
'/') {
484 if (getpwuid_r(getuid() , &pbuf, buf, 256, &prbuf) != 0 || prbuf == 0)
486 fname = (
String)pbuf.pw_dir + fname.substr(1);
490 size_t first_slash = fname.find_first_of(
'/');
492 if (first_slash == string::npos)
493 name = fname.substr(1);
495 name = fname.substr(1, first_slash-1);
497 if (getpwnam_r(name.c_str() , &pbuf, buf, 256, &prbuf) != 0 || prbuf == 0)
500 if (first_slash == string::npos)
503 fname = (
String)pbuf.pw_dir + fname.substr(first_slash);
512 std::vector<struct dirent> &listing) {
514 DIR *dirp = opendir(dirname.c_str());
515 struct dirent de, *dep;
516 boost::shared_ptr<RE2> regex(fname_regex.length()
517 ?
new RE2(fname_regex)
521 if ((ret = readdir_r(dirp, &de, &dep)) != 0)
522 HT_FATALF(
"Problem reading directory '%s' - %s", dirname.c_str(),
525 if (dep != 0 && (!regex || RE2::FullMatch(de.d_name, *regex)))
526 listing.push_back(de);
529 (void)closedir(dirp);
static char * file_to_buffer(const String &fname, off_t *lenp)
Reads a full file into a new buffer; the buffer is allocated with operator new[], and the caller has ...
#define HT_WARNF(msg,...)
static std::mutex ms_mutex
Mutex for protecting thread-unsafe glibc library function calls.
static bool read(const String &fname, String &contents)
Reads a whole file into a String.
std::string String
A String is simply a typedef to std::string.
static bool unlink(const String &fname)
Unlinks (deletes) a file or directory.
static off_t length(const String &fname)
Returns the size of a file (-1 on error)
Po::typed_value< String > * str(String *v=0)
static ssize_t write(const String &fname, const std::string &contents)
Writes a String buffer to a file; the file is overwritten if it already exists.
static void add_trailing_slash(String &path)
Adds a trailing slash to a path.
static bool exists(const String &fname)
Checks if a file or directory exists.
static bool mkdirs(const String &dirname)
Creates a directory (with all parent directories, if required)
static ssize_t recvfrom(int fd, void *vptr, size_t n, struct sockaddr *from, socklen_t *fromlen)
Receives data from a network connection and returns the sender's address.
static ssize_t pread(int fd, void *vptr, size_t n, off_t offset)
Reads positional data from a file descriptor into a buffer.
static ssize_t sendto(int fd, const void *vptr, size_t n, const sockaddr *to, socklen_t tolen)
Sends data through a network connection; if the socket is TCP then the address is ignored...
static ssize_t send(int fd, const void *vptr, size_t n)
Sends data through a network connection.
static uint64_t size(const String &fname)
Returns the size of a file (0 on error)
File system utility functions.
Logging routines and macros.
Compatibility Macros for C/C++.
static bool expand_tilde(String &fname)
Expands a leading tilde character in a filename.
static bool set_flags(int fd, int flags)
Sets fcntl flags of a socket.
static void readdir(const String &dirname, const String &fname_regex, std::vector< struct dirent > &listing)
Reads all directory entries, applies a regular expression and returns those which match...
#define HT_FATALF(msg,...)
static void * mmap(const String &fname, off_t *lenp)
Maps a full file into memory using mmap; the mapping will be released when the application terminates...
static ssize_t writev(int fd, const struct iovec *vector, int count)
Atomically writes data from multiple buffers to a file descriptor.
#define HT_ERRORF(msg,...)
static bool rename(const String &oldpath, const String &newpath)
Renames a file or directory.
static ssize_t recv(int fd, void *vptr, size_t n)
Receives data from a network connection.
static String file_to_string(const String &fname)
Reads a full file into a String.