From dbb6f94d95d557b9ad6eab660826255cef39857e Mon Sep 17 00:00:00 2001 From: albertony <12441419+albertony@users.noreply.github.com> Date: Fri, 10 Sep 2021 14:44:13 +0200 Subject: [PATCH] config: make temporary directory user-configurable See #5591 --- docs/content/docs.md | 16 +++++++++++++++ docs/content/flags.md | 1 + fs/config/config.go | 29 ++++++++++++++++++++++++++++ fs/config/configflags/configflags.go | 8 ++++++++ 4 files changed, 54 insertions(+) diff --git a/docs/content/docs.md b/docs/content/docs.md index 5a7183a2b..a6955a271 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -1554,6 +1554,22 @@ If using `--syslog` this sets the syslog facility (e.g. `KERN`, `USER`). See `man syslog` for a list of possible facilities. The default facility is `DAEMON`. +### --temp-dir=DIR ### + +Specify the directory rclone will use for temporary files, to override +the default. Make sure the directory exists and have accessible permissions. + +By default the operating system's temp directory will be used: +- On Unix systems, `$TMPDIR` if non-empty, else `/tmp`. +- On Windows, the first non-empty value from `%TMP%`, `%TEMP%`, `%USERPROFILE%`, or the Windows directory. + +When overriding the default with this option, the specified path will be +set as value of environment variable `TMPDIR` on Unix systems +and `TMP` and `TEMP` on Windows. + +You can use the [config paths](/commands/rclone_config_paths/) +command to see the current value. + ### --tpslimit float ### Limit transactions per second to this number. Default is 0 which is diff --git a/docs/content/flags.md b/docs/content/flags.md index 9fd078e76..980ab5d18 100644 --- a/docs/content/flags.md +++ b/docs/content/flags.md @@ -21,6 +21,7 @@ These flags are available for every command. --bwlimit BwTimetable Bandwidth limit in KiB/s, or use suffix B|K|M|G|T|P or a full timetable. --bwlimit-file BwTimetable Bandwidth limit per file in KiB/s, or use suffix B|K|M|G|T|P or a full timetable. --ca-cert string CA certificate used to verify servers + --temp-dir string Directory rclone will use for temporary files. (default "$TMPDIR") --cache-dir string Directory rclone will use for caching. (default "$HOME/.cache/rclone") --check-first Do all the checks before starting transfers. --checkers int Number of checkers to run in parallel. (default 8) diff --git a/fs/config/config.go b/fs/config/config.go index b1c7a51d9..0e72922d4 100644 --- a/fs/config/config.go +++ b/fs/config/config.go @@ -712,3 +712,32 @@ func makeCacheDir() (dir string) { } return filepath.Join(dir, "rclone") } + +// SetTempDir sets new default directory to use for temporary files. +// +// Assuming golang's os.TempDir is used to get the directory: +// "On Unix systems, it returns $TMPDIR if non-empty, else /tmp. On Windows, +// it uses GetTempPath, returning the first non-empty value from %TMP%, %TEMP%, +// %USERPROFILE%, or the Windows directory." +// +// To override the default we therefore set environment variable TMPDIR +// on Unix systems, and both TMP and TEMP on Windows (they are almost exclusively +// aliases for the same path, and programs may refer to to either of them). +// This should make all libraries and forked processes use the same. +func SetTempDir(path string) (err error) { + var tempDir string + if tempDir, err = filepath.Abs(path); err != nil { + return err + } + if runtime.GOOS == "windows" { + if err = os.Setenv("TMP", tempDir); err != nil { + return err + } + if err = os.Setenv("TEMP", tempDir); err != nil { + return err + } + } else { + return os.Setenv("TMPDIR", tempDir) + } + return nil +} diff --git a/fs/config/configflags/configflags.go b/fs/config/configflags/configflags.go index b7c656d9b..fbe5a93b1 100644 --- a/fs/config/configflags/configflags.go +++ b/fs/config/configflags/configflags.go @@ -6,6 +6,7 @@ package configflags import ( "log" "net" + "os" "strconv" "strings" @@ -23,6 +24,7 @@ var ( verbose int quiet bool configPath string + tempDir string dumpHeaders bool dumpBodies bool deleteBefore bool @@ -47,6 +49,7 @@ func AddFlags(ci *fs.ConfigInfo, flagSet *pflag.FlagSet) { flags.IntVarP(flagSet, &ci.Transfers, "transfers", "", ci.Transfers, "Number of file transfers to run in parallel.") flags.StringVarP(flagSet, &configPath, "config", "", config.GetConfigPath(), "Config file.") flags.StringVarP(flagSet, &config.CacheDir, "cache-dir", "", config.CacheDir, "Directory rclone will use for caching.") + flags.StringVarP(flagSet, &tempDir, "temp-dir", "", os.TempDir(), "Directory rclone will use for temporary files.") flags.BoolVarP(flagSet, &ci.CheckSum, "checksum", "c", ci.CheckSum, "Skip based on checksum (if available) & size, not mod-time & size") flags.BoolVarP(flagSet, &ci.SizeOnly, "size-only", "", ci.SizeOnly, "Skip based on size only, not mod-time or checksum") flags.BoolVarP(flagSet, &ci.IgnoreTimes, "ignore-times", "I", ci.IgnoreTimes, "Don't skip files that match size and time - transfer all files") @@ -278,6 +281,11 @@ func SetFlags(ci *fs.ConfigInfo) { log.Fatalf("--config: Failed to set %q as config path: %v", configPath, err) } + // Set path to temp dir + if err := config.SetTempDir(tempDir); err != nil { + log.Fatalf("--temp-dir: Failed to set %q as temp dir: %v", tempDir, err) + } + // Set whether multi-thread-streams was set multiThreadStreamsFlag := pflag.Lookup("multi-thread-streams") ci.MultiThreadSet = multiThreadStreamsFlag != nil && multiThreadStreamsFlag.Changed