diff --git a/chown_linux.go b/chown_linux.go index 465f569..642eec1 100644 --- a/chown_linux.go +++ b/chown_linux.go @@ -9,7 +9,11 @@ import ( var osChown = os.Chown func chown(name string, info os.FileInfo) error { - f, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, info.Mode()) + return chownWithMode(name, info, info.Mode()) +} + +func chownWithMode(name string, info os.FileInfo, mode os.FileMode) error { + f, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode) if err != nil { return err } diff --git a/linux_test.go b/linux_test.go index d1423c3..3801988 100644 --- a/linux_test.go +++ b/linux_test.go @@ -18,7 +18,6 @@ func testMaintainMode(t *testing.T, fileMode fs.FileMode) { filename := logFile(dir) - mode := os.FileMode(0600) l := &Logger{ Filename: filename, MaxBackups: 1, @@ -27,6 +26,7 @@ func testMaintainMode(t *testing.T, fileMode fs.FileMode) { } defer l.Close() + mode := defaultFileMode // If custom file mode is set then use it. if l.fileModeIsSet() { mode = l.FileMode @@ -89,7 +89,7 @@ func TestMaintainOwner(t *testing.T) { filename := logFile(dir) - f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, 0644) + f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, defaultFileMode) isNil(err, t) f.Close() @@ -121,7 +121,6 @@ func testCompressMaintainMode(t *testing.T, fileMode fs.FileMode) { filename := logFile(dir) - mode := os.FileMode(0600) l := &Logger{ Compress: true, Filename: filename, @@ -131,6 +130,7 @@ func testCompressMaintainMode(t *testing.T, fileMode fs.FileMode) { } defer l.Close() + mode := defaultFileMode // If custom file mode is set then use it. if l.fileModeIsSet() { mode = l.FileMode @@ -199,7 +199,7 @@ func TestCompressMaintainOwner(t *testing.T) { filename := logFile(dir) - f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, 0644) + f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, defaultFileMode) isNil(err, t) f.Close() @@ -292,3 +292,68 @@ func TestFileModeIsSet(t *testing.T) { equals(c.isSet, l.fileModeIsSet(), t) } } + +func testChangeModeOnRotate(t *testing.T, oldMode fs.FileMode, newMode fs.FileMode) { + currentTime = fakeTime + dir := t.TempDir() + defer os.RemoveAll(dir) + + // create logger + filename := logFile(dir) + l := &Logger{ + Filename: filename, + MaxBackups: 1, + MaxSize: 100, // megabytes + FileMode: oldMode, + } + defer l.Close() + + // create file + mode := defaultFileMode + if l.fileModeIsSet() { + mode = l.FileMode + } + f, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, mode) + isNil(err, t) + f.Close() + + // change logger file mode + l.FileMode = newMode + + // write something to the file + b := []byte("boo!") + n, err := l.Write(b) + isNil(err, t) + equals(len(b), n, t) + + // check that file permissions didn't change + info, err := os.Stat(filename) + isNil(err, t) + equals(mode, info.Mode(), t) + + // rotate the file + newFakeTime() + err = l.Rotate() + isNil(err, t) + + // check permissions for the rotated file + rotatedFilename := backupFile(dir) + rotatedInfo, err := os.Stat(rotatedFilename) + isNil(err, t) + equals(mode, rotatedInfo.Mode(), t) + // check permissions for the new file + expected := oldMode + if l.fileModeIsSet() { + expected = l.FileMode + } + info, err = os.Stat(filename) + isNil(err, t) + equals(expected, info.Mode(), t) +} + +func TestChangeModeOnRotate(t *testing.T) { + testChangeModeOnRotate(t, 0600, 0644) + testChangeModeOnRotate(t, 0644, 0600) + testChangeModeOnRotate(t, 0000, 0640) + testChangeModeOnRotate(t, 0640, 0000) +} diff --git a/lumberjack.go b/lumberjack.go index 3f86a52..f3f4694 100644 --- a/lumberjack.go +++ b/lumberjack.go @@ -132,6 +132,8 @@ var ( // variable so tests can mock it out and not need to write megabytes of data // to disk. megabyte = 1024 * 1024 + + defaultFileMode = os.FileMode(0644) ) // Write implements io.Writer. If a write would cause the log file to be larger @@ -218,16 +220,17 @@ func (l *Logger) openNew() error { } name := l.filename() - mode := os.FileMode(0644) - + mode := defaultFileMode if l.fileModeIsSet() { mode = l.FileMode } info, err := osStat(name) if err == nil { - // Copy the mode off the old logfile. - mode = info.Mode() + // If file mode is not set, use the mode of the existing file. + if !l.fileModeIsSet() { + mode = info.Mode() + } // move the existing file newname := backupName(name, l.LocalTime) if err := os.Rename(name, newname); err != nil { @@ -235,7 +238,7 @@ func (l *Logger) openNew() error { } // this is a no-op anywhere but linux - if err := chown(name, info); err != nil { + if err := chownWithMode(name, info, mode); err != nil { return err } } @@ -288,7 +291,7 @@ func (l *Logger) openExistingOrNew(writeLen int) error { return l.rotate() } - file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0644) + file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, defaultFileMode) if err != nil { // if we fail to open the old log file for some reason, just ignore // it and open a new log file.