xref: /aosp_15_r20/external/libchrome-gestures/src/file_util.cc (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
1*aed3e508SAndroid Build Coastguard Worker // Copyright 2014 The ChromiumOS Authors
2*aed3e508SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*aed3e508SAndroid Build Coastguard Worker // found in the LICENSE file.
4*aed3e508SAndroid Build Coastguard Worker 
5*aed3e508SAndroid Build Coastguard Worker #include "include/file_util.h"
6*aed3e508SAndroid Build Coastguard Worker 
7*aed3e508SAndroid Build Coastguard Worker #include <fcntl.h>
8*aed3e508SAndroid Build Coastguard Worker #include <limits>
9*aed3e508SAndroid Build Coastguard Worker #include <sys/types.h>
10*aed3e508SAndroid Build Coastguard Worker #include <sys/stat.h>
11*aed3e508SAndroid Build Coastguard Worker #include <unistd.h>
12*aed3e508SAndroid Build Coastguard Worker 
13*aed3e508SAndroid Build Coastguard Worker #include "include/eintr_wrapper.h"
14*aed3e508SAndroid Build Coastguard Worker 
15*aed3e508SAndroid Build Coastguard Worker namespace gestures {
16*aed3e508SAndroid Build Coastguard Worker 
OpenFile(const char * filename,const char * mode)17*aed3e508SAndroid Build Coastguard Worker FILE* OpenFile(const char* filename, const char* mode) {
18*aed3e508SAndroid Build Coastguard Worker   FILE* result = nullptr;
19*aed3e508SAndroid Build Coastguard Worker   do {
20*aed3e508SAndroid Build Coastguard Worker     result = fopen(filename, mode);
21*aed3e508SAndroid Build Coastguard Worker   } while (!result && errno == EINTR);
22*aed3e508SAndroid Build Coastguard Worker   return result;
23*aed3e508SAndroid Build Coastguard Worker }
24*aed3e508SAndroid Build Coastguard Worker 
CloseFile(FILE * file)25*aed3e508SAndroid Build Coastguard Worker bool CloseFile(FILE* file) {
26*aed3e508SAndroid Build Coastguard Worker   if (file == nullptr)
27*aed3e508SAndroid Build Coastguard Worker     return true;
28*aed3e508SAndroid Build Coastguard Worker   return fclose(file) == 0;
29*aed3e508SAndroid Build Coastguard Worker }
30*aed3e508SAndroid Build Coastguard Worker 
ReadFileToString(const char * path,std::string * contents,size_t max_size)31*aed3e508SAndroid Build Coastguard Worker bool ReadFileToString(const char* path,
32*aed3e508SAndroid Build Coastguard Worker                       std::string* contents,
33*aed3e508SAndroid Build Coastguard Worker                       size_t max_size) {
34*aed3e508SAndroid Build Coastguard Worker   if (contents)
35*aed3e508SAndroid Build Coastguard Worker     contents->clear();
36*aed3e508SAndroid Build Coastguard Worker   FILE* file = OpenFile(path, "rb");
37*aed3e508SAndroid Build Coastguard Worker   if (!file) {
38*aed3e508SAndroid Build Coastguard Worker     return false;
39*aed3e508SAndroid Build Coastguard Worker   }
40*aed3e508SAndroid Build Coastguard Worker 
41*aed3e508SAndroid Build Coastguard Worker   char buf[1 << 16];
42*aed3e508SAndroid Build Coastguard Worker   size_t len;
43*aed3e508SAndroid Build Coastguard Worker   size_t size = 0;
44*aed3e508SAndroid Build Coastguard Worker   bool read_status = true;
45*aed3e508SAndroid Build Coastguard Worker 
46*aed3e508SAndroid Build Coastguard Worker   // Many files supplied in |path| have incorrect size (proc files etc).
47*aed3e508SAndroid Build Coastguard Worker   // Hence, the file is read sequentially as opposed to a one-shot read.
48*aed3e508SAndroid Build Coastguard Worker   while ((len = fread(buf, 1, sizeof(buf), file)) > 0) {
49*aed3e508SAndroid Build Coastguard Worker     if (contents)
50*aed3e508SAndroid Build Coastguard Worker       contents->append(buf, std::min(len, max_size - size));
51*aed3e508SAndroid Build Coastguard Worker 
52*aed3e508SAndroid Build Coastguard Worker     if ((max_size - size) < len) {
53*aed3e508SAndroid Build Coastguard Worker       read_status = false;
54*aed3e508SAndroid Build Coastguard Worker       break;
55*aed3e508SAndroid Build Coastguard Worker     }
56*aed3e508SAndroid Build Coastguard Worker 
57*aed3e508SAndroid Build Coastguard Worker     size += len;
58*aed3e508SAndroid Build Coastguard Worker   }
59*aed3e508SAndroid Build Coastguard Worker   CloseFile(file);
60*aed3e508SAndroid Build Coastguard Worker 
61*aed3e508SAndroid Build Coastguard Worker   return read_status;
62*aed3e508SAndroid Build Coastguard Worker }
63*aed3e508SAndroid Build Coastguard Worker 
ReadFileToString(const char * path,std::string * contents)64*aed3e508SAndroid Build Coastguard Worker bool ReadFileToString(const char* path, std::string* contents) {
65*aed3e508SAndroid Build Coastguard Worker   return ReadFileToString(path, contents, std::numeric_limits<size_t>::max());
66*aed3e508SAndroid Build Coastguard Worker }
67*aed3e508SAndroid Build Coastguard Worker 
WriteFileDescriptor(const int fd,const char * data,int size)68*aed3e508SAndroid Build Coastguard Worker int WriteFileDescriptor(const int fd, const char* data, int size) {
69*aed3e508SAndroid Build Coastguard Worker   // Allow for partial writes.
70*aed3e508SAndroid Build Coastguard Worker   ssize_t bytes_written_total = 0;
71*aed3e508SAndroid Build Coastguard Worker   for (ssize_t bytes_written_partial = 0; bytes_written_total < size;
72*aed3e508SAndroid Build Coastguard Worker        bytes_written_total += bytes_written_partial) {
73*aed3e508SAndroid Build Coastguard Worker     bytes_written_partial =
74*aed3e508SAndroid Build Coastguard Worker         HANDLE_EINTR(write(fd, data + bytes_written_total,
75*aed3e508SAndroid Build Coastguard Worker                            size - bytes_written_total));
76*aed3e508SAndroid Build Coastguard Worker     if (bytes_written_partial < 0)
77*aed3e508SAndroid Build Coastguard Worker       return -1;
78*aed3e508SAndroid Build Coastguard Worker   }
79*aed3e508SAndroid Build Coastguard Worker 
80*aed3e508SAndroid Build Coastguard Worker   return bytes_written_total;
81*aed3e508SAndroid Build Coastguard Worker }
82*aed3e508SAndroid Build Coastguard Worker 
WriteFile(const char * filename,const char * data,int size)83*aed3e508SAndroid Build Coastguard Worker int WriteFile(const char *filename, const char* data, int size) {
84*aed3e508SAndroid Build Coastguard Worker   int fd = HANDLE_EINTR(creat(filename, 0666));
85*aed3e508SAndroid Build Coastguard Worker   if (fd < 0)
86*aed3e508SAndroid Build Coastguard Worker     return -1;
87*aed3e508SAndroid Build Coastguard Worker 
88*aed3e508SAndroid Build Coastguard Worker   int bytes_written = WriteFileDescriptor(fd, data, size);
89*aed3e508SAndroid Build Coastguard Worker   if (int ret = IGNORE_EINTR(close(fd)) < 0)
90*aed3e508SAndroid Build Coastguard Worker     return ret;
91*aed3e508SAndroid Build Coastguard Worker   return bytes_written;
92*aed3e508SAndroid Build Coastguard Worker }
93*aed3e508SAndroid Build Coastguard Worker 
94*aed3e508SAndroid Build Coastguard Worker }  // namespace gestures
95