Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os: Readlink should return destination even if link is broken #31996

Closed
mfojtik opened this issue May 13, 2019 · 6 comments
Closed

os: Readlink should return destination even if link is broken #31996

mfojtik opened this issue May 13, 2019 · 6 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@mfojtik
Copy link

mfojtik commented May 13, 2019

What version of Go are you using (go version)?

$ go version
go version go1.12.5 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPROXY=""
GORACE=""
GOTMPDIR=""
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

When reading a symlink with non-existing target the os.Readlink will return empty string and error. That makes reading the path of the target impossible.

For example, if you are in container and use shared PID namespace (which means you share the /proc) and you want to get a PID, one way to do so is to follow the /proc/PID/exe link.
In case of shared PID namespace, if you don't use the same image for containers sharing the /proc, it will return broken link (which is OK). Unfortunately, os.Readlink can't be used to get the destination string.

What did you expect to see?

I want to see the destination of a symlink, even when os.Readlink is not able to follow the link. It is fine to return the error, but the destination can be returned as well.
The caller can decide to ignore (or not to ignore) the returned destination.
There should be no breakage to existing code.

What did you see instead?

The os.Readlink return "", error on broken link.

@andybons andybons changed the title os: Readlink does not return destination when link is broken os: Readlink should return destination even if link is broken May 13, 2019
@andybons
Copy link
Member

@ianlancetaylor @bradfitz

@andybons andybons added NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels May 13, 2019
@andybons andybons added this to the Unplanned milestone May 13, 2019
@gopherbot gopherbot removed the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label May 13, 2019
@ianlancetaylor
Copy link
Contributor

I'm sorry, I don't understand what you mean. This program shows an example of reading a symlink whose destination does not exist, and it works without error.

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
)

func main() {
	tmpdir, err := ioutil.TempDir("", "readlink")
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(tmpdir)
	from := filepath.Join(tmpdir, "from")
	to := filepath.Join(tmpdir, "to")
	if err := os.Symlink(to, from); err != nil {
		panic(err)
	}
	fmt.Println(os.Readlink(from))
}

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label May 13, 2019
@networkimprov
Copy link

/proc/PID/exe is not a normal symlink; it's a resource of procfs.

This might reproduce it:

$ ln /usr/bin/cat ./mycat
$ ./mycat &
$ mypid=$!
$ rm ./mycat
$ ls -l /proc/$mypid/exe // try Go app with os.Readlink() here
$ kill %1

@ianlancetaylor
Copy link
Contributor

Thanks for the example. But when I try that on my system, os.Readlink("/proc/3540/exe") returns without error.

@bradfitz
Copy link
Contributor

@mfojtik, you say you're using go version go1.12.5 darwin/amd64 but there's no /proc on macOS.

What is your environment?

@gopherbot
Copy link

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

@golang golang locked and limited conversation to collaborators Jun 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

6 participants