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