xref: /aosp_15_r20/external/google-breakpad/src/common/tests/file_utils.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1*9712c20fSFrederick Mayle // Copyright 2011 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle //     * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle //     * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle //     * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle 
29*9712c20fSFrederick Mayle // file_utils.cc: Implement utility functions for file manipulation.
30*9712c20fSFrederick Mayle // See file_utils.h for details.
31*9712c20fSFrederick Mayle 
32*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
33*9712c20fSFrederick Mayle #include <config.h>  // Must come first
34*9712c20fSFrederick Mayle #endif
35*9712c20fSFrederick Mayle 
36*9712c20fSFrederick Mayle #include <fcntl.h>
37*9712c20fSFrederick Mayle #include <stdio.h>
38*9712c20fSFrederick Mayle #include <string.h>
39*9712c20fSFrederick Mayle #include <sys/stat.h>
40*9712c20fSFrederick Mayle #include <unistd.h>
41*9712c20fSFrederick Mayle 
42*9712c20fSFrederick Mayle #include "common/linux/eintr_wrapper.h"
43*9712c20fSFrederick Mayle #include "common/tests/file_utils.h"
44*9712c20fSFrederick Mayle 
45*9712c20fSFrederick Mayle namespace google_breakpad {
46*9712c20fSFrederick Mayle 
CopyFile(const char * from_path,const char * to_path)47*9712c20fSFrederick Mayle bool CopyFile(const char* from_path, const char* to_path) {
48*9712c20fSFrederick Mayle   int infile = HANDLE_EINTR(open(from_path, O_RDONLY));
49*9712c20fSFrederick Mayle   if (infile < 0) {
50*9712c20fSFrederick Mayle     perror("open");
51*9712c20fSFrederick Mayle     return false;
52*9712c20fSFrederick Mayle   }
53*9712c20fSFrederick Mayle 
54*9712c20fSFrederick Mayle   int outfile = HANDLE_EINTR(creat(to_path, 0666));
55*9712c20fSFrederick Mayle   if (outfile < 0) {
56*9712c20fSFrederick Mayle     perror("creat");
57*9712c20fSFrederick Mayle     if (IGNORE_EINTR(close(infile)) < 0) {
58*9712c20fSFrederick Mayle       perror("close");
59*9712c20fSFrederick Mayle     }
60*9712c20fSFrederick Mayle     return false;
61*9712c20fSFrederick Mayle   }
62*9712c20fSFrederick Mayle 
63*9712c20fSFrederick Mayle   char buffer[1024];
64*9712c20fSFrederick Mayle   bool result = true;
65*9712c20fSFrederick Mayle 
66*9712c20fSFrederick Mayle   while (result) {
67*9712c20fSFrederick Mayle     ssize_t bytes_read = HANDLE_EINTR(read(infile, buffer, sizeof(buffer)));
68*9712c20fSFrederick Mayle     if (bytes_read < 0) {
69*9712c20fSFrederick Mayle       perror("read");
70*9712c20fSFrederick Mayle       result = false;
71*9712c20fSFrederick Mayle       break;
72*9712c20fSFrederick Mayle     }
73*9712c20fSFrederick Mayle     if (bytes_read == 0)
74*9712c20fSFrederick Mayle       break;
75*9712c20fSFrederick Mayle     ssize_t bytes_written_per_read = 0;
76*9712c20fSFrederick Mayle     do {
77*9712c20fSFrederick Mayle       ssize_t bytes_written_partial = HANDLE_EINTR(write(
78*9712c20fSFrederick Mayle           outfile,
79*9712c20fSFrederick Mayle           &buffer[bytes_written_per_read],
80*9712c20fSFrederick Mayle           bytes_read - bytes_written_per_read));
81*9712c20fSFrederick Mayle       if (bytes_written_partial < 0) {
82*9712c20fSFrederick Mayle         perror("write");
83*9712c20fSFrederick Mayle         result = false;
84*9712c20fSFrederick Mayle         break;
85*9712c20fSFrederick Mayle       }
86*9712c20fSFrederick Mayle       bytes_written_per_read += bytes_written_partial;
87*9712c20fSFrederick Mayle     } while (bytes_written_per_read < bytes_read);
88*9712c20fSFrederick Mayle   }
89*9712c20fSFrederick Mayle 
90*9712c20fSFrederick Mayle   if (IGNORE_EINTR(close(infile)) == -1) {
91*9712c20fSFrederick Mayle     perror("close");
92*9712c20fSFrederick Mayle     result = false;
93*9712c20fSFrederick Mayle   }
94*9712c20fSFrederick Mayle   if (IGNORE_EINTR(close(outfile)) == -1) {
95*9712c20fSFrederick Mayle     perror("close");
96*9712c20fSFrederick Mayle     result = false;
97*9712c20fSFrederick Mayle   }
98*9712c20fSFrederick Mayle 
99*9712c20fSFrederick Mayle   return result;
100*9712c20fSFrederick Mayle }
101*9712c20fSFrederick Mayle 
CopyFile(const std::string & from_path,const std::string & to_path)102*9712c20fSFrederick Mayle bool CopyFile(const std::string& from_path, const std::string& to_path) {
103*9712c20fSFrederick Mayle   return CopyFile(from_path.c_str(), to_path.c_str());
104*9712c20fSFrederick Mayle }
105*9712c20fSFrederick Mayle 
ReadFile(const char * path,void * buffer,ssize_t * buffer_size)106*9712c20fSFrederick Mayle bool ReadFile(const char* path, void* buffer, ssize_t* buffer_size) {
107*9712c20fSFrederick Mayle   int fd = HANDLE_EINTR(open(path, O_RDONLY));
108*9712c20fSFrederick Mayle   if (fd == -1) {
109*9712c20fSFrederick Mayle     perror("open");
110*9712c20fSFrederick Mayle     return false;
111*9712c20fSFrederick Mayle   }
112*9712c20fSFrederick Mayle 
113*9712c20fSFrederick Mayle   bool ok = true;
114*9712c20fSFrederick Mayle   if (buffer && buffer_size && *buffer_size > 0) {
115*9712c20fSFrederick Mayle     memset(buffer, 0, sizeof(*buffer_size));
116*9712c20fSFrederick Mayle     *buffer_size = HANDLE_EINTR(read(fd, buffer, *buffer_size));
117*9712c20fSFrederick Mayle     if (*buffer_size == -1) {
118*9712c20fSFrederick Mayle       perror("read");
119*9712c20fSFrederick Mayle       ok = false;
120*9712c20fSFrederick Mayle     }
121*9712c20fSFrederick Mayle   }
122*9712c20fSFrederick Mayle   if (IGNORE_EINTR(close(fd)) == -1) {
123*9712c20fSFrederick Mayle     perror("close");
124*9712c20fSFrederick Mayle     ok = false;
125*9712c20fSFrederick Mayle   }
126*9712c20fSFrederick Mayle   return ok;
127*9712c20fSFrederick Mayle }
128*9712c20fSFrederick Mayle 
WriteFile(const char * path,const void * buffer,size_t buffer_size)129*9712c20fSFrederick Mayle bool WriteFile(const char* path, const void* buffer, size_t buffer_size) {
130*9712c20fSFrederick Mayle   int fd = HANDLE_EINTR(open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU));
131*9712c20fSFrederick Mayle   if (fd == -1) {
132*9712c20fSFrederick Mayle     perror("open");
133*9712c20fSFrederick Mayle     return false;
134*9712c20fSFrederick Mayle   }
135*9712c20fSFrederick Mayle 
136*9712c20fSFrederick Mayle   bool ok = true;
137*9712c20fSFrederick Mayle   if (buffer) {
138*9712c20fSFrederick Mayle     size_t bytes_written_total = 0;
139*9712c20fSFrederick Mayle     ssize_t bytes_written_partial = 0;
140*9712c20fSFrederick Mayle     const char* data = reinterpret_cast<const char*>(buffer);
141*9712c20fSFrederick Mayle     while (bytes_written_total < buffer_size) {
142*9712c20fSFrederick Mayle       bytes_written_partial =
143*9712c20fSFrederick Mayle           HANDLE_EINTR(write(fd, data + bytes_written_total,
144*9712c20fSFrederick Mayle                              buffer_size - bytes_written_total));
145*9712c20fSFrederick Mayle       if (bytes_written_partial < 0) {
146*9712c20fSFrederick Mayle         perror("write");
147*9712c20fSFrederick Mayle         ok = false;
148*9712c20fSFrederick Mayle         break;
149*9712c20fSFrederick Mayle       }
150*9712c20fSFrederick Mayle       bytes_written_total += bytes_written_partial;
151*9712c20fSFrederick Mayle     }
152*9712c20fSFrederick Mayle   }
153*9712c20fSFrederick Mayle   if (IGNORE_EINTR(close(fd)) == -1) {
154*9712c20fSFrederick Mayle     perror("close");
155*9712c20fSFrederick Mayle     ok = false;
156*9712c20fSFrederick Mayle   }
157*9712c20fSFrederick Mayle   return ok;
158*9712c20fSFrederick Mayle }
159*9712c20fSFrederick Mayle 
160*9712c20fSFrederick Mayle }  // namespace google_breakpad
161