Skip to content

Commit c50db70

Browse files
committed
Version 1.34
1 parent 86df1ef commit c50db70

File tree

9 files changed

+1029
-512
lines changed

9 files changed

+1029
-512
lines changed

Changelog

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
2020-06-10 Version 1.34
2+
* Add manual in PDF
3+
* Add support for FreeBSD 11
4+
* Show scanning progress with colours on a tty
5+
* Detect when output is redirected to a file
6+
* [Windows] Maximize console window
7+
* Add support for SSH in non-interactive mode (no tty)
8+
* Tested with i386, Amd64, and ARM (Raspberry Pi 3)
9+
110
2019-05-12 Version 1.32
211
* Fix incorrect truncation of long filenames
312
* Add option to print sizes in human readable format

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Usage: tdu [options] [directory]
3333
```
3434
##Quick start guide for end users
3535
- If you just want to use the program on Linux or Windows x86-64, then you can download a ready-to-run binary at https://bitbucket.org/josephpaul0/tdu/downloads/
36+
- On the "Downloads" page, you will find packages for:
37+
- Linux (386, Amd64, Armv6), including Raspberry Pi.
38+
- Windows 7, 8, 10 (386, Amd64)
39+
- FreeBSD 11 (386, Amd64)
3640

3741
##Quick start guide for advanced users / developers
3842
- You need a Go compiler

doc/tdu.1

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH TDU 1 "2019-05-12" "1.32" "Top Disk Usage manual"
1+
.TH TDU 1 "2020-06-10" "1.34" "Top Disk Usage manual"
22

33
.SH NAME
44
tdu \- get information about largest files and directories
@@ -13,9 +13,9 @@ It is written in Go and is inspired by the well-known UNIX
1313
.B du
1414
command.
1515
.PP
16-
17-
It scans recursively all subdirectories starting at <directory> or at current
18-
directory by default.
16+
It scans recursively all subdirectories starting at <directory>
17+
.br
18+
or at current directory by default.
1919

2020
.SH FEATURES
2121
* Counts files, directories, links, sockets, pipes.
@@ -76,7 +76,7 @@ Does not cross filesystem boundaries. It behaves like
7676
.B du \-skx
7777

7878
.SH COPYRIGHT
79-
Copyright \(co 2019 Joseph Paul <joseph.paul1@gmx.com>.
79+
Copyright \(co 2019,2020 Joseph Paul <joseph.paul1@gmx.com>.
8080
.br
8181
License GPLv2+: GNU GPL version 2 or later.
8282

tdu.go

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import (
3838
)
3939

4040
const (
41-
prg_VERSION = "1.32"
41+
prg_VERSION = "1.34"
4242
dft_MAXSHOWNLINES = 15
4343
dft_MAXEMPTYDIRS = 0
4444
dft_MAXDENIEDDIRS = 0
@@ -91,6 +91,7 @@ type s_scan struct { // Global variables
9191
maxPathLen int64 // maximum directory path length
9292
maxFNameLen int64 // maximum filename length
9393
currentDevice uint64 // device number of current partition
94+
refreshDelay int64 // delay between progress bar updates
9495
maxWidth int // display width (tty columns)
9596
maxNameLen int // max filename length for depth = 1
9697
maxShownLines int // number of depth 1 items to display
@@ -105,6 +106,7 @@ type s_scan struct { // Global variables
105106
foundBoundary bool // found other filesystems
106107
showMax bool // show deepest and longest paths
107108
export bool // export result to Ncdu's JSON format
109+
tty bool // stdout is on a TTY
108110
humanReadable bool // print sizes in human readable format
109111
exportPath string // path to exported file
110112
exportFile *os.File // exported file
@@ -126,6 +128,7 @@ type s_scan struct { // Global variables
126128
start time.Time // time at process start
127129
msg chan string
128130
done chan bool
131+
sys interface{} // OS functions
129132
}
130133

131134
func detectOS(sc *s_scan) {
@@ -147,7 +150,7 @@ func detectOS(sc *s_scan) {
147150

148151
func getConsoleWidth(sc *s_scan) {
149152
sc.maxWidth = 80
150-
w := getTtyWidth()
153+
w := getTtyWidth(sc)
151154
if w >= 72 {
152155
if w <= 120 {
153156
sc.maxWidth = w
@@ -158,13 +161,15 @@ func getConsoleWidth(sc *s_scan) {
158161
sc.maxNameLen = sc.maxWidth - 43 // formatting: stay below N columns
159162
}
160163

161-
func newScanStruct(start time.Time) *s_scan {
164+
func newScanStruct(start time.Time, sys interface{}) *s_scan {
162165
var sc s_scan
163166
sc.pathSeparator = string(os.PathSeparator)
164167
sc.inodes = make(map[uint64]uint16, 256)
165168
sc.start = start
166169
sc.msg = make(chan string, 32)
167170
sc.done = make(chan bool)
171+
sc.refreshDelay = cst_PROGRESSBEAT
172+
sc.sys = sys
168173
return &sc
169174
}
170175

@@ -648,10 +653,6 @@ func changeDir(args []string) (string, error) {
648653
dir, _ = os.Getwd()
649654
return dir, nil
650655
}
651-
if len(args) > 1 {
652-
e1 := fmt.Errorf("Can only scan one top directory: got %d", len(args))
653-
return dir, e1
654-
}
655656
err := os.Chdir(args[0])
656657
if err != nil {
657658
e2 := fmt.Errorf("Cannot change directory to %s\n%v", args[0], err)
@@ -668,7 +669,7 @@ func changeDir(args []string) (string, error) {
668669
func usage(sc *s_scan) []string {
669670
flag.Usage = func() {
670671
showTitle()
671-
fmt.Println(" Copyright (c) 2019 Joseph Paul <joseph.paul1@gmx.com>")
672+
fmt.Println(" Copyright (c) 2020 Joseph Paul <joseph.paul1@gmx.com>")
672673
fmt.Println(" https://bitbucket.org/josephpaul0/tdu")
673674
fmt.Println()
674675
fmt.Printf(" Usage: %s [options] [directory]\n", os.Args[0])
@@ -739,6 +740,17 @@ func usage(sc *s_scan) []string {
739740
sc.export = true
740741
sc.exportPath = *ex
741742
}
743+
if len(flag.Args()) > 1 {
744+
fmt.Println()
745+
fmt.Printf("[ERROR] can only scan one top directory: got %d", len(args))
746+
fmt.Println()
747+
fmt.Println()
748+
fmt.Println("[TIP] Use double-quotes around the directory path if it contains spaces.")
749+
fmt.Println("[TIP] Example: tdu.exe \"C:\\Program Files\"")
750+
fmt.Println()
751+
flag.Usage()
752+
os.Exit(2)
753+
}
742754
return args
743755
}
744756

@@ -751,8 +763,9 @@ func showProgress(sc *s_scan) {
751763
var i int
752764
var m string
753765
space := strings.Repeat(" ", 42)
766+
fmt.Println()
754767
for {
755-
time.Sleep(cst_PROGRESSBEAT * time.Millisecond)
768+
time.Sleep(time.Duration(sc.refreshDelay) * time.Millisecond)
756769
select {
757770
case m = <-sc.msg:
758771
fmt.Print(space)
@@ -762,8 +775,7 @@ func showProgress(sc *s_scan) {
762775
}
763776
default:
764777
i++
765-
n := sc.nErrors + sc.nItems
766-
fmt.Printf(" [.... scanning... %6d ....]\r", n)
778+
printProgress(sc)
767779
}
768780
if m == cst_ENDPROGRESS {
769781
break
@@ -774,8 +786,10 @@ func showProgress(sc *s_scan) {
774786
}
775787

776788
func endProgress(sc *s_scan) {
777-
sc.msg <- cst_ENDPROGRESS
778-
<-sc.done
789+
if sc.tty {
790+
sc.msg <- cst_ENDPROGRESS
791+
<-sc.done
792+
}
779793
}
780794

781795
func push(sc *s_scan, msg string) {
@@ -790,7 +804,7 @@ func showTitle() {
790804
fmt.Println()
791805
}
792806

793-
func relocate(args []string) string {
807+
func relocate(sc *s_scan, args []string) string {
794808
d, err := changeDir(flag.Args())
795809
if err != nil {
796810
showTitle()
@@ -801,37 +815,49 @@ func relocate(args []string) string {
801815
return d
802816
}
803817

818+
func showResults(sc *s_scan, fi []file, total *file) {
819+
show(sc, fi, total) // Step 3
820+
showmax(sc, total) // step 4
821+
showempty(sc)
822+
showdenied(sc)
823+
showerrors(sc)
824+
showstreams(sc)
825+
showdevices(sc)
826+
}
827+
828+
func startProgress(sc *s_scan) {
829+
if sc.tty {
830+
go showProgress(sc)
831+
} else {
832+
fmt.Fprintln(os.Stderr, " Please wait...")
833+
}
834+
}
835+
804836
/* Basically, the process has got several steps:
805837
* 1. change directory to given path
806838
* 2. scan all files recursively, collecting 'stat' data
807839
* 3. sort results and output a list of biggest items at depth 1.
808840
* 4. show the largest files at any depth.
809841
*/
810842
func main() {
811-
osInit()
843+
_, sys := osInit()
812844
start := time.Now()
813-
sc := newScanStruct(start)
845+
sc := newScanStruct(start, sys)
814846
args := usage(sc)
815-
d := relocate(args) // step 1
847+
d := relocate(sc, args) // step 1
816848
detectOS(sc)
817-
clearTty()
849+
initTty(sc)
818850
getConsoleWidth(sc)
819851
showTitle()
820852
fmt.Printf(" OS: %s %s,", sc.os, runtime.GOARCH)
821853
fmt.Printf(" scanning [%s]...\n", d)
822854
ncduInit(sc)
823-
go showProgress(sc)
855+
startProgress(sc)
824856
var fi []file
825857
t, _ := scan(sc, &fi, ".", 1) // Step 2
826858
endProgress(sc)
827-
show(sc, fi, t) // Step 3
828-
showmax(sc, t) // step 4
829-
showempty(sc)
830-
showdenied(sc)
831-
showerrors(sc)
832-
showstreams(sc)
833-
showdevices(sc)
859+
showResults(sc, fi, t)
834860
ncduEnd(sc)
835861
showElapsed(sc)
836-
osEnd()
862+
osEnd(sys)
837863
}

tdu_bsd.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// +build darwin freebsd
2+
3+
/* Top Disk Usage.
4+
* Copyright (C) 2019 Joseph Paul <joseph.paul1@gmx.com>
5+
* https://bitbucket.org/josephpaul0/tdu
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*/
12+
13+
package main
14+
15+
import (
16+
"syscall"
17+
)
18+
19+
func tcgets() uintptr {
20+
return uintptr(syscall.TIOCGETA)
21+
}

tdu_generic.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// +build !linux
22
// +build !windows
3+
// +build !freebsd
34

45
/* Top Disk Usage.
56
* Copyright (C) 2019 Joseph Paul <joseph.paul1@gmx.com>
@@ -15,6 +16,10 @@
1516

1617
package main
1718

19+
import (
20+
"fmt"
21+
)
22+
1823
func osInit() bool {
1924
return true
2025
}
@@ -27,7 +32,12 @@ func getTtyWidth() int {
2732
return 80
2833
}
2934

30-
func clearTty() {} // OS Specific
35+
func initTty(sc *sc_scan) {} // OS Specific
36+
37+
func printProgress(sc *s_scan) {
38+
n := sc.nErrors + sc.nItems
39+
fmt.Printf(" [.... scanning... %6d ....]\r", n)
40+
}
3141

3242
// Disk usage is inaccurate because appropriate syscall is not yet implemented
3343
func sysStat(sc *s_scan, f *file) error {

0 commit comments

Comments
 (0)