Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/platform/memento_softwareupdate/split_write.cc

Issue 1520028: New Full AU Format w/ support for kernel partition. (Closed)
Patch Set: fixes for review Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <sys/stat.h>
6 #include <sys/types.h>
7
8 #include <endian.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13
14 #include <algorithm>
15
16 namespace {
17
18 class ScopedFileDescriptorCloser {
19 public:
20 ScopedFileDescriptorCloser(int fd) : fd_(fd) {}
21 ~ScopedFileDescriptorCloser() {
22 close(fd_);
23 }
24 private:
25 const int fd_;
26 };
27
28 const int kBufSize = 1024 * 1024 * 4; // 4 MiB
29
30 // This program takes two files as args. It will open both and write the
31 // first part of stdin into the first file, the second part into the second
32 // file. The first 8 bytes contain the unsigned big-endian count of bytes
33 // that should go to the first file. Following bytes go to the second file.
34
35 // Writes all bytes to fd. Exits on error.
36 void write_all(int fd, const void *buf, size_t count) {
37 const char* c_buf = static_cast<const char*>(buf);
38 size_t written = 0;
39 while (written < count) {
40 ssize_t rc = write(fd, c_buf + written, count - written);
41 if (rc < 0) {
42 perror("write");
43 exit(1);
44 }
45 written += static_cast<size_t>(rc);
46 }
47 }
48
49 // Returns bytes read, which may be short on EOF. Exits on error.
50 size_t read_all(int fd, void* buf, size_t count) {
51 char* c_buf = static_cast<char*>(buf);
52 size_t bytes_read = 0;
53 while (bytes_read < count) {
54 ssize_t rc = read(fd, c_buf + bytes_read, count - bytes_read);
55 if (rc == 0) {
56 break;
57 }
58 if (rc < 0) {
59 perror("read");
60 exit(1);
61 }
62 bytes_read += static_cast<size_t>(rc);
63 }
64 return bytes_read;
65 }
66
67 void usage(char* argv0) {
68 fprintf(stderr, "Usage: %s first_file second_file\n", argv0);
69 exit(1);
70 }
71
72 // Returns valid fd or exits program.
73 int open_file(const char* path) {
74 int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
75 if (fd < 0) {
76 perror("open");
77 fprintf(stderr, "failed to open %s\n", path);
78 exit(1);
79 }
80 }
81
82 typedef long long int64;
83 // Compile assert sizeof(int64) == 8:
84 char int64_8_bytes_long[(sizeof(int64) == 8) - 1];
85
86 } // namespace {}
87
88 int main(int argc, char** argv) {
89 if (argc != 3) {
90 usage(argv[0]);
91 }
92 const int fd1 = open_file(argv[1]);
93 ScopedFileDescriptorCloser fd1_closer(fd1);
94 const int fd2 = open_file(argv[2]);
95 ScopedFileDescriptorCloser fd2_closer(fd2);
96 const int fd_in = 0; // stdin
97 char* const buf = static_cast<char*>(malloc(kBufSize));
98 if (buf == NULL) {
99 fprintf(stderr, "malloc on buffer failed.\n");
100 return 1;
101 }
102 int64 first_file_size = 0;
103 size_t bytes_read =
104 read_all(fd_in, &first_file_size, sizeof(first_file_size));
105 if (bytes_read < sizeof(first_file_size)) {
106 fprintf(stderr, "short read on first file size.\n");
107 return 1;
108 }
109 first_file_size = be64toh(first_file_size);
110 int64 first_bytes_written = 0;
111 while (first_bytes_written < first_file_size) {
112 size_t chunk_size = std::min(first_file_size - first_bytes_written,
113 static_cast<int64>(kBufSize));
114 chunk_size = read_all(fd_in, buf, chunk_size);
115 if (chunk_size == 0) {
116 // All data went to first partition, none left for second.
117 // This is okay only if the first file size is exactl how much we've
118 // written thus far
119 if (first_file_size == first_bytes_written) {
120 return 0;
121 } else {
122 fprintf(stderr, "file appears truncated.\n");
123 return 1;
124 }
125 }
126 write_all(fd1, buf, chunk_size);
127 first_bytes_written += chunk_size;
128 }
129 // Do the rest on the second file
130 for (;;) {
131 size_t chunk_size = read_all(fd_in, buf, kBufSize);
132 if (chunk_size == 0)
133 break;
134 write_all(fd2, buf, chunk_size);
135 }
136 return 0;
137 }
OLDNEW
« no previous file with comments | « src/platform/memento_softwareupdate/memento_updater.sh ('k') | src/scripts/mk_memento_images.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698