Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

gen_init_cpio: write to fd instead of stdout stream

In preparation for more efficient archiving using copy_file_range(),
switch from writing archive data to stdout to using STDOUT_FILENO and
I/O via write(), dprintf(), etc.
Basic I/O error handling is added to cover cases such as ENOSPC. Partial
writes are treated as errors.

Signed-off-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
Link: https://lore.kernel.org/r/20250819032607.28727-2-ddiss@suse.de
Signed-off-by: Nathan Chancellor <nathan@kernel.org>

authored by

David Disseldorp and committed by
Nathan Chancellor
14002277 75a6b459

+81 -58
+81 -58
usr/gen_init_cpio.c
··· 23 23 #define xstr(s) #s 24 24 #define str(s) xstr(s) 25 25 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 26 + #define CPIO_HDR_LEN 110 27 + #define padlen(_off, _align) (((_align) - ((_off) & ((_align) - 1))) % (_align)) 26 28 29 + static char padding[512]; 27 30 static unsigned int offset; 28 31 static unsigned int ino = 721; 29 32 static time_t default_mtime; 30 33 static bool do_file_mtime; 31 34 static bool do_csum = false; 35 + static int outfd = STDOUT_FILENO; 32 36 33 37 struct file_handler { 34 38 const char *type; 35 39 int (*handler)(const char *line); 36 40 }; 37 41 38 - static void push_string(const char *name) 42 + static int push_string(const char *name) 39 43 { 40 44 unsigned int name_len = strlen(name) + 1; 45 + ssize_t len; 41 46 42 - fputs(name, stdout); 43 - putchar(0); 47 + len = write(outfd, name, name_len); 48 + if (len != name_len) 49 + return -1; 50 + 44 51 offset += name_len; 52 + return 0; 45 53 } 46 54 47 - static void push_pad (void) 55 + static int push_pad(size_t padlen) 48 56 { 49 - while (offset & 3) { 50 - putchar(0); 51 - offset++; 52 - } 57 + ssize_t len = 0; 58 + 59 + if (!padlen) 60 + return 0; 61 + 62 + if (padlen < sizeof(padding)) 63 + len = write(outfd, padding, padlen); 64 + if (len != padlen) 65 + return -1; 66 + 67 + offset += padlen; 68 + return 0; 53 69 } 54 70 55 - static void push_rest(const char *name) 71 + static int push_rest(const char *name) 56 72 { 57 73 unsigned int name_len = strlen(name) + 1; 58 - unsigned int tmp_ofs; 74 + ssize_t len; 59 75 60 - fputs(name, stdout); 61 - putchar(0); 76 + len = write(outfd, name, name_len); 77 + if (len != name_len) 78 + return -1; 79 + 62 80 offset += name_len; 63 81 64 - tmp_ofs = name_len + 110; 65 - while (tmp_ofs & 3) { 66 - putchar(0); 67 - offset++; 68 - tmp_ofs++; 69 - } 82 + return push_pad(padlen(name_len + CPIO_HDR_LEN, 4)); 70 83 } 71 84 72 - static void push_hdr(const char *s) 85 + static int cpio_trailer(void) 73 86 { 74 - fputs(s, stdout); 75 - offset += 110; 76 - } 77 - 78 - static void cpio_trailer(void) 79 - { 80 - char s[256]; 81 87 const char name[] = "TRAILER!!!"; 88 + int len; 82 89 83 - sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX" 90 + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" 84 91 "%08X%08X%08X%08X%08X%08X%08X", 85 92 do_csum ? "070702" : "070701", /* magic */ 86 93 0, /* ino */ ··· 103 96 0, /* rminor */ 104 97 (unsigned)strlen(name)+1, /* namesize */ 105 98 0); /* chksum */ 106 - push_hdr(s); 107 - push_rest(name); 99 + offset += len; 108 100 109 - while (offset % 512) { 110 - putchar(0); 111 - offset++; 112 - } 101 + if (len != CPIO_HDR_LEN || 102 + push_rest(name) < 0 || 103 + push_pad(padlen(offset, 512)) < 0) 104 + return -1; 105 + 106 + return 0; 113 107 } 114 108 115 109 static int cpio_mkslink(const char *name, const char *target, 116 110 unsigned int mode, uid_t uid, gid_t gid) 117 111 { 118 - char s[256]; 112 + int len; 119 113 120 114 if (name[0] == '/') 121 115 name++; 122 - sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 116 + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" 123 117 "%08X%08X%08X%08X%08X%08X%08X", 124 118 do_csum ? "070702" : "070701", /* magic */ 125 119 ino++, /* ino */ ··· 136 128 0, /* rminor */ 137 129 (unsigned)strlen(name) + 1,/* namesize */ 138 130 0); /* chksum */ 139 - push_hdr(s); 140 - push_string(name); 141 - push_pad(); 142 - push_string(target); 143 - push_pad(); 131 + offset += len; 132 + 133 + if (len != CPIO_HDR_LEN || 134 + push_string(name) < 0 || 135 + push_pad(padlen(offset, 4)) < 0 || 136 + push_string(target) < 0 || 137 + push_pad(padlen(offset, 4)) < 0) 138 + return -1; 139 + 144 140 return 0; 141 + 145 142 } 146 143 147 144 static int cpio_mkslink_line(const char *line) ··· 170 157 static int cpio_mkgeneric(const char *name, unsigned int mode, 171 158 uid_t uid, gid_t gid) 172 159 { 173 - char s[256]; 160 + int len; 174 161 175 162 if (name[0] == '/') 176 163 name++; 177 - sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 164 + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" 178 165 "%08X%08X%08X%08X%08X%08X%08X", 179 166 do_csum ? "070702" : "070701", /* magic */ 180 167 ino++, /* ino */ ··· 190 177 0, /* rminor */ 191 178 (unsigned)strlen(name) + 1,/* namesize */ 192 179 0); /* chksum */ 193 - push_hdr(s); 194 - push_rest(name); 180 + offset += len; 181 + 182 + if (len != CPIO_HDR_LEN || 183 + push_rest(name) < 0) 184 + return -1; 185 + 195 186 return 0; 196 187 } 197 188 ··· 263 246 uid_t uid, gid_t gid, char dev_type, 264 247 unsigned int maj, unsigned int min) 265 248 { 266 - char s[256]; 249 + int len; 267 250 268 251 if (dev_type == 'b') 269 252 mode |= S_IFBLK; ··· 272 255 273 256 if (name[0] == '/') 274 257 name++; 275 - sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 258 + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" 276 259 "%08X%08X%08X%08X%08X%08X%08X", 277 260 do_csum ? "070702" : "070701", /* magic */ 278 261 ino++, /* ino */ ··· 288 271 min, /* rminor */ 289 272 (unsigned)strlen(name) + 1,/* namesize */ 290 273 0); /* chksum */ 291 - push_hdr(s); 292 - push_rest(name); 274 + offset += len; 275 + 276 + if (len != CPIO_HDR_LEN || 277 + push_rest(name) < 0) 278 + return -1; 279 + 293 280 return 0; 294 281 } 295 282 ··· 345 324 unsigned int mode, uid_t uid, gid_t gid, 346 325 unsigned int nlinks) 347 326 { 348 - char s[256]; 349 327 struct stat buf; 350 328 unsigned long size; 351 - int file; 352 - int retval; 329 + int file, retval, len; 353 330 int rc = -1; 354 331 time_t mtime; 355 332 int namesize; ··· 405 386 if (name[0] == '/') 406 387 name++; 407 388 namesize = strlen(name) + 1; 408 - sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" 389 + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" 409 390 "%08lX%08X%08X%08X%08X%08X%08X", 410 391 do_csum ? "070702" : "070701", /* magic */ 411 392 ino, /* ino */ ··· 421 402 0, /* rminor */ 422 403 namesize, /* namesize */ 423 404 size ? csum : 0); /* chksum */ 424 - push_hdr(s); 425 - push_string(name); 426 - push_pad(); 405 + offset += len; 406 + 407 + if (len != CPIO_HDR_LEN || 408 + push_string(name) < 0 || 409 + push_pad(padlen(offset, 4)) < 0) 410 + goto error; 427 411 428 412 while (size) { 429 413 unsigned char filebuf[65536]; ··· 439 417 goto error; 440 418 } 441 419 442 - if (fwrite(filebuf, this_read, 1, stdout) != 1) { 420 + if (write(outfd, filebuf, this_read) != this_read) { 443 421 fprintf(stderr, "writing filebuf failed\n"); 444 422 goto error; 445 423 } 446 424 offset += this_read; 447 425 size -= this_read; 448 426 } 449 - push_pad(); 427 + if (push_pad(padlen(offset, 4)) < 0) 428 + goto error; 450 429 451 430 name += namesize; 452 431 } ··· 714 691 } 715 692 } 716 693 if (ec == 0) 717 - cpio_trailer(); 694 + ec = cpio_trailer(); 718 695 719 696 exit(ec); 720 697 }