blob: c37bb2c8eb552dedef060d75a2ef5b8c3667be8a [file] [log] [blame]
Zheng Baof080cd52023-03-22 12:50:36 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
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>
11
12#include "amdfwtool.h"
13
14void write_or_fail(int fd, void *ptr, size_t size)
15{
16 ssize_t written;
17
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);
23 }
24}
25
26ssize_t read_from_file_to_buf(int fd, void *buf, size_t buf_size)
27{
28 ssize_t bytes;
29 size_t total_bytes = 0;
30
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;
36 }
37
38 if (bytes < 0 && errno == EAGAIN)
39 bytes = 0;
40
41 if (bytes < 0) {
42 fprintf(stderr, "Read failure %s\n", strerror(errno));
43 return bytes;
44 }
45
46 total_bytes += bytes;
47 } while (total_bytes < buf_size);
48
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;
53 }
54 return buf_size;
55}
56
57ssize_t write_from_buf_to_file(int fd, const void *buf, size_t buf_size)
58{
59 ssize_t bytes;
60 size_t total_bytes = 0;
61
62 do {
63 bytes = write(fd, buf + total_bytes, buf_size - total_bytes);
64 if (bytes < 0 && errno == EAGAIN)
65 bytes = 0;
66
67 if (bytes < 0) {
68 fprintf(stderr, "Write failure %s\n", strerror(errno));
69 lseek(fd, SEEK_CUR, -total_bytes);
70 return bytes;
71 }
72
73 total_bytes += bytes;
74 } while (total_bytes < buf_size);
75
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;
81 }
82
83 return buf_size;
84}
Zheng Bao92a9d932023-10-10 11:15:07 +080085
86ssize_t write_body(char *output, void *body_offset, ssize_t body_size)
87{
88 char body_name[PATH_MAX], body_tmp_name[PATH_MAX];
89 int ret;
90 int fd;
91 ssize_t bytes = -1;
92
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;
104 }
105
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;
110 }
111
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;
116 }
117 close(fd);
118
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;
124 }
125
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;
129 }
130
131 return bytes;
132}
133
134ssize_t copy_blob(void *dest, const char *src_file, size_t room)
135{
136 int fd;
137 struct stat fd_stat;
138 ssize_t bytes;
139
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;
145 }
146
147 if (fstat(fd, &fd_stat)) {
148 fprintf(stderr, "fstat error: %s\n", strerror(errno));
149 close(fd);
150 return -2;
151 }
152
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;
157 }
158
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;
164 }
165
166 return bytes;
167}