3rdparty/blobs: Update submodule to upstream main
[coreboot.git] / util / amdfwtool / handle_file.c
blobc37bb2c8eb552dedef060d75a2ef5b8c3667be8a
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <fcntl.h>
4 #include <errno.h>
5 #include <limits.h>
6 #include <stdio.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <string.h>
10 #include <stdlib.h>
12 #include "amdfwtool.h"
14 void write_or_fail(int fd, void *ptr, size_t size)
16 ssize_t written;
18 written = write_from_buf_to_file(fd, ptr, size);
19 if (written < 0 || (size_t)written != size) {
20 fprintf(stderr, "%s: Error writing %zu bytes - written %zd bytes\n",
21 __func__, size, written);
22 exit(-1);
26 ssize_t read_from_file_to_buf(int fd, void *buf, size_t buf_size)
28 ssize_t bytes;
29 size_t total_bytes = 0;
31 do {
32 bytes = read(fd, buf + total_bytes, buf_size - total_bytes);
33 if (bytes == 0) {
34 fprintf(stderr, "Reached EOF probably\n");
35 break;
38 if (bytes < 0 && errno == EAGAIN)
39 bytes = 0;
41 if (bytes < 0) {
42 fprintf(stderr, "Read failure %s\n", strerror(errno));
43 return bytes;
46 total_bytes += bytes;
47 } while (total_bytes < buf_size);
49 if (total_bytes != buf_size) {
50 fprintf(stderr, "Read data size(%zu) != buffer size(%zu)\n",
51 total_bytes, buf_size);
52 return -1;
54 return buf_size;
57 ssize_t write_from_buf_to_file(int fd, const void *buf, size_t buf_size)
59 ssize_t bytes;
60 size_t total_bytes = 0;
62 do {
63 bytes = write(fd, buf + total_bytes, buf_size - total_bytes);
64 if (bytes < 0 && errno == EAGAIN)
65 bytes = 0;
67 if (bytes < 0) {
68 fprintf(stderr, "Write failure %s\n", strerror(errno));
69 lseek(fd, SEEK_CUR, -total_bytes);
70 return bytes;
73 total_bytes += bytes;
74 } while (total_bytes < buf_size);
76 if (total_bytes != buf_size) {
77 fprintf(stderr, "Wrote more data(%zu) than buffer size(%zu)\n",
78 total_bytes, buf_size);
79 lseek(fd, SEEK_CUR, -total_bytes);
80 return -1;
83 return buf_size;
86 ssize_t write_body(char *output, void *body_offset, ssize_t body_size)
88 char body_name[PATH_MAX], body_tmp_name[PATH_MAX];
89 int ret;
90 int fd;
91 ssize_t bytes = -1;
93 /* Create a tmp file and rename it at the end so that make does not get confused
94 if amdfwtool is killed for some unexpected reasons. */
95 ret = snprintf(body_tmp_name, sizeof(body_tmp_name), "%s%s%s",
96 output, BODY_FILE_SUFFIX, TMP_FILE_SUFFIX);
97 if (ret < 0) {
98 fprintf(stderr, "Error %s forming BODY tmp file name: %d\n",
99 strerror(errno), ret);
100 return -1;
101 } else if ((unsigned int)ret >= sizeof(body_tmp_name)) {
102 fprintf(stderr, "BODY File name %d > %zu\n", ret, sizeof(body_tmp_name));
103 return -1;
106 fd = open(body_tmp_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
107 if (fd < 0) {
108 fprintf(stderr, "Error: Opening %s file: %s\n", body_tmp_name, strerror(errno));
109 return -1;
112 bytes = write_from_buf_to_file(fd, body_offset, body_size);
113 if (bytes != body_size) {
114 fprintf(stderr, "Error: Writing to file %s failed\n", body_tmp_name);
115 return -1;
117 close(fd);
119 /* Rename the tmp file */
120 ret = snprintf(body_name, sizeof(body_name), "%s%s", output, BODY_FILE_SUFFIX);
121 if (ret < 0) {
122 fprintf(stderr, "Error %s forming BODY file name: %d\n", strerror(errno), ret);
123 return -1;
126 if (rename(body_tmp_name, body_name)) {
127 fprintf(stderr, "Error: renaming file %s to %s\n", body_tmp_name, body_name);
128 return -1;
131 return bytes;
134 ssize_t copy_blob(void *dest, const char *src_file, size_t room)
136 int fd;
137 struct stat fd_stat;
138 ssize_t bytes;
140 fd = open(src_file, O_RDONLY);
141 if (fd < 0) {
142 fprintf(stderr, "Error opening file: %s: %s\n",
143 src_file, strerror(errno));
144 return -1;
147 if (fstat(fd, &fd_stat)) {
148 fprintf(stderr, "fstat error: %s\n", strerror(errno));
149 close(fd);
150 return -2;
153 if ((size_t)fd_stat.st_size > room) {
154 fprintf(stderr, "Error: %s will not fit. Exiting.\n", src_file);
155 close(fd);
156 return -3;
159 bytes = read(fd, dest, (size_t)fd_stat.st_size);
160 close(fd);
161 if (bytes != (ssize_t)fd_stat.st_size) {
162 fprintf(stderr, "Error while reading %s\n", src_file);
163 return -4;
166 return bytes;