• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libs/diskconfig/diskutils.c
2  *
3  * Copyright 2008, The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #define LOG_TAG "diskutils"
19 
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 
28 #include <cutils/log.h>
29 
30 #include <diskconfig/diskconfig.h>
31 
32 int
write_raw_image(const char * dst,const char * src,loff_t offset,int test)33 write_raw_image(const char *dst, const char *src, loff_t offset, int test)
34 {
35     int dst_fd = -1;
36     int src_fd = -1;
37     uint8_t buffer[2048];
38     int nr_bytes;
39     int tmp;
40     int done = 0;
41     uint64_t total = 0;
42 
43     ALOGI("Writing RAW image '%s' to '%s' (offset=%llu)", src, dst, offset);
44     if ((src_fd = open(src, O_RDONLY)) < 0) {
45         ALOGE("Could not open %s for reading (errno=%d).", src, errno);
46         goto fail;
47     }
48 
49     if (!test) {
50         if ((dst_fd = open(dst, O_RDWR)) < 0) {
51             ALOGE("Could not open '%s' for read/write (errno=%d).", dst, errno);
52             goto fail;
53         }
54 
55         if (lseek64(dst_fd, offset, SEEK_SET) != offset) {
56             ALOGE("Could not seek to offset %lld in %s.", offset, dst);
57             goto fail;
58         }
59     }
60 
61     while (!done) {
62         if ((nr_bytes = read(src_fd, buffer, sizeof(buffer))) < 0) {
63             /* XXX: Should we not even bother with EINTR? */
64             if (errno == EINTR)
65                 continue;
66             ALOGE("Error (%d) while reading from '%s'", errno, src);
67             goto fail;
68         }
69 
70         if (!nr_bytes) {
71             /* we're done. */
72             done = 1;
73             break;
74         }
75 
76         total += nr_bytes;
77 
78         /* skip the write loop if we're testing */
79         if (test)
80             nr_bytes = 0;
81 
82         while (nr_bytes > 0) {
83             if ((tmp = write(dst_fd, buffer, nr_bytes)) < 0) {
84                 /* XXX: Should we not even bother with EINTR? */
85                 if (errno == EINTR)
86                     continue;
87                 ALOGE("Error (%d) while writing to '%s'", errno, dst);
88                 goto fail;
89             }
90             if (!tmp)
91                 continue;
92             nr_bytes -= tmp;
93         }
94     }
95 
96     if (!done) {
97         ALOGE("Exited read/write loop without setting flag! WTF?!");
98         goto fail;
99     }
100 
101     if (dst_fd >= 0)
102         fsync(dst_fd);
103 
104     ALOGI("Wrote %llu bytes to %s @ %lld", total, dst, offset);
105 
106     close(src_fd);
107     if (dst_fd >= 0)
108         close(dst_fd);
109     return 0;
110 
111 fail:
112     if (dst_fd >= 0)
113         close(dst_fd);
114     if (src_fd >= 0)
115         close(src_fd);
116     return 1;
117 }
118