Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » GetExeFilePath() in Linux
GetExeFilePath() in Linux [message #6334] Tue, 07 November 2006 00:47 Go to next message
zsolt is currently offline  zsolt
Messages: 590
Registered: December 2005
Location: Budapest, Hungary
Contributor
I have implemented GetExeFilePath(). It is a little bit tricky, I dont know if it is able to work in BSD systems, but OK for Linux. It is based on the proc filesystem, as there is no standard posix function to this problem (AFAIK).
String GetExeFilePath()
{
	char h[_MAX_PATH + 1];
	String link;
	link << "/proc/" << getpid() << "/exe";
	int ret = readlink(link, h, _MAX_PATH);
	if(ret == -1 || ret > _MAX_PATH)
		return "";
	h[ret] = 0;
	return FromSystemCharset(h);
}

Re: GetExeFilePath() in Linux [message #6335 is a reply to message #6334] Tue, 07 November 2006 00:53 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12050
Registered: November 2005
Ultimate Member
Wow, this is really interesting solution to the problem! (Personally, I was thinking about searching in the path....).

Mirek
Re: GetExeFilePath() in Linux [message #6337 is a reply to message #6335] Tue, 07 November 2006 01:53 Go to previous messageGo to next message
guido is currently offline  guido
Messages: 169
Registered: April 2006
Experienced Member

Yes, that's thoroughly non-portable voodoo - Linux only.

Solaris has /proc too.
There it seems to be /proc/self/object/something

But on further investigation, Sun's Unix Systems had getexecname() since like forever:

http://docs.sun.com/app/docs/doc/816-5168/6mbb3hrbp?a=view

BSDs? No idea! Only thing I know is, they don't have /proc at all, MacOS X included.

Guido
Re: GetExeFilePath() in Linux [message #6338 is a reply to message #6337] Tue, 07 November 2006 09:35 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12050
Registered: November 2005
Ultimate Member
OK, so what we will do?

Separate branches for various posixes are OK, but before adding Linux version, I would like to know about BSDs.... (it has not much sense to have this in Linux only I think, win32 being specific affair).

Mirek
Re: GetExeFilePath() in Linux [message #6339 is a reply to message #6338] Tue, 07 November 2006 10:09 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 590
Registered: December 2005
Location: Budapest, Hungary
Contributor
After using google:
On FreeBSD u can use /proc/$pid/file. The only problem is, that /proc is not mounted by default Sad
Re: GetExeFilePath() in Linux [message #6363 is a reply to message #6339] Thu, 09 November 2006 20:27 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12050
Registered: November 2005
Ultimate Member
What about the original idea - perform search of argv[0] in PATH variable? Alternatively, as FreeBSD version?

Mirek
Re: GetExeFilePath() in Linux [message #6374 is a reply to message #6363] Thu, 09 November 2006 23:08 Go to previous messageGo to next message
masu is currently offline  masu
Messages: 378
Registered: February 2006
Senior Member
luzr wrote on Thu, 09 November 2006 20:27

What about the original idea - perform search of argv[0] in PATH variable? Alternatively, as FreeBSD version?

Mirek


This could be an appropriate solution for FreeBSD.
A silly question, but why do you need the location at all Wink?

Matthias


931b81e7ea53320dccc37375b34b38c3
Re: GetExeFilePath() in Linux [message #6377 is a reply to message #6374] Fri, 10 November 2006 00:13 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12050
Registered: November 2005
Ultimate Member
masu wrote on Thu, 09 November 2006 17:08

luzr wrote on Thu, 09 November 2006 20:27

What about the original idea - perform search of argv[0] in PATH variable? Alternatively, as FreeBSD version?

Mirek


This could be an appropriate solution for FreeBSD.
A silly question, but why do you need the location at all Wink?

Matthias



Well, a sort of win32-ism Smile

E.g. to put some data files there. Or .log files in debug version. I know it is not quite appropriate for Posix and in fact, that is why it was not defined for posix.

But Zoltan obviously has a use for it Wink

Mirek
Re: GetExeFilePath() in Linux [message #6379 is a reply to message #6377] Fri, 10 November 2006 01:01 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 590
Registered: December 2005
Location: Budapest, Hungary
Contributor
Quote:

But Zoltan obviously has a use for it

I just wanted to make my app installable to anywhere in the filesystem. I didn't want to hardcode a path to resource files.

I think, on FreeBSD GetExeFilePath() would try proc first and continue with searching when proc is not mounted.

Btw, Zoltan and Zsolt are different Hungarian names, my name is Zsolt Smile
Re: GetExeFilePath() in Linux [message #6384 is a reply to message #6379] Fri, 10 November 2006 09:22 Go to previous messageGo to next message
masu is currently offline  masu
Messages: 378
Registered: February 2006
Senior Member
zsolt wrote on Fri, 10 November 2006 01:01

I just wanted to make my app installable to anywhere in the filesystem. I didn't want to hardcode a path to resource files.


Will you execute your program with giving the complete path on the command line then?

Quote:

I think, on FreeBSD GetExeFilePath() would try proc first and continue with searching when proc is not mounted.


I agree Smile

Matthias
Re: GetExeFilePath() in Linux [message #6385 is a reply to message #6374] Fri, 10 November 2006 10:21 Go to previous messageGo to next message
fallingdutch is currently offline  fallingdutch
Messages: 258
Registered: July 2006
Experienced Member
masu wrote on Thu, 09 November 2006 23:08


A silly question, but why do you need the location at all Wink?

I don't see any use for it, too

you store your app in eg /usr/bin or /usr/local/bin and your ressources either in ~/.Appname/ or /var/Appname and your configuration in /etc/Appname.conf or ~/.Appname/Appname.conf

Bas
Re: GetExeFilePath() in Linux [message #6386 is a reply to message #6384] Fri, 10 November 2006 10:22 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 590
Registered: December 2005
Location: Budapest, Hungary
Contributor
masu wrote on Fri, 10 November 2006 09:22

zsolt wrote on Fri, 10 November 2006 01:01

I just wanted to make my app installable to anywhere in the filesystem. I didn't want to hardcode a path to resource files.


Will you execute your program with giving the complete path on the command line then?


No, but some admins prefer installing 3rd party apps not with /usr prefix, but with /usr/local or /opt. And some prefer putting it to e.g. /opt/appdir-version and using symlinks to switch easily between versions.
Re: GetExeFilePath() in Linux [message #6387 is a reply to message #6385] Fri, 10 November 2006 10:34 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12050
Registered: November 2005
Ultimate Member
fallingdutch wrote on Fri, 10 November 2006 04:21

masu wrote on Thu, 09 November 2006 23:08


A silly question, but why do you need the location at all Wink?

I don't see any use for it, too

you store your app in eg /usr/bin or /usr/local/bin and your ressources either in ~/.Appname/ or /var/Appname and your configuration in /etc/Appname.conf or ~/.Appname/Appname.conf

Bas



Well, that is current status quo - one that makes adding and removing applications in linux somewhat difficult.

What many would like to see is macosx like handling - all application specific files (minus configuration) are in single directory. You want to add application - you just copy the directory with application. You want to delete it - remove dir.

Mirek
Re: GetExeFilePath() in Linux [message #6388 is a reply to message #6386] Fri, 10 November 2006 10:48 Go to previous messageGo to next message
masu is currently offline  masu
Messages: 378
Registered: February 2006
Senior Member
Normally you run your application as a user and therefore the application does not have any write access to system directories llike /usr/local/bin. Reading is possible of course. But if you don't have write privileges on your application path, you also cannot store any files there.
So it does not matter where the application is located in the system unless you are using it as root, which is not advisable.

And if root installs software under /opt then it should also be read-restricted for normal users and normally these dirs are also added to PATH to comfortably execute them.

Matthias
Re: GetExeFilePath() in Linux [message #6393 is a reply to message #6388] Fri, 10 November 2006 12:17 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 590
Registered: December 2005
Location: Budapest, Hungary
Contributor
Quote:

But if you don't have write privileges on your application path, you also cannot store any files there.

I have a directory structure like this:

bin/appname - this is the binary
share/appname/ - this is a directory for document and configuration templates and other readonly resources

I have a lot of document and configuration templates and the application wants to READ them. I don't want to compile them into the app because they are extensible by installing additional packages.
I can write into the documentation, that resources have to be in e.g. /usr/local/share/appname/ directory, but it is not very admin friendly. It is much better to get these resources with the next algorithm:
GetFileFolder(GetExeFilePath()) + "/../share/" + appname + "/something.resource"
Re: GetExeFilePath() in Linux [message #6394 is a reply to message #6393] Fri, 10 November 2006 12:23 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12050
Registered: November 2005
Ultimate Member
Quote:


GetFileFolder(GetExeFilePath()) + "/../share/" + appname + "/something.resource"


Shorter equivalent:

GetExeDirFile("../share/" + appname + "/something.resource")

Mirek
Re: GetExeFilePath() in Linux [message #6395 is a reply to message #6394] Fri, 10 November 2006 12:35 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 590
Registered: December 2005
Location: Budapest, Hungary
Contributor
luzr wrote on Fri, 10 November 2006 12:23

Quote:


GetFileFolder(GetExeFilePath()) + "/../share/" + appname + "/something.resource"


Shorter equivalent:

GetExeDirFile("../share/" + appname + "/something.resource")

Mirek

This is why U++ is my favourite development environment Smile
Re: GetExeFilePath() in Linux [message #6398 is a reply to message #6393] Fri, 10 November 2006 16:28 Go to previous messageGo to next message
masu is currently offline  masu
Messages: 378
Registered: February 2006
Senior Member
zsolt wrote on Fri, 10 November 2006 12:17

I have a directory structure like this:

bin/appname - this is the binary
share/appname/ - this is a directory for document and configuration templates and other readonly resources

I have a lot of document and configuration templates and the application wants to READ them. I don't want to compile them into the app because they are extensible by installing additional packages.
I can write into the documentation, that resources have to be in e.g. /usr/local/share/appname/ directory, but it is not very admin friendly. It is much better to get these resources with the next algorithm:
GetFileFolder(GetExeFilePath()) + "/../share/" + appname + "/something.resource"


Now I understand your problem Very Happy and I vote for including to search via proc first and if it is not available in argv[0] and PATH.

Matthias
Re: GetExeFilePath() in Linux [message #6401 is a reply to message #6398] Fri, 10 November 2006 20:08 Go to previous messageGo to next message
fallingdutch is currently offline  fallingdutch
Messages: 258
Registered: July 2006
Experienced Member
you could write a config file in /etc and read the dir where the app-data (eg extensions) is stored (the way eg MySQL works)

Bas

[Updated on: Fri, 10 November 2006 20:08]

Report message to a moderator

Re: GetExeFilePath() in Linux [message #6411 is a reply to message #6401] Sat, 11 November 2006 12:48 Go to previous messageGo to previous message
mirek is currently offline  mirek
Messages: 12050
Registered: November 2005
Ultimate Member
OK, this is my final version:

const char *procexepath_() {
	static char h[_MAX_PATH + 1];
	ONCELOCK {
		char link[100];
		sprintf(link, "/proc/%d/exe", getpid());
		int ret = readlink(link, h, _MAX_PATH);
		if(ret > 0 && ret < _MAX_PATH)
			h[ret] = '\0';
		else
			*h = '\0';
	}
	return h;
}

String GetExeFilePath()
{
	static String exepath;
	ONCELOCK {
		const char *exe = procexepath_();
		if(exe)
			exepath = exe;
		else {
			String x = Argv0__;
			if(IsFullPath(x) && FileExists(x))
				exepath = x;
			else {
				exepath = GetHomeDirFile("upp");
				Vector<String> p = Split(FromSystemCharset(Environment().Get("PATH")), ':');
				if(x.Find('/') >= 0)
					p.Add(GetCurrentDirectory());
				for(int i = 0; i < p.GetCount(); i++) {
					String ep = NormalizePath(AppendFileName(p[i], x));
					if(FileExists(ep))
						exepath = ep;
				}
			}
		}
	}
	return exepath;
}


Please check.

Mirek

P.S.: I need the name of executable in log files, without using the heap and before entering the main - that is why I have separated "procexepath_"...

[Updated on: Sat, 11 November 2006 12:49]

Report message to a moderator

Previous Topic: Double formatting bug?
Next Topic: How to catch keyboard input?
Goto Forum:
  


Current Time: Sat Oct 19 04:39:56 CEST 2019

Total time taken to generate the page: 0.01732 seconds