Windows vs. Linux GCC argv [0] value

Possible duplicate:
Get the path to the executable

I am programming Windows using MinGW, gcc 4.4.3. When I use the main function as follows:

int main(int argc, char* argv[]){ cout << "path is " << argv[0] << endl; } 

On Windows, I get the full path as follows: "C: / dev / stuff / bin / Test". However, when I run the same application on Linux, I get some kind of relative path: "bin / Test". It breaks my application! Any idea on how to make sure the path is absolute for both systems?

+6
source share
3 answers

No no. In most Linux shells, argv[0] contains exactly what the user typed to run the binary. This allows binary files to do different things depending on what the user is typing.

For example, a program with multiple command-line commands can install a binary file once, and then hard-link different commands to the same binary code. For example, on my system:

  $ ls -l / usr / bin / git *
 -rwxr-xr-x 109 root wheel 2500 640 16 May 18:44 / usr / bin / git
 -rwxr-xr-x 2 root wheel 121453 16 May 18:43 / usr / bin / git-cvsserver
 -rwxr-xr-x 109 root wheel 2500 640 16 May 18:44 / usr / bin / git-receive-pack
 -rwxr-xr-x 2 root wheel 1021264 16 May 18:44 / usr / bin / git-shell
 -rwxr-xr-x 109 root wheel 2500 640 16 May 18:44 / usr / bin / git-upload-archive
 -rwxr-xr-x 2 root wheel 1042560 16 May 18:44 / usr / bin / git-upload-pack
 -rwxr-xr-x 1 root wheel 323897 16 May 18:43 / usr / bin / gitk

Please note that some of these files are the same size. A more detailed study shows:

  $ stat / usr / bin / git
 234881026 459240 -rwxr-xr-x 109 root wheel 0 2500640 "Oct 29 08:51:50 2011" "May 16 18:44:05 2011" "Jul 26 20:28:29 2011" "May 16 18:44: 05 2011 "4096 4888 0 / usr / bin / git
 $ stat / usr / bin / git-receive-pack 
 234881026 459240 -rwxr-xr-x 109 root wheel 0 2500640 "Oct 29 08:51:50 2011" "May 16 18:44:05 2011" "Jul 26 20:28:29 2011" "May 16 18:44: 05 2011 "4096 4888 0 / usr / bin / git-receive-pack

The inode number (459240) is identical, and therefore these are two links to the same file on disk. When launched, the binary uses the contents of argv[0] to determine which function to execute. You can see this (sort) in the code for Git main() .

+9
source

argv array

argv[0] is a parameter like any other: it can be an arbitrary ending string with NUL bytes. This may be an empty string. This is what the startup process wants.

By default, the shell with the setting argv[0] used to indicate the program: the name found in $PATH , relative or absolute path. It can be a symbolic link or a regular file.

To invoke a program with some other value, with zsh (dunno with other shells) use:

  ARGV0 = whatever_you_want some_program arguments

If you really need a path to the executable, you cannot use the command line on Unix.

Linux only

On Linux: /proc/self/exe is a symbolic link to an executable file.

You can readlink it. You can also directly stat or open .

Rename and soft link

A normal soft link is a dumb line and does not know what is happening with its purpose (if it exists at all). But the soft link /proc/self/exe is magic.

In case of renaming, soft-but-magic-link will follow the renaming. If there are several hard links, this will follow the name of the specific hard link that was used. (So ​​different hard links to the same file are not exactly equivalent under Linux.)

If this hard link is disconnected, I think that " (deleted)" added to the value of the symlink. Note that this is a valid file name, so another unrelated file may have that name.

In any case, a symbolic link is a hard link to a file , so you can directly stat or open .

I do not think that you can count on anything in the network file system if the binary is renamed or detached on a different system than the one where the executable is running.

Security questions

When your program uses the special /proc/self/exe , the file used to run your program will be unlink ed or rename d. This should be taken seriously if the program has the privilege (SUID or Set Capabilities): even if the user does not have write access to the source binary “Set Something”, he can make a hard link to it if he has write access to the directory in that same file system, so it can change the name if a privileged binary is running.

By the time you readlink , the return value may refer to another file. (Of course, there is always an inevitable race condition with an open readlink result.)

As usual, NFS does not provide all the same guarantees as local file systems.

+4
source

It cannot be guaranteed that argv[0] is an absolute path, because it is assumed that it is called by the program. So, if you invoke your program on the Linux command line via ./bin/Test , then argv[0] must be exactly "./bin/Test" .

It seems that there is an error during the execution of MinGW if, when calling the program from the command line via .\bin\Test , argv[0] is "C:/dev/stuff/bin/Test" . With the latest version of MinGW (gcc version 4.5.2), invoking binary through .\bin\Test means argv[0] is equal to ".\bin\Test" . The Microsoft Visual C ++ Embedded Binary File (cl version 16.00.40219.01), called with .\bin\Test , also has ".\bin\Test" for argv[0] .

+3
source

Source: https://habr.com/ru/post/900352/


All Articles