diff --git a/log/handler.go b/log/handler.go index 2f01b5dc6f..0f8910d9e3 100644 --- a/log/handler.go +++ b/log/handler.go @@ -102,29 +102,20 @@ func prepFile(path string) (*countingWriter, error) { if err != nil { return nil, err } - _, err = f.Seek(-1, io.SeekEnd) + fi, err := f.Stat() if err != nil { return nil, err } buf := make([]byte, 1) - var cut int64 - for { - if _, err := f.Read(buf); err != nil { + var ns int64 + for ns = fi.Size(); ns > 0; ns-- { + if _, err := f.ReadAt(buf, ns-1); err != nil { return nil, err } if buf[0] == '\n' { break } - if _, err = f.Seek(-2, io.SeekCurrent); err != nil { - return nil, err - } - cut++ } - fi, err := f.Stat() - if err != nil { - return nil, err - } - ns := fi.Size() - cut if err = f.Truncate(ns); err != nil { return nil, err } diff --git a/log/handler_test.go b/log/handler_test.go new file mode 100644 index 0000000000..cd0eddd6ea --- /dev/null +++ b/log/handler_test.go @@ -0,0 +1,86 @@ +package log + +import ( + "io/ioutil" + "os" + "testing" +) + +func newTempFileWithData(data []byte) string { + for { + f, err := ioutil.TempFile("", "ethereum.log") + if err != nil { + continue + } + + err = f.Truncate(0) + if err != nil { + continue + } + + if len(data) != 0 { + _, err = f.Write(data) + if err != nil { + continue + } + } + + name := f.Name() + _ = f.Close() + + return name + } +} + +func TestPrepFileWithEmptyFile(t *testing.T) { + tmpfile := newTempFileWithData(nil) + + w, err := prepFile(tmpfile) + if err != nil { + t.Errorf("Expect nil, got %v", err) + } + + w.Close() + + defer os.Remove(tmpfile) +} + +func TestPrepFileWithoutNewLine(t *testing.T) { + dataWithoutNewLine := make([]byte, 100) + for i := range dataWithoutNewLine { + dataWithoutNewLine[i] = 'A' + } + + tmpfile := newTempFileWithData(dataWithoutNewLine) + + w, err := prepFile(tmpfile) + if err != nil { + t.Errorf("Expect nil, got %v", err) + } + + w.Close() + + defer os.Remove(tmpfile) +} + +func TestPrepFileWithNewLine(t *testing.T) { + dataWithoutNewLine := make([]byte, 100) + for i := range dataWithoutNewLine { + dataWithoutNewLine[i] = 'A' + } + dataWithoutNewLine[0] = '\n' + + tmpfile := newTempFileWithData(dataWithoutNewLine) + + w, err := prepFile(tmpfile) + if err != nil { + t.Errorf("Expect nil, got %v", err) + } + if w.count != 1 { + t.Errorf("Expect 1, got %v", w.count) + } + + w.Close() + + defer os.Remove(tmpfile) +}