Skip to content

Commit fa59149

Browse files
committed
handle when SeekEnd with offset < - max offset
1 parent ba755e4 commit fa59149

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

tail.go

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// Copyright (c) 2015 HPE Software Inc. All rights reserved.
33
// Copyright (c) 2013 ActiveState Software Inc. All rights reserved.
44

5-
//nxadm/tail provides a Go library that emulates the features of the BSD `tail`
6-
//program. The library comes with full support for truncation/move detection as
7-
//it is designed to work with log rotation tools. The library works on all
8-
//operating systems supported by Go, including POSIX systems like Linux and
9-
//*BSD, and MS Windows. Go 1.9 is the oldest compiler release supported.
5+
// nxadm/tail provides a Go library that emulates the features of the BSD `tail`
6+
// program. The library comes with full support for truncation/move detection as
7+
// it is designed to work with log rotation tools. The library works on all
8+
// operating systems supported by Go, including POSIX systems like Linux and
9+
// *BSD, and MS Windows. Go 1.9 is the oldest compiler release supported.
1010
package tail
1111

1212
import (
@@ -16,15 +16,17 @@ import (
1616
"io"
1717
"io/ioutil"
1818
"log"
19+
"math"
1920
"os"
2021
"strings"
2122
"sync"
2223
"time"
2324

25+
"gopkg.in/tomb.v1"
26+
2427
"github.com/nxadm/tail/ratelimiter"
2528
"github.com/nxadm/tail/util"
2629
"github.com/nxadm/tail/watch"
27-
"gopkg.in/tomb.v1"
2830
)
2931

3032
var (
@@ -221,14 +223,14 @@ func (tail *Tail) reopen() error {
221223
if os.IsNotExist(err) {
222224
tail.Logger.Printf("Waiting for %s to appear...", tail.Filename)
223225
if err := tail.watcher.BlockUntilExists(&tail.Tomb); err != nil {
224-
if err == tomb.ErrDying {
226+
if errors.Is(err, tomb.ErrDying) {
225227
return err
226228
}
227-
return fmt.Errorf("Failed to detect creation of %s: %s", tail.Filename, err)
229+
return fmt.Errorf("failed to detect creation of %s: %s", tail.Filename, err)
228230
}
229231
continue
230232
}
231-
return fmt.Errorf("Unable to open file %s: %s", tail.Filename, err)
233+
return fmt.Errorf("unable to open file %s: %s", tail.Filename, err)
232234
}
233235
break
234236
}
@@ -275,7 +277,7 @@ func (tail *Tail) tailFileSync() {
275277
// deferred first open.
276278
err := tail.reopen()
277279
if err != nil {
278-
if err != tomb.ErrDying {
280+
if !errors.Is(err, tomb.ErrDying) {
279281
tail.Kill(err)
280282
}
281283
return
@@ -284,9 +286,23 @@ func (tail *Tail) tailFileSync() {
284286

285287
// Seek to requested location on first open of the file.
286288
if tail.Location != nil {
287-
_, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence)
288-
if err != nil {
289-
tail.Killf("Seek error on %s: %s", tail.Filename, err)
289+
offset := tail.Location.Offset
290+
if tail.Location.Whence == io.SeekEnd && offset < 0 {
291+
ret, err := tail.file.Seek(0, io.SeekEnd)
292+
if err != nil {
293+
_ = tail.Killf("Seek error on %s: %s", tail.Filename, err)
294+
return
295+
}
296+
297+
// min of 0 and ret - tail.Location.Offset
298+
// if ret - tail.Location.Offset is negative, then 0 is returned
299+
// otherwise ret - tail.Location.Offset is returned
300+
301+
offset = int64(math.Min(0, float64(ret)-math.Abs(float64(offset))))
302+
}
303+
304+
if _, err := tail.file.Seek(offset, tail.Location.Whence); err != nil {
305+
_ = tail.Killf("Seek error on %s: %s", tail.Filename, err)
290306
return
291307
}
292308
}
@@ -312,7 +328,7 @@ func (tail *Tail) tailFileSync() {
312328
if cooloff {
313329
// Wait a second before seeking till the end of
314330
// file when rate limit is reached.
315-
msg := ("Too much log activity; waiting a second before resuming tailing")
331+
msg := "too much log activity; waiting a second before resuming tailing"
316332
offset, _ := tail.Tell()
317333
tail.Lines <- &Line{msg, tail.lineNum, SeekInfo{Offset: offset}, time.Now(), errors.New(msg)}
318334
select {
@@ -346,7 +362,7 @@ func (tail *Tail) tailFileSync() {
346362
// implementation (inotify or polling).
347363
err := tail.waitForChanges()
348364
if err != nil {
349-
if err != ErrStop {
365+
if !errors.Is(err, ErrStop) {
350366
tail.Kill(err)
351367
}
352368
return
@@ -359,7 +375,7 @@ func (tail *Tail) tailFileSync() {
359375

360376
select {
361377
case <-tail.Dying():
362-
if tail.Err() == errStopAtEOF {
378+
if errors.Is(tail.Err(), errStopAtEOF) {
363379
continue
364380
}
365381
return

0 commit comments

Comments
 (0)