From 8787c5e9f422ae6a9d3e3f5445301f753c3fe02d Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 18 Sep 2007 13:28:59 +0200 Subject: inotail.c: Implement tail_pipe_bytes() For now more or less a copy from coreutils --- inotail.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- inotail.h | 7 ++++++ 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/inotail.c b/inotail.c index 02cf462..cd96ec1 100644 --- a/inotail.c +++ b/inotail.c @@ -345,23 +345,84 @@ out: return rc; } -/* TODO: Implement me :) */ static ssize_t tail_pipe_bytes(struct file_struct *f, unsigned long n_bytes) { + struct char_buf *first, *last, *tmp; ssize_t rc; - char buf[BUFSIZ]; + unsigned long total_bytes = 0; + unsigned long i = 0; /* Index into buffer */ - /* We will just tail everything here */ - while ((rc = read(f->fd, buf, f->blksize)) > 0) { - if (write(STDOUT_FILENO, buf, (size_t) rc) <= 0) { - /* e.g. when writing to a pipe which gets closed */ + if (n_bytes == 0) + return 0; + + first = last = emalloc(sizeof(struct char_buf)); + first->n_bytes = 0; + first->next = NULL; + tmp = emalloc(sizeof(struct char_buf)); + + while(1) { + if ((rc = read(f->fd, tmp->buf, BUFSIZ)) <= 0) { + if (rc < 0 && (errno == EINTR || errno == EAGAIN)) + continue; + else + break; + } + total_bytes += rc; + tmp->n_bytes = rc; + tmp->next = NULL; + + /* Try to append to the previous buffer if there's enough free + * space + */ + if (tmp->n_bytes + last->n_bytes < BUFSIZ) { + memcpy(&last->buf[last->n_bytes], tmp->buf, tmp->n_bytes); + last->n_bytes += tmp->n_bytes; + } else { + last = last->next = tmp; + if (total_bytes - first->n_bytes > n_bytes) { + tmp = first; + total_bytes -= first->n_bytes; + first = first->next; + } else + tmp = emalloc(sizeof(struct char_buf)); + } + } + + free(tmp); + + if (rc < 0) { + fprintf(stderr, "Error: Could not read from %s\n", pretty_name(f->name)); + goto out; + } + + /* Skip unneeded buffers */ + for (tmp = first; total_bytes - tmp->n_bytes > n_bytes; tmp = tmp->next) + total_bytes -= tmp->n_bytes; + + if (total_bytes > n_bytes) + i = total_bytes - n_bytes; + + if ((rc = write(STDOUT_FILENO, &tmp->buf[i], tmp->n_bytes - i)) <= 0) { + /* e.g. when writing to a pipe which gets closed */ + fprintf(stderr, "Error: Could not write to stdout (%s)\n", strerror(errno)); + goto out; + } + + for (tmp = tmp->next; tmp; tmp = tmp->next) + if ((rc = write(STDOUT_FILENO, tmp->buf, tmp->n_bytes)) <= 0) { fprintf(stderr, "Error: Could not write to stdout (%s)\n", strerror(errno)); - rc = -1; - break; + goto out; } + + + rc = 0; +out: + while (first) { + tmp = first->next; + free(first); + first = tmp; } - free(buf); return rc; } diff --git a/inotail.h b/inotail.h index f9eabba..5029540 100644 --- a/inotail.h +++ b/inotail.h @@ -32,6 +32,13 @@ struct line_buf { struct line_buf *next; }; +/* struct for linked list of byte buffers in tail_pipe_bytes */ +struct char_buf { + char buf[BUFSIZ]; + size_t n_bytes; + struct char_buf *next; +}; + #define IS_PIPELIKE(mode) \ (S_ISFIFO(mode) || S_ISSOCK(mode)) -- cgit v1.2.3-54-g00ecf -panel'>diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-14 10:58:17 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-14 10:58:17 -0800
commit2a4c32edd39b7de166e723b1991abcde4db3a701 (patch)
tree1eba8e303e19d0f8fa0874f4514f87ebac82ae5c /drivers
parentb9f98bd4034a3196ff068eb0fa376c5f41077480 (diff)
parent20737738d397dfadbca1ea50dcc00d7259f500cf (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md
Pull MD updates from Shaohua Li: - a raid5 writeback cache feature. The goal is to aggregate writes to make full stripe write and reduce read-modify-write. It's helpful for workload which does sequential write and follows fsync for example. This feature is experimental and off by default right now. - FAILFAST support. This fails IOs to broken raid disks quickly, so can improve latency. It's mainly for DASD storage, but some patches help normal raid array too. - support bad block for raid array with external metadata - AVX2 instruction support for raid6 parity calculation - normalize MD info output - add missing blktrace - other bug fixes * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md: (66 commits) md: separate flags for superblock changes md: MD_RECOVERY_NEEDED is set for mddev->recovery md: takeover should clear unrelated bits md/r5cache: after recovery, increase journal seq by 10000 md/raid5-cache: fix crc in rewrite_data_only_stripes() md/raid5-cache: no recovery is required when create super-block md: fix refcount problem on mddev when stopping array. md/r5cache: do r5c_update_log_state after log recovery md/raid5-cache: adjust the write position of the empty block if no data blocks md/r5cache: run_no_space_stripes() when R5C_LOG_CRITICAL == 0 md/raid5: limit request size according to implementation limits md/raid5-cache: do not need to set STRIPE_PREREAD_ACTIVE repeatedly md/raid5-cache: remove the unnecessary next_cp_seq field from the r5l_log md/raid5-cache: release the stripe_head at the appropriate location md/raid5-cache: use ring add to prevent overflow md/raid5-cache: remove unnecessary function parameters raid5-cache: don't set STRIPE_R5C_PARTIAL_STRIPE flag while load stripe into cache raid5-cache: add another check conditon before replaying one stripe md/r5cache: enable IRQs on error path md/r5cache: handle alloc_page failure ...
Diffstat (limited to 'drivers')