Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

Wrong CWD when running Wine programs from file manager,

New to Debian (Or Linux in general)? Ask your questions here!
Post Reply
Message
Author
bicyclesonthemoon
Posts: 11
Joined: 2018-03-06 22:00

Wrong CWD when running Wine programs from file manager,

#1 Post by bicyclesonthemoon »

Hello,
I was not completely sure if this's place is really in the beginner section, but my feeling is that I'm missing something obvious here that everybody else knows.

I have Debian 9 with LXDE.

I wrote a simple program and compiled it for Windows with mingw.
When testing the program I discovered that if I run the program by double clicking it (wrich opens it in Wine) then the current working directory was my home directory (instead of the directory where the exe is located and where it was clicked from the file manager).

I prepared a simple test program:

Code: Select all

#include <stdio.h>
#include <unistd.h>

int main (int argc, char **argv){
	char cwd[1024];
	FILE* file;
	getcwd(cwd, sizeof(cwd));
	file=fopen("Z:\\b\\pro\\cwdtest\\cwd.txt","w");
	if (file != NULL) {
		fprintf(file,"%s\n",cwd);
		fclose (file);
	}
	printf("%s\n",cwd);
}
which would write to some file its current working directory.
Some context: file is cwdwin.c in directory /b/pro/cwdtest and my home directory is /b
compiled with

Code: Select all

b@balt3:~/pro/cwdtest$ i686-w64-mingw32-g++ -o cwdwin.exe cwdwin.c 
b@balt3:~/pro/cwdtest$
and ran ot twice:
Once from the command line:

Code: Select all

b@balt3:~/pro/cwdtest$ wine cwdwin.exe 
Z:\b\pro\cwdtest
b@balt3:~/pro/cwdtest$
and the CWD was "Z:\b\pro\cwdtest".
and once by double-clicking cwdwin.exe from the file manager in directory /b/pro/cwdtest and the CWD was "Z:\b".

So it is true: When I run the program from command line the CWD is the directory from where I call it but if I click it from file manager CWD is my home directory.

Why is it like this?
How can I change it?

I wanted to find out if the problem is with Wine or with the file manager.
A very simple test: prepare a similar test program but this time compile it natively and not for windows.
I made:

Code: Select all

#include <stdio.h>
#include <unistd.h>

int main (int argc, char **argv){
	char cwd[1024];
	FILE* file;
	getcwd(cwd, sizeof(cwd));
	file=fopen("/b/pro/cwdtest/cwd.txt","w");
	if (file != NULL) {
		fprintf(file,"%s\n",cwd);
		fclose (file);
	}
	printf("%s\n",cwd);
}
I compiled

Code: Select all

b@balt3:~/pro/cwdtest$ g++ -o cwd cwd.c
b@balt3:~/pro/cwdtest$
I ran it from command line

Code: Select all

b@balt3:~/pro/cwdtest$ ./cwd
/b/pro/cwdtest
b@balt3:~/pro/cwdtest$
and like expected the CWD was "/b/pro/cwdtest"
I tried to run it by double clicking it from the file manager but I couldn't.
I detected another problem:
I'm not able to run native programs by double clicking on them. Not only this one but any program too.
When I click it it just asks me what program to open it with. And apparently it says that this is a "shared library" and not an executable file
(but it is an executable program and the execute bit is set). In Debian Wheezy I was able to run all programs by clicking them. On Stretch I can't.
I can run executable #! scripts, however. After clicking it says it's an executable script and I can chose to run or open it or cancel. Similar window appeared in Wheezy when clicking executable programs.
But here it thinks it's a shared library and doesn't give me this choice which is annoying.
Is this a MIME problem?
How do I solve it?
So because of this additional problem I was unable to determine if my original problem is fault of Wine or file manager.

So my actual problems are:

1. Why if I run Wine programs from file manager then CWD is set to my home directory? How to fix this?

2. Why I can't run normal programs from file manager? How to fix this?

I'll just add that this is a relatively recently installed system and so far only things I did with it was moving home directory from /home/b to /b, instaling some packets from the package manager, browsing some internet and writing some programs so there is low probability that I broke this by myself by some stupid actions.

Thanks in advance and please tell me if I have to provide additional information.
Last edited by bicyclesonthemoon on 2018-05-14 20:36, edited 1 time in total.

User avatar
debiman
Posts: 3063
Joined: 2013-03-12 07:18

Re: Wrong CWD when running Wine programs from file manager,

#2 Post by debiman »

bicyclesonthemoon wrote:So it is true: When I run the program from command line the CWD is the directory from where I call it but if I click it from file manager CWD is my home directory.
this (the latter) has something to do with the .desktop file that is associated with launching the app.
you need to read up on https://freedesktop.org/wiki/Specificat ... ntry-spec/

bicyclesonthemoon
Posts: 11
Joined: 2018-03-06 22:00

Re: Wrong CWD when running Wine programs from file manager,

#3 Post by bicyclesonthemoon »

I did some reading and I found this:
https://bugs.freedesktop.org/show_bug.cgi?id=97226
So it looks like my problem #2 (not being able to launch executable files from file manager) is caused by the fact that in Debian 9 the default form of executable files (compiled by me or already present in the system) is PIE (whatever that means) which is not distinguished by the MIME system from a shared executable.
Did I get it right?

So if I understand it correctly it's not that there is something wrong just for me but generally, on this version of Debian the functionality of running programs by clicking them in the file manager is broken and apparently not much is done about this.

I just cannot believe how this is even possible that such a basic and important functionality of the OS is missing and everyone allows it to be like this.

I just confirmed it by compiling it with -no-pie; I was able to run it by clicking then.
the CWD was "/b/pro/cwdtest" which means that my problem #1 (wrong CWD) is happening only for Wine.

So, if mime system is not able to distinguish some executable files from shared libraries, can I make the file manager treat shared libraries the same way as executables, so that clicking them will give me an option to run them? how? Can something bad happen it this is done?

User avatar
debiman
Posts: 3063
Joined: 2013-03-12 07:18

Re: Wrong CWD when running Wine programs from file manager,

#4 Post by debiman »

i think you're misunderstanding & overinterpreting something there.

what i meant is sth along the lines that it is possible to tell .desktop files which working directory to use.
or maybe not, i'm not so sure now.
imo, the way .desktop files and the associated applications work, it does not make much sense to always use the current working directory (where the application is called from), like with shell utilities.
you can however pass the current directory as an argument to your program.

your whole example looks like a proof-of-concept sort of thing, or an excercise, that has no practical value.

i'd just file what you learned and move on to the next excercise.

User avatar
bw123
Posts: 4015
Joined: 2011-05-09 06:02
Has thanked: 1 time
Been thanked: 28 times

Re: Wrong CWD when running Wine programs from file manager,

#5 Post by bw123 »

Here is some more reading...
https://www.debian.org/releases/stable/ ... ow-default
bicyclesonthemoon wrote: ...So if I understand it correctly it's not that there is something wrong just for me but generally, on this version of Debian the functionality of running programs by clicking them in the file manager is broken and apparently not much is done about this.
...
What do you mean by "the" file manager. I use mc, and it does just fine if I want to click a file that is marked as executable whether PIE or not? I checked dolphin, and it does report PIE ELF as "shared library" but they can be opened with xterm -e and work fine. Maybe slow down and explore your filemanager a little more... or try another, there are many.

good luck.

p.s. I have zero knowledge of wine, so I can't comment on it.

another edit: before someone beats me to it
http://linux.oneandoneis2.org/LNW.htm
Last edited by bw123 on 2018-05-15 19:46, edited 1 time in total.
resigned by AI ChatGPT

bicyclesonthemoon
Posts: 11
Joined: 2018-03-06 22:00

Re: Wrong CWD when running Wine programs from file manager,

#6 Post by bicyclesonthemoon »

"the" file manager here is PCManFM, which is the default for Debian with LXDE.
mc which I also use doesn't have problems.

"xterm -e" indeed allows me to run executable files from pcmanfm but then the CWD is changed to my home directory too.
So it looks like this is fault of PCManFM that the CWD is changed. Like you said.
So far did not find out if this can be changed.

User avatar
bw123
Posts: 4015
Joined: 2011-05-09 06:02
Has thanked: 1 time
Been thanked: 28 times

Re: Wrong CWD when running Wine programs from file manager,

#7 Post by bw123 »

Your c looks good and you obviously know how to research things, so if it's a bug file it (with a workaround or patch if possible) and if it's a config issue tweak it.
resigned by AI ChatGPT

User avatar
debiman
Posts: 3063
Joined: 2013-03-12 07:18

Re: Wrong CWD when running Wine programs from file manager,

#8 Post by debiman »

it's not a bug; there's a logical error on op's behalf, using .desktop files for small, self-written C exercises running under wine is not appropriate.
also i have pointed out that it is possible to pass the CWD to the program via .desktop file specs, if so desired.
of course pointless if the program's sole purpiose is to spit out the CWD...
:roll:

edit: oops, it's been 11 days... i was away for a while...

bicyclesonthemoon
Posts: 11
Joined: 2018-03-06 22:00

Re: Wrong CWD when running Wine programs from file manager,

#9 Post by bicyclesonthemoon »

debiman wrote:it's not a bug; there's a logical error on op's behalf, using .desktop files for small, self-written C exercises running under wine is not appropriate.
the self written C was only done for:
  • demonstrating the problem with a simple example program
  • testing in which situation the problem occurs and in which not
What I really mean is that the expected behavior is that when I double-click ANY executable file (and not just an example made by me) then the program will be run with the CWD set to the directory where I clicked it (which is where the file is located) but that is not happening in all cases.

With these test programs I was able to verify that this is not working for windows executables run in wine and PIE executables and that this is working for non-PIE executables and executable scripts.

I also asked a question on the pcmanfm-related forum but didn't get the answer I needed.
In the meantime I tried to determine by myself if I can change pcmanfm behavior by some its config and the answer is most likely no.
and tried to see in its source code how it exactly runs programs after clicking and I failed to find it but didn't spend much time on it.

Anyway I did find a solution and it does indeed use .desktop files.
debiman wrote:it is possible to pass the CWD to the program via .desktop file specs, if so desired.
Actually, not really. also that is not a generic solution. Unless I do some tricks.

So I found out that .desktop is my only remaining option.
So there is this the "Path" key which is used exactly for this reason.
Great, so something like

Code: Select all

Path=$PWD
should help.
But it didn't.
There could be 2 reasons:
  1. the PWD variable could be already set to home at this stage
  2. $PWD was not passed as the variable value but literally "$PWD"
I made a simple test program and made it print all its arguments and added $PWD to the "Exec" key and saw that it indeed was passed as just "$PWD". So this approach is useless.

I was told here and on the lxde forum that it is possible to pass the cwd as an argument by .desktop.
Like I already said this is not a generic solution.
On that forum a wrapper was suggested to me. This gave me an idea.
After some thinking I realised that it IS possible to make a generic wrapper.

I wrote this,
runcwd.c:

Code: Select all

//Niezła wymota
//This generic wrapper allows to run a program with specified CWD. First argument is the CWD, second is the program to run, rest are the parameters passed to that program

#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[], char *envp[])
{
	int r;
	
	if (argc<2) {
		fprintf(stderr,"%s\n","CWD missing.");
		return 1;
	}
	else if (argc <3) {
		fprintf(stderr,"%s\n","Command missing.");
		return 1;
	}
	
	if (chdir(argv[1]))
		fprintf(stderr,"Chdir to %s failed.\n",argv[1]);
	
	r=execve(argv[2],argv+2,envp);
	
	fprintf(stderr,"Failed to run %s.\n",argv[2]);
	return r;
}
A very simple program which
  • changes the cwd to the first argument
  • runs the program from the second argument
  • passes all next arguments to that program
The only thing left to do was to figure out how to pass the cwd as the first argument. And I found out that I can not do it.
$PWD is not an option but the Exec key has some special field codes. Maybe one of them could be useful?
From the available codes none is the directory.
There used to be a %d code which is exactly this but it is deprecated. I tested it and it does not work. Why remove such a useful option?
So I can not do it this way.
But I could modify it to extract the path from %f.

runcwdi.c:

Code: Select all

//Niezła wymota
//This generic wrapper allows to run a program with specified CWD. First argument is the CWD (must end with "/", anything after it is ignored), second is the program to run, rest are the parameters passed to that program

#include <string.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[], char *envp[])
{
	int r;
	
	if (argc<2) {
		fprintf(stderr,"%s\n","CWD missing.");
		return 1;
	}
	else if (argc <3) {
		fprintf(stderr,"%s\n","Command missing.");
		return 1;
	}
	
	for (r=strlen(argv[1])-1; r>=0; --r)
	{
		if (argv[1][r] == '/')
			break;
		argv[1][r]=0;
	}
	
	if (chdir(argv[1]))
		fprintf(stderr,"Chdir to %s failed.\n",argv[1]);
	
	r=execve(argv[2],argv+2,envp);
	
	fprintf(stderr,"Failed to run %s.\n",argv[2]);
	return r;
}
I modified it to cut everything after the last "/" in the path.

And, finally, it works.
I moved runcwdi to /usr/bin.
This is now my .desktop for windows executables:

Code: Select all

[Desktop Entry]
Type=Application
Name=winecwd
Exec=/usr/bin/runcwdi %f /usr/bin/wine %f
Categories=Other;
NoDisplay=true
MimeType=application/x-ms-dos-executable
Terminal=false
and this is now my .desktop for PIE executables:

Code: Select all

[Desktop Entry]
Type=Application
Name=execcwd
Exec=/usr/bin/runcwdi %f %f
Categories=Other;
NoDisplay=true
MimeType=application/x-sharedlib
Terminal=true
Now everything works like it should.
I'm glad that I made it work.
But I don't like the fact that it was necessary to do such things just to make the system work correctly.
I could solve this for myself after spending effort and time to figure it out and do it (when I could be drawing comics for example) and that's one of the basic functionalities of the OS, something that you would expect to just work by default. But not here.
Also some other people might not be able to fix this for themselves because it's not trivial.

Also, this is not the only problem I have with this system.
Another one is, for example, midi playback.
But that's a topic for another thread (coming soon).

User avatar
debiman
Posts: 3063
Joined: 2013-03-12 07:18

Re: Wrong CWD when running Wine programs from file manager,

#10 Post by debiman »

to anybody else reading this:
this is a non-problem.
op found some inconsistency somewhere and is spreading it wide and thin to make it look big and important.
it isn't.

also they've been doing this on at least one other forum.

Post Reply