Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F14754471
homedir.go
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Subscribers
None
homedir.go
View Options
package
homedir
import
(
"bytes"
"errors"
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
)
// DisableCache will disable caching of the home directory. Caching is enabled
// by default.
var
DisableCache
bool
var
homedirCache
string
var
cacheLock
sync
.
RWMutex
// Dir returns the home directory for the executing user.
//
// This uses an OS-specific method for discovering the home directory.
// An error is returned if a home directory cannot be detected.
func
Dir
()
(
string
,
error
)
{
if
!
DisableCache
{
cacheLock
.
RLock
()
cached
:=
homedirCache
cacheLock
.
RUnlock
()
if
cached
!=
""
{
return
cached
,
nil
}
}
cacheLock
.
Lock
()
defer
cacheLock
.
Unlock
()
var
result
string
var
err
error
if
runtime
.
GOOS
==
"windows"
{
result
,
err
=
dirWindows
()
}
else
{
// Unix-like system, so just assume Unix
result
,
err
=
dirUnix
()
}
if
err
!=
nil
{
return
""
,
err
}
homedirCache
=
result
return
result
,
nil
}
// Expand expands the path to include the home directory if the path
// is prefixed with `~`. If it isn't prefixed with `~`, the path is
// returned as-is.
func
Expand
(
path
string
)
(
string
,
error
)
{
if
len
(
path
)
==
0
{
return
path
,
nil
}
if
path
[
0
]
!=
'~'
{
return
path
,
nil
}
if
len
(
path
)
>
1
&&
path
[
1
]
!=
'/'
&&
path
[
1
]
!=
'\\'
{
return
""
,
errors
.
New
(
"cannot expand user-specific home dir"
)
}
dir
,
err
:=
Dir
()
if
err
!=
nil
{
return
""
,
err
}
return
filepath
.
Join
(
dir
,
path
[
1
:]),
nil
}
func
dirUnix
()
(
string
,
error
)
{
homeEnv
:=
"HOME"
if
runtime
.
GOOS
==
"plan9"
{
// On plan9, env vars are lowercase.
homeEnv
=
"home"
}
// First prefer the HOME environmental variable
if
home
:=
os
.
Getenv
(
homeEnv
);
home
!=
""
{
return
home
,
nil
}
var
stdout
bytes
.
Buffer
// If that fails, try OS specific commands
if
runtime
.
GOOS
==
"darwin"
{
cmd
:=
exec
.
Command
(
"sh"
,
"-c"
,
`dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`
)
cmd
.
Stdout
=
&
stdout
if
err
:=
cmd
.
Run
();
err
==
nil
{
result
:=
strings
.
TrimSpace
(
stdout
.
String
())
if
result
!=
""
{
return
result
,
nil
}
}
}
else
{
cmd
:=
exec
.
Command
(
"getent"
,
"passwd"
,
strconv
.
Itoa
(
os
.
Getuid
()))
cmd
.
Stdout
=
&
stdout
if
err
:=
cmd
.
Run
();
err
!=
nil
{
// If the error is ErrNotFound, we ignore it. Otherwise, return it.
if
err
!=
exec
.
ErrNotFound
{
return
""
,
err
}
}
else
{
if
passwd
:=
strings
.
TrimSpace
(
stdout
.
String
());
passwd
!=
""
{
// username:password:uid:gid:gecos:home:shell
passwdParts
:=
strings
.
SplitN
(
passwd
,
":"
,
7
)
if
len
(
passwdParts
)
>
5
{
return
passwdParts
[
5
],
nil
}
}
}
}
// If all else fails, try the shell
stdout
.
Reset
()
cmd
:=
exec
.
Command
(
"sh"
,
"-c"
,
"cd && pwd"
)
cmd
.
Stdout
=
&
stdout
if
err
:=
cmd
.
Run
();
err
!=
nil
{
return
""
,
err
}
result
:=
strings
.
TrimSpace
(
stdout
.
String
())
if
result
==
""
{
return
""
,
errors
.
New
(
"blank output when reading home directory"
)
}
return
result
,
nil
}
func
dirWindows
()
(
string
,
error
)
{
// First prefer the HOME environmental variable
if
home
:=
os
.
Getenv
(
"HOME"
);
home
!=
""
{
return
home
,
nil
}
// Prefer standard environment variable USERPROFILE
if
home
:=
os
.
Getenv
(
"USERPROFILE"
);
home
!=
""
{
return
home
,
nil
}
drive
:=
os
.
Getenv
(
"HOMEDRIVE"
)
path
:=
os
.
Getenv
(
"HOMEPATH"
)
home
:=
drive
+
path
if
drive
==
""
||
path
==
""
{
return
""
,
errors
.
New
(
"HOMEDRIVE, HOMEPATH, or USERPROFILE are blank"
)
}
return
home
,
nil
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 24, 1:22 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3708770
Attached To
rWCLI writeas-cli
Event Timeline
Log In to Comment