I need to get the full path of an executable from inside the
program. I know, that I can just look into /proc/PID/exe, but I need a
method, that is a bit more portable between other unix-systems.
Any help will be appreciated!
Thanks
Stephan
--
/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
| EMail: s...@tzi.de __o |
| >>> ...destination anywhere, -\<, |
| >>> east or west, I don't care... (*)/(*) |
| WWW: http://www.tzi.de/~stk |
\____________________________________________________________/
PS: Ich widerspreche der Nutzung oder Uebermittlung meiner
Daten fuer Werbezwecke oder fuer die Markt- und Meinungsforschung
(ยง28 Abs. 3 Bundesdatenschutzgesetz)
>Hello.
>
>I need to get the full path of an executable from inside the
>program. I know, that I can just look into /proc/PID/exe, but I need a
>method, that is a bit more portable between other unix-systems.
There is no portable unix method of determining the full path of the
executable from inside the program.
See the Unix FAQ, question 1.14
http://www.faqs.org/faqs/unix-faq/programmer/faq/
Lew Pitcher, Information Technology Consultant, Toronto Dominion Bank Financial Group
(Lew_P...@td.com)
(Opinions expressed are my own, not my employer's.)
The best we can come up with is to use argv[0]:
- If it starts with a / assume it is the full path.
- If it contains a / assume it is a path relative
to the current directory.
- If it contains no / search through the PATH
environment variable for an executable with at
matching name.
Just keep in mind that somebody might deliberately
want to fool your program to think something else.
--
Kasper Dupont
What you should do is ask yourself:
Q: Why do I want to know where the executable is?
A: Because I want to do X.
Once you have that answer, then the question is: "Since I
_dont'_ know where my executable is, how do Unix programs
usually do X?"
--
Grant Edwards grante Yow! There's a lot of BIG
at MONEY in MISERY if you have
visi.com an AGENT!!
I once had a suid binary that I wanted to modify
it's own filepermtions. My conclusion was that
there was no secure way to do that.
--
Kasper Dupont
Often this is done so that you can then locate the configuration files
associated with a program by searching directories near the
executable. If the files are not around (because the program was
invoked via a symbolic link or something) it just complains that the
installation is incorrect and exits.
To which point 1.14.1 of the Unix Programmer's FAQ
(http://www.faqs.org/faqs/unix-faq/programmer/faq/) that I refered to says
"1.14.1 So where do I put my configuration files then?
-----------------------------------------------------
The correct directory for this usually depends on the particular flavour of
Unix you're using; `/var/opt/PACKAGE', `/usr/local/lib', `/usr/local/etc',
or any of several other possibilities. User-specific configuration files
are usually hidden `dotfiles' under `$HOME' (e.g. `$HOME/.exrc').
..."
Lew Pitcher
IT Consultant, Development Services
Toronto Dominion Bank Financial Group
(Opinions expressed are my own, not my employers')
> >> What you should do is ask yourself:
> >>
> >> Q: Why do I want to know where the executable is?
> >> A: Because I want to do X.
> >>
> >> Once you have that answer, then the question is: "Since I
> >> _dont'_ know where my executable is, how do Unix programs
> >> usually do X?"
> >
> >Often this is done so that you can then locate the configuration files
> >associated with a program by searching directories near the
> >executable. If the files are not around (because the program was
> >invoked via a symbolic link or something) it just complains that the
> >installation is incorrect and exits.
>
> To which point 1.14.1 of the Unix Programmer's FAQ
> (http://www.faqs.org/faqs/unix-faq/programmer/faq/) that I refered to says
> "1.14.1 So where do I put my configuration files then?
> -----------------------------------------------------
>
> The correct directory for this usually depends on the particular flavour of
> Unix you're using; `/var/opt/PACKAGE', `/usr/local/lib', `/usr/local/etc',
> or any of several other possibilities. User-specific configuration files
> are usually hidden `dotfiles' under `$HOME' (e.g. `$HOME/.exrc').
>
> ..."
The argument in the FAQ is pretty weak, basically boiling down to
"This is considered to be bad form." Well excuuuse me!
I might add that compiling fixed paths like "/usr/local/lib" into your
executable is far poorer form than locating the configuration files
using the perfectly adequate method of examining argv[0] and scanning
$PATH. What if you want to install multiple versions of a program?
What if you want to test a new version in your home directory? What
if you want users without root permission to be able to install and
use your software? So what if it won't work if someone tries to invoke
it via a symbolic link? The "approved" method will fail too if you
put the configuration files in the wrong place.
>> What you should do is ask yourself:
>>
>> Q: Why do I want to know where the executable is?
>> A: Because I want to do X.
>>
>> Once you have that answer, then the question is: "Since I
>> _dont'_ know where my executable is, how do Unix programs
>> usually do X?"
>
> Often this is done so that you can then locate the configuration files
> associated with a program by searching directories near the
> executable. If the files are not around (because the program was
> invoked via a symbolic link or something) it just complains that the
> installation is incorrect and exits.
Mixing configuration files (R/W data) with program executables
(RO data) is generally considered a bad idea. MSWindows does
it a *lot*.
'nuff said?
The Unix philosophy: executables go one place (it can be
read-only, shared between systems, updated when new versions
come out etc.). Configuration data goes somewhere else
(writable, unique to system or user, conserved across updates).
--
Grant Edwards grante Yow! I'm ZIPPY!! Are we
at having FUN yet??
visi.com
You're excused. Go ahead an do it if you want. It's possible
that Unix progrmmers over the past 30 years were all wrong, and
you're right.
It is considered bad form.
1) That means that if you do it that way, your program won't
work the way the rest of the system does. In the SW
engineering classes I took the definition of a bug is "when
a program doesn't do what a user reasonably expects it to
do." That was the only useful thing I learned in those
classes.
On a Unix system, a reasonable user will not exepct that
the location of configuration files depends on the location
of the executable. If your program does so, it is therefore
a bug. It will cause problems for users.
2) It's considered bad form for a _reason_ (several, actually):
a) It's a very useful thing to be able to put executable
stuff in a read-only filesystem and share it amongst
hosts. This precludes putting configuration data in the
same location, since it generally needs to be both
writable and host-specific.
b) Placing configuration files in a seperate location makes
it far easier to upgrade/reinstall the OS or program
without loosing the configuration data.
c) Putting all of the configuration files in known,
predicatable locations makes it easy to take a
"snapshot" of your system configuration without having
to save gigabytes of executable images that you don't
care about. IOW, you don't have to back up /usr/bin as
often (or at all, on some systems) compared with /etc or
the user home directories.
d) Historically, there's no reliable way to _find_ the
executable's path.
One could argue about whether d is the result or cause of a-c,
but at this point in the history of Unix it's a moot point.
--
Grant Edwards grante Yow! I know things about
at TROY DONAHUE that can't
visi.com even be PRINTED!!
Since I've been a Unix programmer for twenty five years they can't
*all* have been wrong, but...
> It is considered bad form.
>
> 1) That means that if you do it that way, your program won't
> work the way the rest of the system does. In the SW
> engineering classes I took the definition of a bug is "when
> a program doesn't do what a user reasonably expects it to
> do." That was the only useful thing I learned in those
> classes.
>
> On a Unix system, a reasonable user will not exepct that
> the location of configuration files depends on the location
> of the executable. If your program does so, it is therefore
> a bug. It will cause problems for users.
Reasonable users don't care about the location of the configuration
files. They have no expectation one way or another. They expect the
application to perform the task for which it was designed.
> 2) It's considered bad form for a _reason_ (several, actually):
>
> a) It's a very useful thing to be able to put executable
> stuff in a read-only filesystem and share it amongst
> hosts. This precludes putting configuration data in the
> same location, since it generally needs to be both
> writable and host-specific.
It does not preclude this at all, in general if the executable is
found in a directory such as <whatever>/usr/bin/foo the program can
look in <whatever>/var/lib/foo/ for configuration files. If
<whatever> happens to be the empty string the configuration files will
be found on the writable /var filesystem.
> b) Placing configuration files in a seperate location makes
> it far easier to upgrade/reinstall the OS or program
> without loosing the configuration data.
Per-user configuration data is a separate issue, and of course belongs
in the user's home directory. We're talking about system-wide
configuration files, such as those that appear in /etc - the files
that are installed or created when the program is installed, not while
it is running.
> c) Putting all of the configuration files in known,
> predicatable locations makes it easy to take a
> "snapshot" of your system configuration without having
> to save gigabytes of executable images that you don't
> care about. IOW, you don't have to back up /usr/bin as
> often (or at all, on some systems) compared with /etc or
> the user home directories.
The relative method doesn't preclude a program from installing its
configuration files in /etc, as demonstrated by my example above.
What it does do is allow multiple versions to coexist.
> d) Historically, there's no reliable way to _find_ the
> executable's path.
This is true in theory but irrelevant in practice. If the program's
installation is screwed up to the point that it can't find its own
executable you go in and fix it, like any other bug.
Oh? Then how does the shell find it, pray tell?
Or `which` for that matter?
Not that parsing the PATH env string, pwd, argv[0]
and a mess of symlinks & NFS mounts is easy or fun.
argv[0] has contained the pgm invocation name
from time immemorial [K&R] :) Now at least,
Linux & FreeBSD give the invocation path:
main (int argc, char *argv[]) {
printf ("%s \n", argv[0]) ;
}
-- Robert
>> d) Historically, there's no reliable way to
>> _find_ the executable's path.
>
> Oh? Then how does the shell find it, pray tell?
Pray tell, can you show me how/where the shell can tell you the
full pathname of the executable file associated with a
specified process? That is, after all, the question at hand --
not "what file would the shell execute if I typed 'foo'?"
> Or `which` for that matter?
Which is doing the same thing the shell does -- which is not
what we're trying to do.
> Not that parsing the PATH env string, pwd, argv[0]
> and a mess of symlinks & NFS mounts is easy or fun.
>
> argv[0] has contained the pgm invocation name
> from time immemorial [K&R]
Assuming whoever called exec() put it there. The caller of
exec() can put anything they want in argv[0]. Convention is to
put the name of the program there. It may be something else
entirely. It may not be a complete path, and if multiple files
with than name exists you have no way of knowing which one is
the right one.
If you search PATH for that name, you can _probably_ find it,
but it's not something I'd depend on.
--
Grant Edwards grante Yow! Fold, fold,
at FOLD!! FOLDING many items!!
visi.com
>> > The argument in the FAQ is pretty weak, basically boiling down to
>> > "This is considered to be bad form." Well excuuuse me!
>>
>> You're excused. Go ahead an do it if you want. It's possible
>> that Unix progrmmers over the past 30 years were all wrong, and
>> you're right.
>
> Since I've been a Unix programmer for twenty five years they can't
> *all* have been wrong,
Touchรฉ! :)
>> It is considered bad form.
>>
>> 1) That means that if you do it that way, your program won't
>> work the way the rest of the system does. In the SW
>> engineering classes I took the definition of a bug is "when
>> a program doesn't do what a user reasonably expects it to
>> do." That was the only useful thing I learned in those
>> classes.
>>
>> On a Unix system, a reasonable user will not exepct that
>> the location of configuration files depends on the location
>> of the executable. If your program does so, it is therefore
>> a bug. It will cause problems for users.
>
> Reasonable users don't care about the location of the configuration
> files.
Huh? How does configuration data get put into the files if
users don't put them there?
> They have no expectation one way or another. They expect the
> application to perform the task for which it was designed.
Including obeying the specifications I placed in the
configuration files.
>> a) It's a very useful thing to be able to put executable
>> stuff in a read-only filesystem and share it amongst
>> hosts. This precludes putting configuration data in the
>> same location, since it generally needs to be both
>> writable and host-specific.
>
> It does not preclude this at all, in general if the executable
> is found in a directory such as <whatever>/usr/bin/foo the
> program can look in <whatever>/var/lib/foo/ for configuration
> files. If <whatever> happens to be the empty string the
> configuration files will be found on the writable /var
> filesystem.
What if <whatever> is on a read-only filesystem? What if
<whatever> is on a system-wide fileserver and isn't
host-specific?
>> b) Placing configuration files in a seperate location makes
>> it far easier to upgrade/reinstall the OS or program
>> without loosing the configuration data.
>
> Per-user configuration data is a separate issue, and of course belongs
> in the user's home directory. We're talking about system-wide
> configuration files,
If they're not host specific, and you don't want them to be
writable, then you're right. I prefer my configuration files
to be writable and generally host-specific.
> such as those that appear in /etc - the files that are
> installed or created when the program is installed, not while
> it is running.
Well, I change stuff in /etc while programs are running, but I
don't see that that matters.
>> c) Putting all of the configuration files in known,
>> predicatable locations makes it easy to take a
>> "snapshot" of your system configuration without having
>> to save gigabytes of executable images that you don't
>> care about. IOW, you don't have to back up /usr/bin as
>> often (or at all, on some systems) compared with /etc or
>> the user home directories.
>
> The relative method doesn't preclude a program from installing its
> configuration files in /etc, as demonstrated by my example above.
> What it does do is allow multiple versions to coexist.
There are other ways to do the multiple version thing.
>> d) Historically, there's no reliable way to _find_ the
>> executable's path.
>
> This is true in theory
It's true in theory, historically. On Linux it's false (even
in theory) if you've got the /proc filesystem enabled.
/proc/[pid]/exe is a symlink to the executable file.
> but irrelevant in practice. If the program's installation is
> screwed up to the point that it can't find its own executable
> you go in and fix it, like any other bug.
I quite often run executables that are in directories that are
not in the PATH. That would break your program. I would be
pretty annoyed with a program if the executable had to be in a
specific directory for it to run.
--
Grant Edwards grante Yow! It's so OBVIOUS!!
at
visi.com
> I might add that compiling fixed paths like "/usr/local/lib" into your
> executable is far poorer form than locating the configuration files
> using the perfectly adequate method of examining argv[0] and scanning
> $PATH. What if you want to install multiple versions of a program?
> What if you want to test a new version in your home directory? What
> if you want users without root permission to be able to install and
> use your software? So what if it won't work if someone tries to invoke
> it via a symbolic link? The "approved" method will fail too if you
> put the configuration files in the wrong place.
This is why you do the following:
1. Use autoconf, which will allow the user to specify a location for
configuration files (and binaries, and...) when the program is
compiled.
2. Allow the user to specify an alternate location for the conffile on
the command line.
Combined with a sane default for (1), this is sufficient for
everything. Long-term installations into nonstandard locations
("nonstandard" being defined as "someplace other than where the
package maintainer thinks it should go") use (1); temporary or test
installations use (2).
Note that both the above solutions are highly portable.
--
Eric McCoy <ctr2...@yahoo.com>
"I woke up this morning and realized what the game needed: pirates,
pimps, and gay furries." - Rich "Lowtax" Kyanka
Are we talking about a pgm looking for it's config files,
or a hostile pgm trying to hide from the sysadmin?
Very different problems. I was talking about the first.
Walking the path in canonical order will work.
> If you search PATH for that name, you can _probably_
> find it, but it's not something I'd depend on.
It depends on the consequences of failure. If you're
looking for a config file, and the caller has trashed
the env/argv[0], failover to default should be acceptable.
-- Robert
Robert Redelmeier <red...@ev1.net> writes:
> > Assuming whoever called exec() put it there. The caller of
> > exec() can put anything they want in argv[0]. Convention is to
> > put the name of the program there. It may be something else
> > entirely. It may not be a complete path, and if multiple files
> > with than name exists you have no way of knowing which one is
> > the right one.
> Are we talking about a pgm looking for it's config files,
> or a hostile pgm trying to hide from the sysadmin?
> Very different problems. I was talking about the first.
> Walking the path in canonical order will work.
Not if the program is run as:
chdir("/home/emccoy");
execl("/home/emccoy/tmp/program", "program", NULL);
This is what we mean when we say the caller can put into exec()
whatever he wants. The above is a fairly realistic example (the
chdir() is in there just so you know that .../tmp is not the cwd), and
while I'd consider it bad code, there's nothing strictly wrong with
it.
> > If you search PATH for that name, you can _probably_
> > find it, but it's not something I'd depend on.
> It depends on the consequences of failure. If you're
> looking for a config file, and the caller has trashed
> the env/argv[0], failover to default should be acceptable.
The point is that there are a whole bunch of things you can do to the
env/argv[0] _short_ of trashing them where you still don't have enough
information. In the above example, the program name is perfectly
correct; it just doesn't contain enough path information for you to
find the executable. DOS shells put the complete path to the
program in argv[0], whereas Unix-like shells put only the path the
user gave. inetd lets you specify an arbitrary argv[0] in its config
file, and many programs therein actually _rely_ on being called with a
false argv[0].
And this is what we're talking about when we're saying that you
shouldn't go against established Unix practice of not relying on
argv[0] for anything important.
By the way, "failover to default" is not acceptable when the default
is to have a completely different search path. The program will look
in different locations for its conffile depending on how it is
called. At best, this will result in the program sometimes not
finding its conffile when it should; at worst, it will result in the
program reading a _different_ conffile in what appear, to the user
(and the admin), to be identical circumstances.
>> If you search PATH for that name, you can _probably_
>> find it, but it's not something I'd depend on.
>
>It depends on the consequences of failure. If you're
>looking for a config file, and the caller has trashed
>the env/argv[0], failover to default should be acceptable.
I would think so. Just remember to follow symlinks and watch
for the case where argv[0] specifies a path that's either
absolute or relative to the current directory: the file might
not be in the PATH.
--
Grant Edwards grante Yow! Do I have a lifestyle
at yet?
visi.com
>And this is what we're talking about when we're saying that you
>shouldn't go against established Unix practice of not relying
>on argv[0] for anything important.
Even if argv[0] was reliable, I'd still argue that location of
the executable and location of config files should be
orthogonal properties. I expect that I should be able to move
the executable file if I want to without breaking it. Whether
I meet your definition of "reasonable user" or not determines
whether such non-orthogonality is a bug according my previous
definition of "bug".
--
Grant Edwards grante Yow! HELLO KITTY gang
at terrorizes town, family
visi.com STICKERED to death!
> > Reasonable users don't care about the location of the configuration
> > files.
>
> Huh? How does configuration data get put into the files if
> users don't put them there?
Per-user configuration is usually done using an interactive dialog
called "Preferences". However, the files I'm talking about are not
per-user configuration files, but system wide files that are used by
the program: dynamically loaded libraries, interpreter source code,
icons and other images, etc. I'm going to bow out of this discussion
at this point, and you may interpret this any way you choose.
Even assuming that argv[0] has not been distorted, and does carry the
entire path to the command, as it was when the process was started,
there is no reason to believe that the path remains valid until after
the point at which the process enquires on argv[0].
For instance: The following sequence would leave argv[0] invalid even
though it is a full pathname:
ln /some/pgm /tmp/some/pgm
/tmp/some/pgm & rm /tmp/some/pgm
Immediately after the linked program is started, it's path is deleted.
This invalidates the argv[0] to /tmp/some/pgm even though it _was_
valid when the process was started.
Lew Pitcher, Information Technology Consultant, Toronto Dominion Bank Financial Group
(Lew_P...@td.com)
(Opinions expressed are my own, not my employer's.)
We agree. I'd consider this egregious code, and I'd
accept breakage. For two reasons: `chdir` is NOT a call
to be made lightly. But I won't go so far as to say it
should NEVER be done. The user has chosen the pwd for
a reason, presumably because her data resides there.
Second, the execl() is careless because it ignores
`program`s need to find files. Self-inflicted damage.
> The point is that there are a whole bunch of things you can do to the
> env/argv[0] _short_ of trashing them where you still don't have enough
> information. In the above example, the program name is perfectly
> correct; it just doesn't contain enough path information for you to
> find the executable. DOS shells put the complete path to the
> program in argv[0], whereas Unix-like shells put only the path the
> user gave. inetd lets you specify an arbitrary argv[0] in its config
> file, and many programs therein actually _rely_ on being called with a
> false argv[0].
False argv[0] has a use, and the pgm expects it. But calling a
pgm without the prerequisites and expecting it to work is silly.
> And this is what we're talking about when we're saying that you
> shouldn't go against established Unix practice of not relying on
> argv[0] for anything important.
Go tell that to the *BSD folk. IIRC /bin/cp /bin/mv and possibly
others are hardlinks to the same disk inodes. With some reason.
> By the way, "failover to default" is not acceptable when the default
> is to have a completely different search path. The program will look
> in different locations for its conffile depending on how it is
> called. At best, this will result in the program sometimes not
> finding its conffile when it should; at worst, it will result in the
> program reading a _different_ conffile in what appear, to the user
> (and the admin), to be identical circumstances.
What can I say? Bad code breaks.
If a pgm is going to behave differently depending on how it
is called, then it ought to document such odd behaviour.
And you should expect breakage when it's called otherwise.
The real question becomes: How idiotproof do you want to make it?
Caution: idoits can be really ingenious. And idiotproofing tends
to make troubleshooting harder. Sometimes early breakage is better
than patchup and run.
-- Robert
Oh, _thats_ what you're talking about!
I guess I wouldn't call that type of stuff "configuration
files" but rather library files. I understood "configuration
files" as the files the user edits to configure the appliction
-- either on system-wide, host-specific, or user-specific
basis.
--
Grant Edwards grante Yow! Hey, wait a
at minute!! I want a
visi.com divorce!!... you're not
Clint Eastwood!!
> > > Reasonable users don't care about the location of the configuration
> > > files.
> > Huh? How does configuration data get put into the files if
> > users don't put them there?
> Per-user configuration is usually done using an interactive dialog
> called "Preferences".
root is a reasonable (hopefully) user too.
> On 19 Oct 2001 12:25:18 -0700, David Fox <ds...@cogsci.ucsd.edu> wrote:
> >gra...@visi.com (Grant Edwards) writes:
> >
> >> > Reasonable users don't care about the location of the configuration
> >> > files.
> >>
> >> Huh? How does configuration data get put into the files if
> >> users don't put them there?
> >
> >Per-user configuration is usually done using an interactive dialog
> >called "Preferences". However, the files I'm talking about are not
> >per-user configuration files, but system wide files that are used by
> >the program: dynamically loaded libraries, interpreter source code,
> >icons and other images, etc. I'm going to bow out of this discussion
> >at this point, and you may interpret this any way you choose.
>
> Oh, _thats_ what you're talking about!
>
> I guess I wouldn't call that type of stuff "configuration
> files" but rather library files. I understood "configuration
> files" as the files the user edits to configure the appliction
> -- either on system-wide, host-specific, or user-specific
> basis.
I was responding to what appears in the FAQ to be a ban on even
attempting to determine the location of the executable for any
purpose.
: I need to get the full path of an executable from inside the
: program. I know, that I can just look into /proc/PID/exe, but I need a
: method, that is a bit more portable between other unix-systems.
/proc/pid/exe wouldn't give you path. It just give you an inode.
And it is maximum you can obtain.
You can then search entire filesystem for this inode, and often
you'll come out with several possible filenames in different
directories (i.e. hard links).
--
We question most of the mantras around here periodically, in case
you hadn't noticed. :-)
-- Larry Wall in <1997051019...@wall.org>
Oh, yes Mozilla does so. But I never would call it well-behaved
Unix application.
--
Linux: The OS people choose without $200,000,000 of persuasion.
-- Mike Coleman
On my system it appears to be an absolute symbolic link. ls -l
shows the complete path, and I'm pretty sure it's not searching
the entire disk until it finds the right i-node.
>You can then search entire filesystem for this inode, and often
>you'll come out with several possible filenames in different
>directories (i.e. hard links).
?
--
Grant Edwards grante Yow! I would like to
at urinate in an OVULAR,
visi.com porcelain pool --
> >/proc/pid/exe wouldn't give you path. It just give you an inode.
> On my system it appears to be an absolute symbolic link. ls -l
> shows the complete path, and I'm pretty sure it's not searching
> the entire disk until it finds the right i-node.
Probably not. But there's no reason the binary image of the
executable can't be deleted by the time you read it.
> >You can then search entire filesystem for this inode, and often
> >you'll come out with several possible filenames in different
> >directories (i.e. hard links).
> ?
I'm not sure which part of that triggered the "?", but...
Multiple directory entries can reference the same inode. Those are
hard links. They're roughly equivalent to deliberate cross-links on
FAT. Each instantiation of a hard link increments the inode's link
count; when the link count reaches zero, the inode is moved into free
space (i.e., deleted).
If you search the filesystem for an inode, you may thus get several
matches, since several different files may reference the same inode.
You can also hard link directories (if you're root), though it's
apparently an extremely bad idea.
Sure there is -- VM. It's been awhile since I checked,
but Linux used to only load one page (4KB) of the executable
but would load any others it needed by pagefaults. The
file inodes become the VM page backing store when they
the page gets reused. No write to swap.
I know this worked because I couldn't recompile to the
same pgm name while a previous version was running.
-- Robert
Robert Redelmeier <red...@ev1.net> writes:
> I know this worked because I couldn't recompile to the
> same pgm name while a previous version was running.
Try it now. It works just fine.
I didn't understand where the "searching for a name given an
inode problem" came into the picture.
--
Grant Edwards grante Yow! if it GLISTENS,
at gobble it!!
visi.com
gra...@visi.com (Grant Edwards) writes:
[/proc/pid/exe]
> I didn't understand where the "searching for a name given an
> inode problem" came into the picture.
I'm unclear on how, exactly, the symlink in question works.
Attempting to read /proc/1/exe results in "Permission denied," but
attempting to read /sbin/init works fine. So it is definitely not a
traditional symlink (on my system).
Reading it works fine for me, and it appears to give the same
result as reading /sbin/init. cmp /proc/1/exe /sbin/init
returns 0. Not sure why your system behaves differently.
> but attempting to read /sbin/init works fine. So it is
> definitely not a traditional symlink (on my system).
AFAICT, other than the size being 0, it seems to behave like a
normal symlink on my system: RH6.2, 2.2.16.
--
Grant Edwards grante Yow! Yow! I'm having a
at quadraphonic sensation
visi.com of two winos alone in a
steel mill!
gra...@visi.com (Grant Edwards) writes:
> > [/proc/pid/exe]
> > I'm unclear on how, exactly, the symlink in question works.
> > Attempting to read /proc/1/exe results in "Permission denied,"
> > but attempting to read /sbin/init works fine. So it is
> > definitely not a traditional symlink (on my system).
> Reading it works fine for me, and it appears to give the same
> result as reading /sbin/init. cmp /proc/1/exe /sbin/init
> returns 0. Not sure why your system behaves differently.
> AFAICT, other than the size being 0, it seems to behave like a
> normal symlink on my system: RH6.2, 2.2.16.
Probably because I am running 2.4.7. The kernel people might've
changed it to dodge the dangling symlink problem where an executable's
disk image is deleted while it's still running.
... or a user deliberately trying to fool a badly written set[ug]id
program?
>Not if the program is run as:
>
> chdir("/home/emccoy");
> execl("/home/emccoy/tmp/program", "program", NULL);
Exactly. Consider, that we'd have a set?id program trying to locate
its global configuration based on its own location. Then someone
comes around working the above trick. The poor program will happily
read the "user-specified" "global" configuration file.
>[...] and many programs therein actually _rely_ on being called with
>a false argv[0].
And some programs change their behaviour based on argv[0].
--
Wolf a.k.a. Juha Laiho Espoo, Finland
(GC 3.0) GIT d- s+: a C++ UH++++$ UL++++$ P++@ L+++ E(-) W+$@ N++ !K w !O
!M V PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h--- r+++ y+++
"...cancel my subscription to the resurrection!" (Jim Morrison)
There's actually two distinct counters (though only one on the fs);
the filesystem contains only the link count "How many times this
inode is referenced from directory entries?", but the kernel also
contains a use count "How many processes currently have this inode
open?". When you "rm" (unlink) a file, the directory entry for the
file disappears, and a new directory entry by the same name (but
different inode) can be created. Here the inode still remains, and
can be accessed by the programs that have it open. New opens with
the previous name will lead to opening the new file (or "ENOENT",
if there is no new file with the same name). The disk blocks (and
the inode) for the file will exist until the in-kernel use count
of the inode goes to zero. It seems that it is not possible to
create new links to a inode that does not have a direcctory entry,
even if you had the file open, and certainly there is no system
call to create a link to a file just by knowing the inode number.
>I know this worked because I couldn't recompile to the
>same pgm name while a previous version was running.
It seems that for whatever reason the compiler is trying to
overwrite the executable in-place (i.e. reuse the same inode).
See open(2) manual page for possible error messages.
As such it's completely possible to unlink a file that is in
use (executable being run; file being read or written).
> David Fox <ds...@cogsci.ucsd.edu> wrote:
> : gra...@visi.com (Grant Edwards) writes:
> :>
> :> Once you have that answer, then the question is: "Since I
> :> _dont'_ know where my executable is, how do Unix programs
> :> usually do X?"
>
> : Often this is done so that you can then locate the configuration files
> : associated with a program by searching directories near the
>
> On Unix? Really most people either put their configuration files
> in /etc and subdirectories (which easies backing them up and
> making them host-specific when executable is shared over NFS)
> or make their location compile-time option.
Ugh. All compile time options are bugs.
> gra...@visi.com (Grant Edwards) writes:
>
> > >/proc/pid/exe wouldn't give you path. It just give you an inode.
>
> > On my system it appears to be an absolute symbolic link. ls -l
> > shows the complete path, and I'm pretty sure it's not searching
> > the entire disk until it finds the right i-node.
>
> Probably not. But there's no reason the binary image of the
> executable can't be deleted by the time you read it.
If this happens your program is broken and you need to fix it.
What the hell? unlink() of binary being executed _is_ legitimate.
"Full path" may not exist. I.e. there may be _NO_ path to the
binary in question.
--
"You're one of those condescending Unix computer users!"
"Here's a nickel, kid. Get yourself a better computer" - Dilbert.
David Fox <ds...@cogsci.ucsd.edu> writes:
> Ugh. All compile time options are bugs.
No, they are called "sane defaults."
You have a case if and only if the program doesn't provide an
alternate method to access required files.
I'm using a 2.2.13 kernel, and it sure looks like a strange
symlink to me! If root does "cp /proc/1/exe xx", the file xx is
clearly a copy of /sbin/init; however look at the permissions
for /proc/1/exe and /sbin/init:
-rwxr-xr-x 1 root bin 20592 Jul 4 1997 /sbin/init
lrwx------ 1 root root 0 Oct 20 16:29 /proc/1/exe -> /sbin/init
I've never seen a "normal" symlink with permissions like that!
Moreover, it seems to fit what you've both described above.
--
Floyd L. Davidson <http://www.ptialaska.net/~floyd>
Ukpeagvik (Barrow, Alaska) fl...@barrow.com
David Fox <ds...@cogsci.ucsd.edu> writes:
> > > >/proc/pid/exe wouldn't give you path. It just give you an inode.
> > > On my system it appears to be an absolute symbolic link. ls -l
> > > shows the complete path, and I'm pretty sure it's not searching
> > > the entire disk until it finds the right i-node.
> > Probably not. But there's no reason the binary image of the
> > executable can't be deleted by the time you read it.
> If this happens your program is broken and you need to fix it.
What if the "program" is a user upgrading your application with a
newer version? Or just a user who deletes your program?
This entire "argument" is verging on (I'm feeling generous) utterly
useless pedantry. Do what you want. So long as you understand the
potential negative consequences, your program will likely not have
serious interaction problems; it may just impose some special-case
requirements beyond typical Unix applications.
> I'm using a 2.2.13 kernel, and it sure looks like a strange
> symlink to me! If root does "cp /proc/1/exe xx", the file xx is
> clearly a copy of /sbin/init; however look at the permissions
> for /proc/1/exe and /sbin/init:
> -rwxr-xr-x 1 root bin 20592 Jul 4 1997 /sbin/init
> lrwx------ 1 root root 0 Oct 20 16:29 /proc/1/exe -> /sbin/init
How about this?
% ls -l /proc/1/exe
ls: /proc/1/exe: Permission denied
lrwxrwxrwx 1 root root 0 Oct 20 20:53 /proc/1/exe
I like the sporadic error.
> I've never seen a "normal" symlink with permissions like that!
> Moreover, it seems to fit what you've both described above.
It works like yours - if I run `ls' as the user who owns the process.
Odd that I can't even see the destination of the symlink otherwise,
though.
Then you recompile it multiple times, specifying different prefix.
: What if you want to test a new version in your home directory? What
If you want to test something, you probably have sources.
: if you want users without root permission to be able to install and
: use your software? So what if it won't work if someone tries to invoke
You'll be silly if you want users without root permission install
something, sources of which you can examine.
--
I think that's easier to read. Pardon me. Less difficult to read.
-- Larry Wall in <1997101202...@wall.org>
:> > Reasonable users don't care about the location of the configuration
:> > files.
:>
:> Huh? How does configuration data get put into the files if
:> users don't put them there?
: Per-user configuration is usually done using an interactive dialog
: called "Preferences". However, the files I'm talking about are not
Interactive changes is not only way to deal with configuration.
There should be ability to back it up, to copy from machine to machine
etc.
: per-user configuration files, but system wide files that are used by
Same stands for per-site configuration files. They should be under
control of system administrator, not of application.
: the program: dynamically loaded libraries, interpreter source code,
: icons and other images, etc. I'm going to bow out of this discussion
Note that these files are clearly divided into several categories:
1) architecture specific files (such as dynamic libraries)
2) architecture independed files (interpreted scripts, images)
3) volatile files (which should reside on writable filesystems)
Moreover, often these files are not property of application.
Having dynamic libaries usially means that there are APIs which can
be used for other programs, icons should be available for window manager
and such.
Summing it up, it is expected that program installed on the system
becomes integrated part of system.
--
I'd put my money where my mouth is, but my mouth keeps moving.
-- Larry Wall in <1997040517...@wall.org>
: Are we talking about a pgm looking for it's config files,
: or a hostile pgm trying to hide from the sysadmin?
: Very different problems. I was talking about the first.
: Walking the path in canonical order will work.
It would find some name of inode of program executable image,
may be via some symlink or hardlink,
but you cannot guarantee that it would be that name, relative
to which support files can be found.
I, for instance, like to organize my desktop menu by creating symlink
to the program in special directory. Then some desktop gadget scans
this directory and shows menu. If application makes some assumption
about executable name (like mozilla) I have to put there script
rather than symlink, which highly complicates management of menu.
--
'Mounten' wird fะญr drei Dinge benutzt: 'Aufsitzen' auf Pferde, 'einklinken'
von Festplatten in Dateisysteme, und, nun, 'besteigen' beim Sex.
-- Christa Keil
Not only legitimate, but essential to the ability to upgrade a running
system.
--
John Hasler
jo...@dhh.gt.org
Dancing Horse Hill
Elmwood, Wisconsin
I had not tried it except as root, but as a normal user I get
the "Permission denied" message and it does not show me the
linked file, but it still shows the same permissions as it did
with root.
I tried ls -l on the entire /proc/1 directory, and there the other
three "symlinks" give the same result.
Not really. Use mv to change the name, install the new version,
wait until all users of the old version have finished, then rm
the old version. Of course for daemons or something else that
is running continously you just kill it and restart the new one.
Floyd Davidson <fl...@ptialaska.net> writes:
> Not really. Use mv to change the name, install the new version,
> wait until all users of the old version have finished, then rm
> the old version. Of course for daemons or something else that
> is running continously you just kill it and restart the new one.
Try doing that with libc. Have a rescue disk handy, though. (Hint:
you won't be able to run any programs once you rename libc, but your
old ones will continue running.)
I suspect that file-movement works using hard links anyway (make the
destination a hard link to the source, then unlink the source). So
even if what you're suggesting worked (it will if you do it all in one
program and ensure all the needed symbols are preloaded), it wouldn't
get around the problem.
I haven't bothered to look at the source for `mv', so I can't verify
that it works this way, but it's how I'd write the program.
Why?
>Floyd Davidson <fl...@ptialaska.net> writes:
>
>> Not really. Use mv to change the name, install the new version,
>> wait until all users of the old version have finished, then rm
>> the old version. Of course for daemons or something else that
>> is running continously you just kill it and restart the new one.
>
>Try doing that with libc. Have a rescue disk handy, though. (Hint:
>you won't be able to run any programs once you rename libc, but your
>old ones will continue running.)
But I didn't suggest moving a library, just a binary program that
is currently executing.
>I suspect that file-movement works using hard links anyway (make the
>destination a hard link to the source, then unlink the source). So
>even if what you're suggesting worked (it will if you do it all in one
>program and ensure all the needed symbols are preloaded), it wouldn't
>get around the problem.
>
>I haven't bothered to look at the source for `mv', so I can't verify
>that it works this way, but it's how I'd write the program.
In fact libc can be moved that way, but what is needed is a
staticly linked set of commands, including every command that
must be used to make the change.
> >And I continue my crusade to get cold.system removed from the
> >crossposting.
> Why?
What does this have to do with Linux system development?
> >> Not really. Use mv to change the name, install the new version,
> >> wait until all users of the old version have finished, then rm
> >> the old version. Of course for daemons or something else that
> >> is running continously you just kill it and restart the new one.
> >Try doing that with libc. Have a rescue disk handy, though. (Hint:
> >you won't be able to run any programs once you rename libc, but your
> >old ones will continue running.)
> But I didn't suggest moving a library, just a binary program that
> is currently executing.
There is no relevant difference between libraries and executables in
this context.
> >I suspect that file-movement works using hard links anyway (make the
> >destination a hard link to the source, then unlink the source). So
> >even if what you're suggesting worked (it will if you do it all in one
> >program and ensure all the needed symbols are preloaded), it wouldn't
> >get around the problem.
> >I haven't bothered to look at the source for `mv', so I can't verify
> >that it works this way, but it's how I'd write the program.
> In fact libc can be moved that way, but what is needed is a
> staticly linked set of commands, including every command that
> must be used to make the change.
It certainly would work, but I don't consider it a good solution.
> On 20 Oct 2001 00:12:26 +0400, Victor Wagner <vi...@wagner.rinet.ru> wrote:
> >Stephan Kuhagen <s...@tzi.de> wrote:
> >: Hello.
> >
> >: I need to get the full path of an executable from inside the
> >: program. I know, that I can just look into /proc/PID/exe, but I need a
> >: method, that is a bit more portable between other unix-systems.
> >
> >/proc/pid/exe wouldn't give you path. It just give you an inode.
>
> On my system it appears to be an absolute symbolic link. ls -l
> shows the complete path, and I'm pretty sure it's not searching
> the entire disk until it finds the right i-node.
That changed from 2.0 to 2.2.
Kai
--
http://www.westfalen.de/private/khms/
"... by God I *KNOW* what this network is for, and you can't have it."
- Russ Allbery (r...@stanford.edu)
> John Hasler <jo...@dhh.gt.org> wrote:
> >Alexander Viro writes:
> >> What the hell? unlink() of binary being executed _is_ legitimate.
> >
> >Not only legitimate, but essential to the ability to upgrade a running
> >system.
>
> Not really. Use mv to change the name, install the new version,
> wait until all users of the old version have finished, then rm
> the old version.
Well, yes, that is *why* it is essential. The "wait" step is unacceptable
in user space. On the other hand, if you unlink the old version (usually
by just renaming a new one over it), then the kernel will do that waiting
thing, and all is fine.
> gra...@visi.com (Grant Edwards) writes:
>
> > > Reasonable users don't care about the location of the configuration
> > > files.
> >
> > Huh? How does configuration data get put into the files if
> > users don't put them there?
>
> Per-user configuration is usually done using an interactive dialog
> called "Preferences".
For some reason, I often - in fact, usually - prefer the interactive
dialog called "vi". Part of that reason is because it has the same
keybindings for every application.
>However, the files I'm talking about are not
> per-user configuration files, but system wide files that are used by
> the program: dynamically loaded libraries, interpreter source code,
> icons and other images, etc.
*None* of which are usually considered configuration data. And *all* of
which can perfectly well be handled by the means discussed for
configuration files, except that for libraries there's also the LD_*
family of environment variables.
Of course, autoconf/command line options (or even environment variables)
are not only standard and portable, but also rather easy to understand ...
but I guess you're not really interested in *that*.
>I'm going to bow out of this discussion
> at this point, and you may interpret this any way you choose.
I certainly am. This much confusion about not only the state of the art
(which is hardly new) but also about terminology coming from someone who
claims to have been a Unix programmer for 25 years ... incredible.
> It works like yours - if I run `ls' as the user who owns the process.
> Odd that I can't even see the destination of the symlink otherwise,
> though.
Not all that odd. The kernel is just not willing to give out that
information to everybody, as that might create a security hole.
Remember, /proc is just a handful of C code in the kernel.
You just pointed out that there *is* a distinct difference!
>> >I suspect that file-movement works using hard links anyway (make the
>> >destination a hard link to the source, then unlink the source). So
>> >even if what you're suggesting worked (it will if you do it all in one
>> >program and ensure all the needed symbols are preloaded), it wouldn't
>> >get around the problem.
>> >I haven't bothered to look at the source for `mv', so I can't verify
>> >that it works this way, but it's how I'd write the program.
>
>> In fact libc can be moved that way, but what is needed is a
>> staticly linked set of commands, including every command that
>> must be used to make the change.
>
>It certainly would work, but I don't consider it a good solution.
It may not be for your situation, but that wasn't the point either.
It is a viable solution for the problem presented.
The "wait" step might well be inconvenient, and eliminating it equally
nice. But that is not _essential_ to accomplishing the task, which
was the original claim.
But this doesn't prevent anybody to delete a path from filesystem.
Open file descriptor is equivalent of another hard link,
so file wouldn't be actually deleted until last process, that have
opened it, would close file descriptor.
Process which uses this file as binary image, counts.
But file may not have filesystem links (i.e. directory entries)
at this time.
It is the way how install program works, allowing you to upgrade
say sshd without interrupting already opened ssh session.
: I know this worked because I couldn't recompile to the
: same pgm name while a previous version was running.
This is quite another thing. You cannot _modify_ image which is running
now. But nothing prevent you to unlink it, and then replace with
newer image.
--
You have to admit that it's difficult to misplace the Perl sources. :-)
-- Larry Wall in <1992Aug26.1...@netlabs.com>
> gra...@visi.com (Grant Edwards) writes:
>
> > In article <3BCD94...@daimi.au.dk>, Kasper Dupont wrote:
> > > Lew Pitcher wrote:
> > >>
> > >> On 17 Oct 2001 15:40:41 +0200, Stephan Kuhagen <s...@tzi.de> wrote:
> > >>
> > >> >Hello.
> > >> >
> > >> >I need to get the full path of an executable from inside the
> > >> >program. I know, that I can just look into /proc/PID/exe, but I need a
> > >> >method, that is a bit more portable between other unix-systems.
> > >>
> > >> There is no portable unix method of determining the full path of the
> > >> executable from inside the program.
> > >
> > > The best we can come up with is to use argv[0]:
> > > - If it starts with a / assume it is the full path.
> > > - If it contains a / assume it is a path relative
> > > to the current directory.
> > > - If it contains no / search through the PATH
> > > environment variable for an executable with at
> > > matching name.
> > >
> > > Just keep in mind that somebody might deliberately
> > > want to fool your program to think something else.
> >
> > What you should do is ask yourself:
> >
> > Q: Why do I want to know where the executable is?
> > A: Because I want to do X.
> >
> > Once you have that answer, then the question is: "Since I
> > _dont'_ know where my executable is, how do Unix programs
> > usually do X?"
>
> Often this is done so that you can then locate the configuration files
> associated with a program by searching directories near the
> executable. If the files are not around (because the program was
> invoked via a symbolic link or something) it just complains that the
> installation is incorrect and exits.
consider the hard link case.
ln /bin/foo /usr/bin/foo
once your program is running, which directory is the executable in --
/bin or /usr/bin or both? both are equally valid paths.
--
J o h a n K u l l s t a m
[kull...@mediaone.net]
Yes, but only one of them was used to start the program.
And actually Linux does remember which one. You can
readlink /proc/<pid>/exe or /proc/self/exe. But other
systems might only remember the inode number and not the
name. And if the caller doesn't tell you the information
might be lost already when the program starts.
Using argv[0] might be good in some cases, but don't
rely too much on it, and never let the security of suid
binaries rely on it.
--
Kasper Dupont
ok
1) it is non-portable
2) (hard) links are totally broken with respect to locating
configuration files.
> Using argv[0] might be good in some cases, but don't
> rely too much on it, and never let the security of suid
> binaries rely on it.
argv[0] might contain the full path (/bin/foo), but it also might
contain just the name (foo) or some local path like (../bin/foo). and
then argv[0] could be overwritten for even more fun.
--
J o h a n K u l l s t a m
[kull...@ne.mediaone.net]
sysengr
I know this is Linux specific. My point just was that
in this particular case the different paths are not
equally valid, one of them is the correct one.
> 2) (hard) links are totally broken with respect to locating
> configuration files.
Yes, a program using argv[0] to find its configuration
files would be broken. When writing software for UNIX/
Linux, do it the UNIX way not the M$ way. But there
might be other legimate reasons why you want to know
the path to your executable.
>
> > Using argv[0] might be good in some cases, but don't
> > rely too much on it, and never let the security of suid
> > binaries rely on it.
>
> argv[0] might contain the full path (/bin/foo), but it also might
> contain just the name (foo) or some local path like (../bin/foo). and
> then argv[0] could be overwritten for even more fun.
But repeating the path searching algorithm will find
the file for you. (Unless the caller is broken.) Of
course argv[0] can be overwritten, but overwriting it
first and trying to use it afterwards is just plain
stupid. Just do it in the correct order, nobody is
going to overwrite it. This can only be used to find
your own executable, not the executable of another
process. If you need the executable of another
process you have to do something nonportable like
using /proc/<pid>/exe or /proc/<pid>/maps.
>
> --
> J o h a n K u l l s t a m
> [kull...@ne.mediaone.net]
> sysengr
--
Kasper Dupont
>Kasper Dupont <kas...@daimi.au.dk> writes:
>
>> Johan Kullstam wrote:
>> >
>> > David Fox <ds...@cogsci.ucsd.edu> writes:
>> >
>> > > gra...@visi.com (Grant Edwards) writes:
>> > >
>> > > > In article <3BCD94...@daimi.au.dk>, Kasper Dupont wrote:
>> > > > > Lew Pitcher wrote:
>> > > > >>
>> > > > >> On 17 Oct 2001 15:40:41 +0200, Stephan Kuhagen <s...@tzi.de> wrote:
>> > > > >>
>> > > > >> >Hello.
>> > > > >> >
>> > > > >> >I need to get the full path of an executable from inside the
>> > > > >> >program. I know, that I can just look into /proc/PID/exe, but I need a
>> > > > >> >method, that is a bit more portable between other unix-systems.
[snip]
Which takes us back to the original question:
>> > > > >> >I know, that I can just look into /proc/PID/exe, but I need a
>> > > > >> >method, that is a bit more portable between other unix-systems.
And the answer seems to be (drum roll please)....
It's not possible to get an accurate pointer to the _real_ binary in a
portable manner, and if you think that you need this, you should
re-examine and rework your design.
Lew Pitcher, Information Technology Consultant, Toronto Dominion Bank Financial Group
(Lew_P...@td.com)
(Opinions expressed are my own, not my employer's.)
And in case anyone should think `oh, but we can just chase the
symlinks', consider that at one point I did something similar involving
hard links. Chase *that*.
--
`You're the only person I know who can't tell the difference
between a pair of trousers and a desk.' --- Kieran, to me
That's how it is done. The only statically linked command needed is
`sln', amd the window during which there is no libc is very small
(thought not zero, alas).
You mean that is in fact one (of several) ways. And at a minimum
a statically linked ln command is necessary.
:> gra...@visi.com (Grant Edwards) writes:
:>
:> > >/proc/pid/exe wouldn't give you path. It just give you an inode.
:>
:> > On my system it appears to be an absolute symbolic link. ls -l
:> > shows the complete path, and I'm pretty sure it's not searching
:> > the entire disk until it finds the right i-node.
:>
:> Probably not. But there's no reason the binary image of the
:> executable can't be deleted by the time you read it.
: If this happens your program is broken and you need to fix it.
Binary images of running programs typically disappear while program is
running for this very reason - someone want to upgrade them.
--
stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
-- Larry Wall in stab.c from the perl source code
: Not really. Use mv to change the name, install the new version,
: wait until all users of the old version have finished, then rm
Of course, it is possible. But it is against Unix philosophy - why
require user or (God forbids) system administrator to wait the thing
which can be easily detected and handled by system.
Unlink the file, and only values of its usage counter would be opened
filehandles in running processes. If last of them would close the
filehandle, counter would be decremented to zero and storage, occupied
by file, reclaimed automatically. No human intervention needed.
--
We apologize for the inconvenience, but we'd still like yout to test out
this kernel.
-- Linus Torvalds, announcing another kernel patch
: Floyd Davidson <fl...@ptialaska.net> writes:
:> Not really. Use mv to change the name, install the new version,
:> wait until all users of the old version have finished, then rm
:> the old version. Of course for daemons or something else that
:> is running continously you just kill it and restart the new one.
: Try doing that with libc. Have a rescue disk handy, though. (Hint:
: you won't be able to run any programs once you rename libc, but your
: old ones will continue running.)
: I suspect that file-movement works using hard links anyway (make the
: destination a hard link to the source, then unlink the source). So
It was once, in classic Unix. Most modern ones have an atomic "rename"
system call, which among other things allows to handle filesystems,
originated in broken OS-es, where multiple links are not allowed
--
Because I don't need to worry about finances I can ignore Microsoft
and take over the (computing) world from the grassroots.
-- Linus Torvalds
: Why?
:>Floyd Davidson <fl...@ptialaska.net> writes:
:>
:>> Not really. Use mv to change the name, install the new version,
:>> wait until all users of the old version have finished, then rm
:>> the old version. Of course for daemons or something else that
:>> is running continously you just kill it and restart the new one.
:>
:>Try doing that with libc. Have a rescue disk handy, though. (Hint:
:>you won't be able to run any programs once you rename libc, but your
:>old ones will continue running.)
: But I didn't suggest moving a library, just a binary program that
: is currently executing.
Whats the difference? Now there is no difference from binary image
of program and binary image of shared library from the point of
view of virtual FS. You are suggesting to introduce one? Why?
Or you are thinking that security holes are never found in shared
libraries, so on the fly update is not required?
--
Q: What's the big deal about rm, I have been deleting stuff for years? And
never lost anything.. oops!
A: ...
-- From the Frequently Unasked Questions
How long ago I haven't look into /proc/$$/exe!
I've just did couple of tests and find out that thing is broken
completely
I'm not sure that pointing to the interpreter rather than script
which is executing is wrong thing, and haven't checked how it would
work with BINFMT_MISC (executing java class or win32 binary through
wine), but if I do the following
mkdir tmpdir
cd tmpdir
ln ../bin/unlink_test .
cd ..
tmpdir/unlink_test&
pid=$!
rm tmpdir/unlink_test
ls -l /proc/$pid/exe
it shows /home/vitus/tmpdir/unlink_test (deleted)
while program is perfectly accessible via other link
${HOME}/bin/unlink_test
Moreover if I'm renaming image using mv (it seems that it uses atomic
rename(2)), link in /proc/$pid/exe is changed
but if I'm using traditional link;unlink sequence (using ln and rm from
shell) it stil shows old name marked with (deleted).
I think that it is pretty inconsistent behavoir, comparable only with
quality of X resource support in Gtk.
--
The documentation is in Japanese. Good luck.
-- Rich $alz
Where is the inconsistent part?
/proc/$pid/exe is a pointer to a directory entry. If you delete
that entry the system has to report it as deleted, even if there
are other links the system cannot start looking for them. You
might argue that appending " (deleted)" is ambigious if you
actually have a filename ending with that string. But there is
not much else it could do as the readlink systemcall cannot
both return a name and an additional information at the same
time. It might seem strange that renaming the file will update
the link, but that is because it is the same directory entry
and not another entry as in the other cases.
BTW I have another example that I find very inconsistent:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#define NAME1 "_qazsedcftgbhujmkol"
#define NAME2 "_lokmjuhbgtfcdeszaq"
int main()
{
unlink(NAME1);
unlink(NAME2);
close(creat(NAME1,0666));
link(NAME1,NAME2);
rename(NAME1,NAME2);
unlink(NAME2);
return 0;
}
I would expect that this program would leave no links to the
file created, but actually this program leaves one link to
the file. I have verified that other UNIX systems do the same,
and I have found the line in the Linux source responsible for
this. I just wonder who would want this behavior?
--
Kasper Dupont
Whow!!! I'd never thought, that there would be such a dispute about
this question. Maybe, I should ask every week such a question...
But thanks for all the answers and advisories. I found a sufficient
solution of the problem on my own: I looked at the implementation of
the Tcl-Interpreter. Tcl gives you the name of the exe with [info
nameofexecutable]. This might not be perfect, but it's good enough, so
I did a similar implementation. The reason I asked is, because I hoped
there is a simple Method, that I just don't know...
So, Response to your Response: You all are right, I know, that this is
bad programming-style for Unix (I'm programming Unix since nine
years), but sometimes you have to go unusual ways, especially if
working with Windows-People... I'm porting an app for medical imaging,
radiology image-processing etc. (http://www.mevis.de/MeVis/) to
Linux/Unix and for the first steps we need a posibility for a
self-containing installation-method (so, just copy a pre-compiled tgz
anywhere and use it) but with several versions coexisting on the same
filesystem.
Later this all will use autoconf and the canonical Unix-Defaults for
installation. I promise!!! ;-)
Thanks
Stephan
--
/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
| EMail: s...@tzi.de __o |
| >>> ...destination anywhere, -\<, |
| >>> east or west, I don't care... (*)/(*) |
| WWW: http://www.tzi.de/~stk |
\____________________________________________________________/
PS: Ich widerspreche der Nutzung oder Uebermittlung meiner
Daten fuer Werbezwecke oder fuer die Markt- und Meinungsforschung
(ยง28 Abs. 3 Bundesdatenschutzgesetz)
Read man page for inetd.conf and see that it has legitimate
use. I, for instance use it to let tcpwrappers distinguish
when pop3d is called by inetd (and thus is insecure) or
by stunnel.
Now consider that author of pop3d use stupid idea
discussed in this thread... (gladly there is more than
one pop3 server around)
--
Whoa...I did a 'zcat /vmlinuz > /dev/audio' and I think I heard God...
-- mikecd on #Linux
It cannot be overwritten by the caller, but the string
originally given by the caller could be wrong. A caller
giving a wrong string is broken, so in that case it is
OK for the program to fail.
>
> Read man page for inetd.conf and see that it has legitimate
> use. I, for instance use it to let tcpwrappers distinguish
> when pop3d is called by inetd (and thus is insecure) or
> by stunnel.
That manual page just states that argv[0] has to be
specified in the config file. Anything that can be
done by specifying an incorrect argv[0] should also
be possible using an option.
>
> Now consider that author of pop3d use stupid idea
> discussed in this thread... (gladly there is more than
> one pop3 server around)
Which stupid idea?
>
>
> --
> Whoa...I did a 'zcat /vmlinuz > /dev/audio' and I think I heard God...
> -- mikecd on #Linux
--
Kasper Dupont
Kasper Dupont <kas...@daimi.au.dk> writes:
[*argv]
> It cannot be overwritten by the caller, but the string
> originally given by the caller could be wrong. A caller
> giving a wrong string is broken, so in that case it is
> OK for the program to fail.
Your saying so does not make it true. Why expose argv[0] if setting
it to any value other than the executable's One True Path is never
valid behavior?
You know that every modern operating system provides a trivial way to
set an arbitrary argv[0], right? Obviously all the POSIX-like
operating systems do, but so do Windows, OS/2, and DOS.
Bearing in mind that the bulk of Unix history seems to be against you
on this one, what compelling reasons do you have for your argument?
So far I've seen repeated claims that an incorrect *argv is the result
of broken code, but no reason why we should consider that code broken.
Since I made such a claim, allow me to explain, it is a bit
of a philosophical or semantic difference.
If some code runs correctly under one set of circumstances
(free mem, libs present, file location, shell type, arvg[0])
it is NOT broken. It runs. If it fails under different
circumstances, that doesn't make it broken. It means the
code is fragile or not robust. A different defect.
What constitutes reasonable robustness or acceptable fragility
can be endlessly debated. Usually by self-serving parties.
If a shell stops code from running, that shell breaks the
code. That which breaks without intent, is itself broken.
Bull in the china shop.
-- Robert
> If some code runs correctly under one set of circumstances
> (free mem, libs present, file location, shell type, arvg[0])
> it is NOT broken. It runs. If it fails under different
> circumstances, that doesn't make it broken. It means the
> code is fragile or not robust. A different defect.
I, personally, apply different standards for brokenness depending on
the application. Any kernel which permits the system's stability to
be compromised by user applications is broken, for example. I do not
apply that, or any similar, standard to libc.
It's primary purpose is to facilitate a program to provide different functions
based on the name that invokes it. For example in a lot of older Unix systems
mv, cp, and, rm were all the same executable with hard links. So what happened
depended on the name that invoked the command.
blackblox works like this now.
BAJ
How would you tell tcpwrappers that program perform one service
when called from this line and quite another when called fromt that?
:> Now consider that author of pop3d use stupid idea
:> discussed in this thread... (gladly there is more than
:> one pop3 server around)
: Which stupid idea?
That program should put any significance in the full path of executable.
--
#Debian makes me feel all warm and fuzzy inside. :)
-- HippieGuy on #Debian
vi...@wagner.rinet.ru (Victor Wagner) writes:
> : That manual page just states that argv[0] has to be
> : specified in the config file. Anything that can be
> : done by specifying an incorrect argv[0] should also
> : be possible using an option.
> How would you tell tcpwrappers that program perform one service
> when called from this line and quite another when called fromt that?
By using arguments, like he said? To make program A run like program
B:
% ./A --run-like=B
It would arguably (ha!) be clearer than changing argv[0], though both
methods are certainly acceptable.
But we just learned from this thread that there is no way to know what
is going to end up in argv[0]!
Is that like busybox?
--
Grant Edwards grante Yow! NOT fucking!! Also
at not a PACKAGE of LOOSE-LEAF
visi.com PAPER!!
I would call that kernel fragile. It doesn't always break,
except when hit by the wrong hammer. OTOH, the common expectation
is you ought to be able to hit the kernel with a userland pile
driver and it not break. So it is unacceptably fragile.
As for `libc`, I think the common expectation is that you
should be able to make a legit call with any random values
and either get the foolish thing you asked for, or an error
return. There ought to be no expectation that you can trash
`libc`s working areas or jump into the middle of code without
causing wierdness. No way to prevent that without promoting
`libc` out of x86 Ring3 [userland] into Ring2,1, or 0 [kernel].
But you are right, expectations are a very personal thing.
Confusion sets in when they are unstated and assumed.
-- Robert
You have either:
1. The name of the executable
2. Relative path to the executable
3. Full path to the executable
4. Something else the caller used.
For 1-3, simply read everything after the last '/' to get the executable
name. If you use GNU ld, the global variable
program_invocation_short_name holds this, and program_invocation_name is
equivalent to argv[0]. For portability, you can easily define them
yourself.
If you have 4, i.e. something else, then simply revert to the default
behaviour. It's conventional to use the executable name, so this
shouldn't really be done. We can sanely cope with it haowever.
--
Roger Leigh ** Registration Number: 151826, http://counter.li.org **
Need Epson Stylus Utilities? http://gimp-print.sourceforge.net/
For GPG Public Key: finger rl...@tower.york.ac.uk or see public keyservers.
BRAIN LOCK! Sorry.
BAJ
>It seems that it is not possible to
>create new links to a inode that does not have a direcctory entry,
>even if you had the file open, and certainly there is no system
>call to create a link to a file just by knowing the inode number.
This is a design error in Unix; there should be a system call to open a
file by its inode number (incl. major/minor device no), and a system
call to link a currently-open file to a new name in the filesystem.
Nick.
--
Do not send me email copies of postings. Keep it in USENET please.
If a file has no entry in the directory structure, and is not open,
then it is garbage. Any access to garbage is a race condition, because
garbage gets recycled.
By the time you successfully open an inode that *is* known to be linked
into the directory structure just prior to the call, it may have become
unlinked and recycled as another file.
A mechanism that could save you would be wide inode numbers that don't get
reused, so that once an inode becomes garbage, its inode number remains
invalid, even if the inode is later reassigned. Only if the inode generator
cycles around its (large) range could there be an ambiguity.
Also, where do you get a valid inode number from, if not a directory
entry? If you have that, you can just open the file using the directory
entry name.
Inode level access is primarily useful to some file system debugging
utilities, or special backup programs like dump, not applications.
>call to link a currently-open file to a new name in the filesystem.
Superficially, I don't see any problem with this. Since you have a stable
reference to the file, there is no harm in linking it to the directory
structure somewhere.
>>This is a design error in Unix; there should be a system call to open a
>>file by its inode number (incl. major/minor device no), and a system
>
>If a file has no entry in the directory structure, and is not open,
>then it is garbage. Any access to garbage is a race condition, because
>garbage gets recycled.
>
>By the time you successfully open an inode that *is* known to be linked
>into the directory structure just prior to the call, it may have become
>unlinked and recycled as another file.
One would assume that opening an inode that isn't used would fail -- only
open() operations on valid inode numbers would be allowed. Any other
implimentation would be nonsensical.
>A mechanism that could save you would be wide inode numbers that don't get
>reused, so that once an inode becomes garbage, its inode number remains
>invalid, even if the inode is later reassigned. Only if the inode generator
>cycles around its (large) range could there be an ambiguity.
I don't think that would help, since the disk blocks would all be
deallocated and re-used even if the inode wasn't.
>Also, where do you get a valid inode number from, if not a directory
>entry?
From an open file-descriptor.
>If you have that, you can just open the file using the directory
>entry name.
>
>Inode level access is primarily useful to some file system debugging
>utilities, or special backup programs like dump, not applications.
Mabye so.
>>call to link a currently-open file to a new name in the filesystem.
>
>Superficially, I don't see any problem with this. Since you have a stable
>reference to the file, there is no harm in linking it to the directory
>structure somewhere.
--
Grant Edwards grante Yow! I know th'MAMBO!! I
at have a TWO-TONE CHEMISTRY
visi.com SET!!
A valid inode number would be one which has links in the
filesystem or is open in at least one process. But if
this should be allowed at all it should only be allowed
by root, otherwise you would introduce some security
problems. Imagine a file located in a directory you do
not have permitions to access, if you could guess the
inode number of the file you could still access the file.
(If you have read access but no execute access to the
directory you wouldn't even have to guess.)
--
Kasper Dupont
File permissions are in the inode, not the directory.
--
Joseph J. Pfeiffer, Jr., Ph.D. Phone -- (505) 646-1605
Department of Computer Science FAX -- (505) 646-1002
New Mexico State University http://www.cs.nmsu.edu/~pfeiffer
Southwestern NM Regional Science and Engr Fair: http://www.nmsu.edu/~scifair
Support Mayfield HS Band! Send me e-mail by 11/1 if you want to buy some fruit
> > A valid inode number would be one which has links in the
> > filesystem or is open in at least one process. But if
> > this should be allowed at all it should only be allowed
> > by root, otherwise you would introduce some security
> > problems. Imagine a file located in a directory you do
> > not have permitions to access, if you could guess the
> > inode number of the file you could still access the file.
> > (If you have read access but no execute access to the
> > directory you wouldn't even have to guess.)
> File permissions are in the inode, not the directory.
Yes, but if a file in /root is rw-rw-rw and /root itself is rwx------,
if a user correctly guesses the file's inode number, he would be able
to access it even though he strictly shouldn't be able to.
Nothing that Kasper said implies that he doesn't know this.
The file is located in a *directory* that you don't have permission
to access (and linked only in that directory).
The file's permissions permit reading, but the containing
directory is not readable, so you cannot access the file at all.
If you know the inode number and can open using that number,
you bypass the directory permissions.
For similar reasons, chroot-type mechanisms also become useless.
Using inode numbers, you can romp outside your sandbox.
> If a file has no entry in the directory structure, and is not open,
> then it is garbage. Any access to garbage is a race condition, because
> garbage gets recycled.
>
> By the time you successfully open an inode that *is* known to be linked
> into the directory structure just prior to the call, it may have become
> unlinked and recycled as another file.
>
Yes, I guess that's the reason Solaris has got clri(1m) and dcopy(1m)
commands that operate on i-nodes and clear them. Here is the quote from
clri(1m) man page:
SYNOPSIS
clri [ -F FSType ] [ -V ] special i-number
dcopy [ -F FSType ] [ -V ] special i-number
DESCRIPTION
clri writes zeros on the inodes with the decimal i-number on
the file system stored on special. After clri, any blocks
in the affected file show up as missing in an fsck(1M) of
special.
Read and write permission is required on the specified file
system device. The inode becomes allocatable.
The primary purpose of this routine is to remove a file that
for some reason appears in no directory. If it is used to
zap an inode that does appear in a directory, care should be
taken to track down the entry and remove it. Otherwise, when
the inode is reallocated to some new file, the old entry
will still point to that file. At that point, removing the
old entry will destroy the new file. The new entry will
again point to an unallocated inode, so the whole cycle is
likely to be repeated again and again.
dcopy is a symbolic link to clri.
Bye, Dragan
--
Dragan Cvetkovic,
To be or not to be is true. G. Boole
Sounds like this is supposed to be used on a filesystem
that is not currently mounted. And also sounds like it
is a very good idea to fsck the filesystem before
mounting it. And finally sounds like a good idea if this
command marks the fs dirty just to avoid disasters.
--
Kasper Dupont
I'd say it's a design feature, not an error. And creating the API you
suggest ("nopen(maj,min,ino)") would break some of the existing security
mechanisms.
Consider chroot(); you can only open files you see. With the "nopen()"
you could easily try to open any file on the FS -- from within the
chroot()'ed area. The only thing you wouldn't necessarily know would
be the file names.
The other breakable security mechanism would be to let files have relaxed
permissions when they're protected by directory permissions - like having
a file with mode 666 in a directory with mode 750: editing the file
will be possible for anyone having access to the directory, but for no
others. Your proposal would leave the file freely accessible by anyone.
What protection this gives, on top of just having the file in a public
directory, is that not even the file names are publicly visible on the
system.
--
Wolf a.k.a. Juha Laiho Espoo, Finland
(GC 3.0) GIT d- s+: a C++ UH++++$ UL++++$ P++@ L+++ E(-) W+$@ N++ !K w !O
!M V PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h--- r+++ y+++
"...cancel my subscription to the resurrection!" (Jim Morrison)