Merge pull request #29071 from YHNdnzj/loop-write-full
io-util: introduce loop_write_full and use it where appropriate
This commit is contained in:
@@ -614,7 +614,7 @@ int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncom
|
||||
|
||||
n = sizeof(out) - s.avail_out;
|
||||
|
||||
k = loop_write(fdt, out, n, false);
|
||||
k = loop_write(fdt, out, n);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
@@ -693,7 +693,7 @@ int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_unco
|
||||
"Compressed stream longer than %" PRIu64 " bytes", max_bytes);
|
||||
|
||||
if (out_allocsize - offset < frame_size + 4) {
|
||||
k = loop_write(fdt, out_buff, offset, false);
|
||||
k = loop_write(fdt, out_buff, offset);
|
||||
if (k < 0)
|
||||
return k;
|
||||
offset = 0;
|
||||
@@ -706,7 +706,7 @@ int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_unco
|
||||
|
||||
offset += n;
|
||||
total_out += n;
|
||||
r = loop_write(fdt, out_buff, offset, false);
|
||||
r = loop_write(fdt, out_buff, offset);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -779,7 +779,7 @@ int decompress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
|
||||
max_bytes -= n;
|
||||
}
|
||||
|
||||
k = loop_write(fdt, out, n, false);
|
||||
k = loop_write(fdt, out, n);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
@@ -845,7 +845,7 @@ int decompress_stream_lz4(int in, int out, uint64_t max_bytes) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r = loop_write(out, buf, produced, false);
|
||||
r = loop_write(out, buf, produced);
|
||||
if (r < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -931,7 +931,7 @@ int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_unc
|
||||
if (left < output.pos)
|
||||
return -EFBIG;
|
||||
|
||||
wrote = loop_write(fdt, output.dst, output.pos, 1);
|
||||
wrote = loop_write_full(fdt, output.dst, output.pos, USEC_INFINITY);
|
||||
if (wrote < 0)
|
||||
return wrote;
|
||||
|
||||
@@ -1041,7 +1041,7 @@ int decompress_stream_zstd(int fdf, int fdt, uint64_t max_bytes) {
|
||||
if (left < output.pos)
|
||||
return -EFBIG;
|
||||
|
||||
wrote = loop_write(fdt, output.dst, output.pos, 1);
|
||||
wrote = loop_write_full(fdt, output.dst, output.pos, USEC_INFINITY);
|
||||
if (wrote < 0)
|
||||
return wrote;
|
||||
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ int efi_set_variable(const char *variable, const void *value, size_t size) {
|
||||
buf->attr = attr;
|
||||
memcpy(buf->buf, value, size);
|
||||
|
||||
r = loop_write(fd, buf, sizeof(uint32_t) + size, false);
|
||||
r = loop_write(fd, buf, sizeof(uint32_t) + size);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
|
||||
+29
-10
@@ -5,6 +5,7 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "errno-util.h"
|
||||
#include "io-util.h"
|
||||
#include "string-util.h"
|
||||
#include "time-util.h"
|
||||
@@ -105,18 +106,19 @@ int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
int loop_write_full(int fd, const void *buf, size_t nbytes, usec_t timeout) {
|
||||
const uint8_t *p;
|
||||
usec_t end;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(buf || nbytes == 0);
|
||||
|
||||
if (nbytes == 0) {
|
||||
static const dummy_t dummy[0];
|
||||
assert_cc(sizeof(dummy) == 0);
|
||||
p = (const void*) dummy; /* Some valid pointer, in case NULL was specified */
|
||||
} else {
|
||||
assert(buf);
|
||||
|
||||
if (nbytes == SIZE_MAX)
|
||||
nbytes = strlen(buf);
|
||||
else if (_unlikely_(nbytes > (size_t) SSIZE_MAX))
|
||||
@@ -125,6 +127,9 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
p = buf;
|
||||
}
|
||||
|
||||
/* When timeout is 0 or USEC_INFINITY this is not used. But we initialize it to a sensible value. */
|
||||
end = timestamp_is_set(timeout) ? usec_add(now(CLOCK_MONOTONIC), timeout) : USEC_INFINITY;
|
||||
|
||||
do {
|
||||
ssize_t k;
|
||||
|
||||
@@ -133,16 +138,30 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno == EAGAIN && do_poll) {
|
||||
/* We knowingly ignore any return value here,
|
||||
* and expect that any error/EOF is reported
|
||||
* via write() */
|
||||
if (errno != EAGAIN || timeout == 0)
|
||||
return -errno;
|
||||
|
||||
(void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
|
||||
continue;
|
||||
usec_t wait_for;
|
||||
|
||||
if (timeout == USEC_INFINITY)
|
||||
wait_for = USEC_INFINITY;
|
||||
else {
|
||||
usec_t t = now(CLOCK_MONOTONIC);
|
||||
if (t >= end)
|
||||
return -ETIME;
|
||||
|
||||
wait_for = usec_sub_unsigned(end, t);
|
||||
}
|
||||
|
||||
return -errno;
|
||||
r = fd_wait_for_event(fd, POLLOUT, wait_for);
|
||||
if (timeout == USEC_INFINITY || ERRNO_IS_NEG_TRANSIENT(r))
|
||||
/* If timeout == USEC_INFINITY we knowingly ignore any return value
|
||||
* here, and expect that any error/EOF is reported via write() */
|
||||
continue;
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
|
||||
|
||||
+5
-1
@@ -15,7 +15,11 @@ int flush_fd(int fd);
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
||||
|
||||
int loop_write_full(int fd, const void *buf, size_t nbytes, usec_t timeout);
|
||||
static inline int loop_write(int fd, const void *buf, size_t nbytes) {
|
||||
return loop_write_full(fd, buf, nbytes, 0);
|
||||
}
|
||||
|
||||
int pipe_eof(int fd);
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ int random_write_entropy(int fd, const void *seed, size_t size, bool credit) {
|
||||
if (ioctl(fd, RNDADDENTROPY, info) < 0)
|
||||
return -errno;
|
||||
} else {
|
||||
r = loop_write(fd, seed, size, false);
|
||||
r = loop_write(fd, seed, size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -569,7 +569,7 @@ int vt_disallocate(const char *name) {
|
||||
"\033[r" /* clear scrolling region */
|
||||
"\033[H" /* move home */
|
||||
"\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
|
||||
10, false);
|
||||
10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1544,7 +1544,7 @@ int set_terminal_cursor_position(int fd, unsigned int row, unsigned int column)
|
||||
|
||||
xsprintf(cursor_position, "\x1B[%u;%uH", row, column);
|
||||
|
||||
r = loop_write(fd, cursor_position, SIZE_MAX, /* do_poll = */false);
|
||||
r = loop_write(fd, cursor_position, SIZE_MAX);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to set cursor position, ignoring: %m");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user