summaryrefslogtreecommitdiffstats
path: root/libdiskconfig/diskutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdiskconfig/diskutils.c')
-rw-r--r--libdiskconfig/diskutils.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/libdiskconfig/diskutils.c b/libdiskconfig/diskutils.c
new file mode 100644
index 0000000..22767c0
--- /dev/null
+++ b/libdiskconfig/diskutils.c
@@ -0,0 +1,117 @@
+/* libs/diskconfig/diskutils.c
+ *
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "diskutils"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <cutils/log.h>
+
+#include <diskconfig/diskconfig.h>
+
+int
+write_raw_image(const char *dst, const char *src, loff_t offset, int test)
+{
+ int dst_fd = -1;
+ int src_fd = -1;
+ uint8_t buffer[2048];
+ int nr_bytes;
+ int tmp;
+ int done = 0;
+ uint64_t total = 0;
+
+ LOGI("Writing RAW image '%s' to '%s' (offset=%llu)", src, dst, offset);
+ if ((src_fd = open(src, O_RDONLY)) < 0) {
+ LOGE("Could not open %s for reading (errno=%d).", src, errno);
+ goto fail;
+ }
+
+ if (!test) {
+ if ((dst_fd = open(dst, O_RDWR)) < 0) {
+ LOGE("Could not open '%s' for read/write (errno=%d).", dst, errno);
+ goto fail;
+ }
+
+ if (lseek64(dst_fd, offset, SEEK_SET) != offset) {
+ LOGE("Could not seek to offset %lld in %s.", offset, dst);
+ goto fail;
+ }
+ }
+
+ while (!done) {
+ if ((nr_bytes = read(src_fd, buffer, sizeof(buffer))) < 0) {
+ /* XXX: Should we not even bother with EINTR? */
+ if (errno == EINTR)
+ continue;
+ LOGE("Error (%d) while reading from '%s'", errno, src);
+ goto fail;
+ }
+
+ if (!nr_bytes) {
+ /* we're done. */
+ done = 1;
+ break;
+ }
+
+ total += nr_bytes;
+
+ /* skip the write loop if we're testing */
+ if (test)
+ nr_bytes = 0;
+
+ while (nr_bytes > 0) {
+ if ((tmp = write(dst_fd, buffer, nr_bytes)) < 0) {
+ /* XXX: Should we not even bother with EINTR? */
+ if (errno == EINTR)
+ continue;
+ LOGE("Error (%d) while writing to '%s'", errno, dst);
+ goto fail;
+ }
+ if (!tmp)
+ continue;
+ nr_bytes -= tmp;
+ }
+ }
+
+ if (!done) {
+ LOGE("Exited read/write loop without setting flag! WTF?!");
+ goto fail;
+ }
+
+ if (dst_fd >= 0)
+ fsync(dst_fd);
+
+ LOGI("Wrote %llu bytes to %s @ %lld", total, dst, offset);
+
+ close(src_fd);
+ if (dst_fd >= 0)
+ close(dst_fd);
+ return 0;
+
+fail:
+ if (dst_fd >= 0)
+ close(dst_fd);
+ if (src_fd >= 0)
+ close(src_fd);
+ return 1;
+}