mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-14 10:37:33 -07:00
.
This commit is contained in:
parent
e5bd230fb0
commit
8a9669f130
6 changed files with 307 additions and 79 deletions
108
go/pkg/zerotier/sizelimitwriter.go
Normal file
108
go/pkg/zerotier/sizelimitwriter.go
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c)2019 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2023-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package zerotier
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type sizeLimitWriter struct {
|
||||
f *os.File
|
||||
l sync.Mutex
|
||||
}
|
||||
|
||||
func sizeLimitWriterOpen(p string) (*sizeLimitWriter, error) {
|
||||
f, err := os.OpenFile(p, os.O_CREATE|os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Seek(0, os.SEEK_END)
|
||||
return &sizeLimitWriter{f: f}, nil
|
||||
}
|
||||
|
||||
// Write implements io.Writer
|
||||
func (w *sizeLimitWriter) Write(b []byte) (int, error) {
|
||||
w.l.Lock()
|
||||
defer w.l.Unlock()
|
||||
return w.f.Write(b)
|
||||
}
|
||||
|
||||
// Close closes the underlying file
|
||||
func (w *sizeLimitWriter) Close() error {
|
||||
w.l.Lock()
|
||||
defer w.l.Unlock()
|
||||
return w.f.Close()
|
||||
}
|
||||
|
||||
func (w *sizeLimitWriter) trim(maxSize int, trimFactor float64, trimAtCR bool) error {
|
||||
w.l.Lock()
|
||||
defer w.l.Unlock()
|
||||
|
||||
flen, err := w.f.Seek(0, os.SEEK_END)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flen > int64(maxSize) {
|
||||
var buf [131072]byte
|
||||
trimAt := int64(float64(flen) * trimFactor)
|
||||
if trimAt >= flen { // sanity check
|
||||
return nil
|
||||
}
|
||||
|
||||
if trimAtCR {
|
||||
lookForCR:
|
||||
for {
|
||||
nr, err := w.f.ReadAt(buf[0:1024], trimAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < nr; i++ {
|
||||
trimAt++
|
||||
if buf[i] == byte('\n') {
|
||||
break lookForCR
|
||||
}
|
||||
}
|
||||
if trimAt >= flen {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copyTo := int64(0)
|
||||
for trimAt < flen {
|
||||
nr, _ := w.f.ReadAt(buf[:], trimAt)
|
||||
if nr > 0 {
|
||||
wr, _ := w.f.WriteAt(buf[0:nr], copyTo)
|
||||
if wr > 0 {
|
||||
copyTo += int64(wr)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
err = w.f.Truncate(copyTo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.f.Seek(0, os.SEEK_END)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue