Karel Zak wrote: > This patch: > - clean up tailf(1) code > - remove stupid "for() { malloc() }" array allocation in the tailf() function > - add inotify(7) support > > Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> > --- > configure.ac | 1 + > text-utils/tailf.1 | 4 +- > text-utils/tailf.c | 240 ++++++++++++++++++++++++++++++++++------------------ > 3 files changed, 161 insertions(+), 84 deletions(-) > Good job. :) > diff --git a/text-utils/tailf.c b/text-utils/tailf.c > index f4616cc..8898574 100644 > --- a/text-utils/tailf.c > +++ b/text-utils/tailf.c > @@ -19,7 +19,7 @@ > * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > * OTHER DEALINGS IN THE SOFTWARE. > - * > + * > * less -F and tail -f cause a disk access every five seconds. This > * program avoids this problem by waiting for the file size to change. > * Hence, the file is not accessed, and the access time does not need to be > @@ -31,111 +31,185 @@ > #include <unistd.h> > #include <malloc.h> > #include <string.h> > +#include <sys/types.h> > #include <sys/stat.h> > +#include <unistd.h> > +#include <fcntl.h> > #include <ctype.h> > +#include <errno.h> > #include <err.h> > +#include <sys/inotify.h> > #include "nls.h" > > #define DEFAULT_LINES 10 > > -static size_t filesize(const char *filename) > +static void > +tailf(const char *filename, int lines) > { > - struct stat sb; > + char *buf, *p; > + int head = 0; > + int tail = 0; > + FILE *str; > + int i; > + > + if (!(str = fopen(filename, "r"))) > + err(EXIT_FAILURE, _("cannot open \"%s\" for read"), filename); > + > + buf = malloc(lines * BUFSIZ); > + p = buf; > + while(fgets(p, BUFSIZ, str)) { need a space: while ( > + if (++tail >= lines) { > + tail = 0; > + head = 1; > + } > + p = buf + (tail * BUFSIZ); > + } > + > + if (head) { > + for (i = tail; i < lines; i++) > + fputs(buf + (i * BUFSIZ), stdout); > + for (i = 0; i < tail; i++) > + fputs(buf + (i * BUFSIZ), stdout); > + } else { > + for (i = head; i < tail; i++) > + fputs(buf + (i * BUFSIZ), stdout); > + } > > - if (!stat(filename, &sb)) return sb.st_size; > - return 0; > + fflush(stdout); > + free(buf); > + fclose(str); > } > > -static void tailf(const char *filename, int lines) > +static void > +roll_file(const char *filename, off_t *size) > { > - char **buffer; > - int head = 0; > - int tail = 0; > - FILE *str; > - int i; > - > - if (!(str = fopen(filename, "r"))) > - err(1, _("cannot open \"%s\" for read"), filename); > - > - buffer = malloc(lines * sizeof(*buffer)); > - for (i = 0; i < lines; i++) buffer[i] = malloc(BUFSIZ + 1); > - > - while (fgets(buffer[tail], BUFSIZ, str)) { > - if (++tail >= lines) { > - tail = 0; > - head = 1; > + char buf[BUFSIZ]; > + int fd; > + struct stat st; > + > + if (!(fd = open(filename, O_RDONLY))) > + err(EXIT_FAILURE, _("cannot open \"%s\" for read"), filename); > + > + if (fstat(fd, &st) == -1) > + err(EXIT_FAILURE, _("cannot stat \"%s\""), filename); > + > + if (st.st_size == *size) { > + close(fd); > + return; > } > - } > > - if (head) { > - for (i = tail; i < lines; i++) fputs(buffer[i], stdout); > - for (i = 0; i < tail; i++) fputs(buffer[i], stdout); > - } else { > - for (i = head; i < tail; i++) fputs(buffer[i], stdout); > - } > - fflush(stdout); > + if (!lseek(fd, *size, SEEK_SET) != (off_t)-1) { I think this should be: if (lseek(fd, *size, SEEK_SET) != (off_t)-1) Otherwise the if statement will be always true. I don't see any other problems in the patch. - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html