Improve handling of the home directory creation.

This commit improves a couple of issues surrounding the creation of the
btcd home directory.

First, the code was previously attempting to log any errors that occurred
while creating the directory using the logging system which is not
initialized at that point.  Thus, nothing was displayed to the user.

Second, if any component of btcd home directory path already exists, but
is not a directory, such as in the case of symlinks, the error returned
from the os.MkDirAll call indicates the directory can't be created.  While
this is true, it's not always the most helpful error to display to the
user.  So, this commit adds logic to detect when the failure case is due
to an existing symlink and displays a nicer error message suggesting the
user check if the destination of the link is mounted.

Fixes #193.
This commit is contained in:
Dave Collins 2014-12-21 15:53:33 -06:00
parent bc46f8273c
commit f1cbd40713

View file

@ -318,20 +318,13 @@ func loadConfig() (*config, []string, error) {
// Service options which are only added on Windows.
serviceOpts := serviceOptions{}
// Create the home directory if it doesn't already exist.
err := os.MkdirAll(btcdHomeDir, 0700)
if err != nil {
btcdLog.Errorf("%v", err)
return nil, nil, err
}
// Pre-parse the command line options to see if an alternative config
// file or the version flag was specified. Any errors aside from the
// help message error can be ignored here since they will be caught by
// the final parse below.
preCfg := cfg
preParser := newConfigParser(&preCfg, &serviceOpts, flags.HelpFlag)
_, err = preParser.Parse()
_, err := preParser.Parse()
if err != nil {
if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
fmt.Fprintln(os.Stderr, err)
@ -391,8 +384,27 @@ func loadConfig() (*config, []string, error) {
return nil, nil, err
}
// Multiple networks can't be selected simultaneously.
// Create the home directory if it doesn't already exist.
funcName := "loadConfig"
err = os.MkdirAll(btcdHomeDir, 0700)
if err != nil {
// Show a nicer error message if it's because a symlink is
// linked to a directory that does not exist (probably because
// it's not mounted).
if e, ok := err.(*os.PathError); ok && os.IsExist(err) {
if link, lerr := os.Readlink(e.Path); lerr == nil {
str := "is symlink %s -> %s mounted?"
err = fmt.Errorf(str, e.Path, link)
}
}
str := "%s: Failed to create home directory: %v"
err := fmt.Errorf(str, funcName, err)
fmt.Fprintln(os.Stderr, err)
return nil, nil, err
}
// Multiple networks can't be selected simultaneously.
numNets := 0
// Count number of network flags passed; assign active network params
// while we're at it