summaryrefslogtreecommitdiff
path: root/cmd/sbc_harness/fs_harness_uptime_txt.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/sbc_harness/fs_harness_uptime_txt.c')
-rw-r--r--cmd/sbc_harness/fs_harness_uptime_txt.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/cmd/sbc_harness/fs_harness_uptime_txt.c b/cmd/sbc_harness/fs_harness_uptime_txt.c
index 4d35385..9b03b46 100644
--- a/cmd/sbc_harness/fs_harness_uptime_txt.c
+++ b/cmd/sbc_harness/fs_harness_uptime_txt.c
@@ -16,7 +16,13 @@ LO_IMPLEMENTATION_C(lib9p_srv_file, struct uptime_file, uptime_file);
struct uptime_fio {
struct uptime_file *parent;
size_t buf_len;
- char buf[24]; /* len(str(UINT64_MAX)+"ns\n\0") */
+ /* The maximum length (UINT64_MAX) string is 52 bytes, not
+ * including a nul-terminator:
+ *
+ * "18446744073709551615ns\n" # 22+1
+ * "584y343d 23h34m33.709551615s\n" # 28+1
+ */
+ char buf[52];
};
LO_IMPLEMENTATION_STATIC(lib9p_srv_fio, struct uptime_fio, uptime_fio);
@@ -107,27 +113,45 @@ static struct lib9p_qid uptime_fio_ioqid(struct uptime_fio *self) {
return uptime_file_qid(self->parent);
}
-static iovec_or_error uptime_fio_pread(struct uptime_fio *self, struct lib9p_srv_ctx *ctx,
- uint32_t byte_count, uint64_t byte_offset) {
+#define NS_PER_M (NS_PER_S*60)
+#define NS_PER_H (NS_PER_S*60*60)
+#define NS_PER_D (NS_PER_S*60*60*24)
+#define NS_PER_Y (NS_PER_S*60*60*24*365)
+
+static error uptime_fio_pread(struct uptime_fio *self, struct lib9p_srv_ctx *ctx,
+ lo_interface io_writer dst, uint64_t byte_offset, uint32_t byte_count) {
assert(self);
assert(ctx);
if (byte_offset == 0 || self->buf_len == 0) {
uint64_t now = LO_CALL(bootclock, get_time_ns);
self->buf_len = fmt_snprint(self->buf, sizeof(self->buf), now, "ns\n");
+
+ uint64_t ns = now;
+ uint64_t y = ns/NS_PER_Y; ns -= y*NS_PER_Y;
+ uint64_t d = ns/NS_PER_D; ns -= d*NS_PER_D;
+ uint64_t h = ns/NS_PER_H; ns -= h*NS_PER_H;
+ uint64_t m = ns/NS_PER_M; ns -= m*NS_PER_M;
+ uint64_t s = ns/NS_PER_S; ns -= s*NS_PER_S;
+ if (y)
+ self->buf_len += fmt_snprint(&self->buf[self->buf_len], sizeof(self->buf)-self->buf_len, y, "y");
+ if (y || d)
+ self->buf_len += fmt_snprint(&self->buf[self->buf_len], sizeof(self->buf)-self->buf_len, d, "d ");
+ if (y || d || h)
+ self->buf_len += fmt_snprint(&self->buf[self->buf_len], sizeof(self->buf)-self->buf_len, h, "h");
+ if (y || d || h || m)
+ self->buf_len += fmt_snprint(&self->buf[self->buf_len], sizeof(self->buf)-self->buf_len, m, "m");
+ self->buf_len += fmt_snprint(&self->buf[self->buf_len], sizeof(self->buf)-self->buf_len, s, ".", (rjust, 9, '0', ns), "s\n");
}
if (byte_offset > (uint64_t)self->buf_len)
- return ERROR_NEW_ERR(iovec, error_new(E_POSIX_EINVAL, "offset is past end-of-file length"));
+ return error_new(E_POSIX_EINVAL, "offset is past end-of-file length");
size_t beg_off = (size_t)byte_offset;
size_t end_off = beg_off + (size_t)byte_count;
if (end_off > self->buf_len)
end_off = self->buf_len;
- return ERROR_NEW_VAL(iovec, ((struct iovec){
- .iov_base = &self->buf[beg_off],
- .iov_len = end_off-beg_off,
- }));
+ return io_write(dst, &self->buf[beg_off], end_off-beg_off).err;
}
static uint32_t_or_error uptime_fio_pwrite(struct uptime_fio *self, struct lib9p_srv_ctx *ctx,