FAQ
PTAL. All supported OSes have working implementations now.
Except perhaps OpenBSD, where procfs is not mounted by
default, but I don't know any alternatives.

+jsing.
On 2012/10/29 01:06:08, ality wrote:
btw, how to implement this on Plan 9?
func executable() (string, error) {
f, err := Open("/proc/" + itoa(Getpid()) + "/text")
if err != nil {
return "", err
}
defer f.Close()
return syscall.Fd2path(int(f.Fd()))
}
Thank you. I originally assumed fd2path on /proc/PID/text would
return "/proc/PID/text".

https://codereview.appspot.com/6736069/

Search Discussions

  • Anthony Martin at Oct 30, 2012 at 9:13 pm

    minux.ma@gmail.com once said:
    On 2012/10/29 01:06:08, ality wrote:
    btw, how to implement this on Plan 9?
    func executable() (string, error) {
    f, err := Open("/proc/" + itoa(Getpid()) + "/text")
    if err != nil {
    return "", err
    }
    defer f.Close()
    return syscall.Fd2path(int(f.Fd()))
    }
    Thank you. I originally assumed fd2path on /proc/PID/text would
    return "/proc/PID/text".
    Yeah, that's a reasonable assumption but the man page for
    fd2path(2) is careful with its words. There are only a few
    places in the kernel where this distinction is made. The
    prime example is the dup(3) device: when you open either
    of the fd files, a reference to the underlying channel is
    returned.

    It's similar for /proc/$pid/text.

    When you call exec(2) on an executable file, the kernel
    opens the file internally and saves a reference to the
    corresponding channel (along with some other state) into
    something called the "image cache". Then, when you open
    /proc/$pid/text, the original channel is retrieved from
    the cache and returned.
  • Rsc at Oct 30, 2012 at 9:29 pm
    https://codereview.appspot.com/6736069/diff/37032/src/pkg/os/executable.go
    File src/pkg/os/executable.go (right):

    https://codereview.appspot.com/6736069/diff/37032/src/pkg/os/executable.go#newcode7
    src/pkg/os/executable.go:7: // Executable returns the absolute pathname
    of the current
    In general this is impossible, of course, so it would be nice to be more
    specific about what the return value is good for.

    For example, if we wrote:
    // Executable returns a path that can be used to reinvoke the current
    program.
    // It may not be valid after the current program exits.

    then on Linux you could just return "/proc/PID/exe" and on Plan 9
    "/proc/PID/text".

    On the other hand, if there are subtler reasons for wanting this
    information, like trying to find associated files, then we'd need to be
    more clear that those are not acceptable answers. Personally, I don't
    believe we should try to support that use case, so my inclination would
    be to use just the description above and not do any kind of readlink or
    fd2path or anything like that.

    https://codereview.appspot.com/6736069/
  • Minux at Oct 30, 2012 at 9:44 pm

    On Wed, Oct 31, 2012 at 5:29 AM, wrote:

    src/pkg/os/executable.go:7: // Executable returns the absolute pathname
    of the current
    In general this is impossible, of course, so it would be nice to be more
    specific about what the return value is good for.
    Why impossible in general? Assumes nothing changes the environment (that is,
    nothing renames files, deletes files, etc.), this CL implemented the
    behavior on
    all supported OSes.
  • Rob Pike at Oct 30, 2012 at 9:52 pm
    Names are not unique, well-defined, or stable. It's the kind of thing
    that usually works but won't always, and the failures will be subtle.
    Code that depends on this interface will be buggy and maybe insecure.

    -rob
  • Daniel Theophanes at Oct 31, 2012 at 3:42 am
    As an observation, what you have mentioned is true, but is true for
    any path related api, such as os,Getwd(), or even os.Open. You don't
    actually know for sure that is correct until tested. And granted, some
    situations the path is more unstable then others. As an observer, I
    continue to not see the argument against it, though I understand it
    may not be useful to you. But this being my last comment here, should
    this not go in, I'll move what I can (most everything except darwin)
    into a third party package (if that's alright with minux to use his
    code for some of the platforms I don't have).

    -Daniel

    On Oct 30, 2012 2:46 PM, "Rob Pike" wrote:

    Names are not unique, well-defined, or stable. It's the kind of thing
    that usually works but won't always, and the failures will be subtle.
    Code that depends on this interface will be buggy and maybe insecure.

    -rob
  • Rob Pike at Oct 31, 2012 at 3:46 am
    No one has answered Russ's question (and mine). What is this _for_?

    -rob
  • Daniel Theophanes at Oct 31, 2012 at 3:52 am
    This is what I currently use this call for on Windows, Linux, and darwin
    right now:

    * Get a path to the exec when creating a "service" on windows, upstart,
    launchd.
    * I often bundle resources next to the exec for easy deployment.
    Without this I have to watch my working directory when I call it. Not
    horrible,
    but much easier just to get the path the OS already knows, no guesswork
    required,
    same deployment on all systems.

    Prior to this
    * On Linux I had to be sure to set the WD before starting (with nohup).
    * Couldn't get related files without this on Windows at all when running
    as a windows service.

    Does this answer your question?

    Thanks,
    -Daniel

    On Tuesday, October 30, 2012 8:46:40 PM UTC-7, Rob Pike wrote:

    No one has answered Russ's question (and mine). What is this _for_?

    -rob
  • Russ Cox at Nov 1, 2012 at 4:46 pm
    Using "Executable" to find related files bothers me quite a bit. I
    think Go doesn't have a good story for finding associated files, but
    if we want to address that I think we should do it head on instead of
    slipping it into a mostly unrelated function.

    If this were just for re-running the current executable I wouldn't
    mind. But it sounds like that's not why people want it. So my
    inclination is to leave it out for now.
  • Minux at Nov 1, 2012 at 4:55 pm

    On Fri, Nov 2, 2012 at 12:46 AM, Russ Cox wrote:

    Using "Executable" to find related files bothers me quite a bit. I
    think Go doesn't have a good story for finding associated files, but
    if we want to address that I think we should do it head on instead of
    slipping it into a mostly unrelated function.

    If this were just for re-running the current executable I wouldn't
    mind. But it sounds like that's not why people want it. So my
    inclination is to leave it out for now.
    OK, fair enough. I think we can do this.
    stop saying that the return path can be used to find related files
    (it just happen to be able to do this on major platforms, just readlink
    the returned path), and just address the re-running the current
    executable problem.

    I will remove all Readlink calls, and instead just return something
    like /proc/self/exe (I will keep the Plan 9 code, because the solution
    is not apparent).

    what do you think?
  • Russ Cox at Nov 1, 2012 at 5:23 pm
    If we limit Executable to that smaller scope it sounds like no one
    wants it anymore. So I would be inclined to leave it out.

    Russ
  • Minux at Nov 1, 2012 at 5:26 pm

    On Fri, Nov 2, 2012 at 1:23 AM, Russ Cox wrote:

    If we limit Executable to that smaller scope it sounds like no one
    wants it anymore. So I would be inclined to leave it out.
    Darwin, FreeBSD, Windows and Plan 9 all have non-trivial implementation for
    os.Executable (e.g. don't return a constant string)
  • Russ Cox at Nov 1, 2012 at 5:30 pm
    The complexity of the implementation needs to be paid for by general
    utility. I haven't heard anyone claiming they need or would use this
    function (except to find associated files, which I don't want to
    support this way).

    Russ
  • Brad Fitzpatrick at Nov 1, 2012 at 5:35 pm
    I would use this in things like gorunas, launching child processes of
    myself, since we don't have fork.

    In tests I always just use os.Args(0) which isn't guaranteed to be portable
    or even work always on Linux.
    On Nov 1, 2012 6:30 PM, "Russ Cox" wrote:

    The complexity of the implementation needs to be paid for by general
    utility. I haven't heard anyone claiming they need or would use this
    function (except to find associated files, which I don't want to
    support this way).

    Russ
  • Russ Cox at Nov 1, 2012 at 5:56 pm
    If you change the doc comment to

    // Executable returns a path that can be used to reinvoke the current
    program.
    // It may not be valid after the current program exits.

    and simplify the Plan 9 and Linux implementations, then I'll go along with this.
    (On Plan 9 use /proc/+itoa(pid)+/text.)

    On Thu, Nov 1, 2012 at 1:35 PM, Brad Fitzpatrick wrote:
    I would use this in things like gorunas, launching child processes of
    myself, since we don't have fork.

    In tests I always just use os.Args(0) which isn't guaranteed to be portable
    or even work always on Linux.
    On Nov 1, 2012 6:30 PM, "Russ Cox" wrote:

    The complexity of the implementation needs to be paid for by general
    utility. I haven't heard anyone claiming they need or would use this
    function (except to find associated files, which I don't want to
    support this way).

    Russ
  • Rob Pike at Nov 1, 2012 at 7:20 pm
    I'd still prefer to leave it out, for the reasons rsc said. I still
    believe it's a weak solution to a poorly-defined problem that's not
    the one most people actually want solved. and once it goes in we can't
    take it out or change its semantics to be something genuinely useful.

    That's not a veto, just a statement of preference. One use case does
    not a must-last-forever feature make.

    -rob
  • Minux Ma at Nov 1, 2012 at 8:00 pm
    PTAL.
    On 2012/11/01 17:49:57, rsc wrote:
    If you change the doc comment to
    // Executable returns a path that can be used to reinvoke the current
    program.
    // It may not be valid after the current program exits.
    and simplify the Plan 9 and Linux implementations, then I'll go along with
    this.
    (On Plan 9 use /proc/+itoa(pid)+/text.) Done.
    On 2012/11/01 19:20:40, r wrote:
    I'd still prefer to leave it out, for the reasons rsc said. I still
    believe it's a weak solution to a poorly-defined problem that's not
    now the problem is well defined: return a absolute path to re-invoke the
    same program.
    the one most people actually want solved. and once it goes in we can't
    take it out or change its semantics to be something genuinely useful.
    On Unix systems, you simply readlink the returned string, and you will
    get what you want. we just don't make that guarantee.


    https://codereview.appspot.com/6736069/
  • Daniel Theophanes at Nov 1, 2012 at 9:04 pm
    Hi, It seems this is hard to get it.

    However, I would suggest that returning the /proc/../exe path on procfs
    systems is a bad idea. We will simply have to write yet another wrapper to
    readlink on some systems, and take the literal value on others.
    ie
    panic: readlink C:\code\bin\example.exe: not supported by windows

    -Daniel

    On Thursday, November 1, 2012 1:00:55 PM UTC-7, minux wrote:

    PTAL.
    On 2012/11/01 17:49:57, rsc wrote:
    If you change the doc comment to
    // Executable returns a path that can be used to reinvoke the current
    program.
    // It may not be valid after the current program exits.
    and simplify the Plan 9 and Linux implementations, then I'll go along with
    this.
    (On Plan 9 use /proc/+itoa(pid)+/text.) Done.
    On 2012/11/01 19:20:40, r wrote:
    I'd still prefer to leave it out, for the reasons rsc said. I still
    believe it's a weak solution to a poorly-defined problem that's not
    now the problem is well defined: return a absolute path to re-invoke the
    same program.
    the one most people actually want solved. and once it goes in we can't
    take it out or change its semantics to be something genuinely useful.
    On Unix systems, you simply readlink the returned string, and you will
    get what you want. we just don't make that guarantee.


    https://codereview.appspot.com/6736069/
  • Minux at Nov 1, 2012 at 9:21 pm

    On Fri, Nov 2, 2012 at 5:04 AM, Daniel Theophanes wrote:

    However, I would suggest that returning the /proc/../exe path on procfs
    systems is a bad idea. We will simply have to write yet another wrapper to
    readlink on some systems, and take the literal value on others.
    ie
    panic: readlink C:\code\bin\example.exe: not supported by windows
    i think the best strategy is:
    if readlink returns an error, just use the previously returned result from
    Executable.
  • Taruti at Nov 1, 2012 at 10:14 pm
    Why not simply have a (using os/exec):

    func SelfCommand(arg ...string) (*exec.Cmd, error)

    If the idea is to have re-execute the current command.

    Would be much cleaner and allow for potentially better implementations.

    http://codereview.appspot.com/6736069/
  • Aram Hăvărneanu at Nov 2, 2012 at 10:07 am
    A very big -1 on this change. The original problem was "how to find
    assets bundled with binaries", a potentially valid concern, but when
    we found we can't solve that problem with the input we had, we decided
    to search for a new problem that fit the already implemented solution,
    "how to return a absolute path to re-invoke the same program", a
    problem no one asked.

    The semantics are different on each operating system, and on Plan 9
    they don't make sense at all.

    -- Aram
  • Minux at Nov 2, 2012 at 12:07 pm

    On Fri, Nov 2, 2012 at 5:59 PM, Aram Hăvărneanu wrote:

    A very big -1 on this change. The original problem was "how to find
    assets bundled with binaries", a potentially valid concern, but when
    we found we can't solve that problem with the input we had, we decided
    to search for a new problem that fit the already implemented solution,
    "how to return a absolute path to re-invoke the same program", a
    problem no one asked.
    As I've explained, my original patch set does implement the required
    behavior
    on all supported OSes.
    The problem is how to write correct document for it (e.g. how to precisely
    define the behavior).
    The semantics are different on each operating system, and on Plan 9
    they don't make sense at all.
    Why they don't make sense on Plan 9?

    To obtain proper asset filepath, you can do this to path obtained from
    Executable:
    On Unix, just readlink the returned path.
    On Plan 9, you need to open that file, and fd2path.
    On Windows, you don't need to do anything.
  • Russ Cox at Nov 2, 2012 at 8:20 pm
    There is enough disagreement about this that I would like to leave it
    for a 3rd-party package to implement, at least for now. I don't want
    to add an API that we'll be stuck with and regret.

    Thanks.
    Russ
  • Daniel Theophanes at Nov 2, 2012 at 8:23 pm
    Would it be possible to get in a CL just for darwin, and only have the call
    in syscall?

    On Fri, Nov 2, 2012 at 1:20 PM, Russ Cox wrote:

    There is enough disagreement about this that I would like to leave it
    for a 3rd-party package to implement, at least for now. I don't want
    to add an API that we'll be stuck with and regret.

    Thanks.
    Russ
  • Minux at Nov 3, 2012 at 6:15 am

    On Sat, Nov 3, 2012 at 4:20 AM, Russ Cox wrote:

    There is enough disagreement about this that I would like to leave it
    for a 3rd-party package to implement, at least for now. I don't want
    to add an API that we'll be stuck with and regret.
    It's fine for me to move this into a go-gettable package.
    I've found ways to implement the required functionality on
    Darwin without runtime changes.

    What about issue 4057? Should I close it with status unfortunate?
  • Russ Cox at Nov 6, 2012 at 7:35 pm
    Let's leave 4057 as priority-someday. Thanks.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-dev @
categoriesgo
postedOct 30, '12 at 4:12p
activeNov 6, '12 at 7:35p
posts26
users8
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase