0

I'm using Cygwin to get Linux functionality on Windows 11. Specifically, I am using Cygwin's xpdf to browse PDFs. It can open a hyperlinked URL if $BROWSER is set. Mysteriously, I found that I don't need to issue export BROWSER=firefox before issuing xpdf MyFile.pdf &. I just need a preceding BROWSER=firefox before the xpdf command.

# This works
BROWSER=firefox
xpdf MyFile.pdf &

Why is it that xpdf sees BROWSER=firefox even though I didn't export this at the Bash command line?

6
  • 1
    Did you do as one line BROWSER=firefox pdf or did you do BROWSER=firefox and then on the next line xpdf. Commented Jan 17 at 20:03
  • I issued them in separate lines (clarification added). However, I think that it may not be relying on the environment variable. It found firefox in my PATH, which includes ~/bin. I never had firefox.exe in ~/bin before today. Today, as I was trying to get xpdf to open URLs, I symbolically linked ~/bin/firefox.exe to the /c/Program Files/Mozilla Firefox/firefox.exe. Just now, I found that an old xpdf process follows links even though it was launched before I started to experiment with setting BROWSER. It stopped following links when I renamed ~/bin/firefox.exe. Commented Jan 17 at 20:09
  • There is very little information on what exactly happens when I click a link. The man page says URL links are opened in a system‐dependent way. (On UNIX, Qt uses the $BROWSER environment variable.) I'm wondering whether it is still worthwhile leaving this question up. It can certainly help someone trying to get xpdf to follow links. Commented Jan 17 at 20:12
  • Please add more details to your question, because now it is prone to be closed as unclear. Commented Jan 17 at 20:19
  • I would delete the question because your premise was wrong, so the question itself is wrong. If you want to ask a new question "how does xpdf in cygwin determine what browser to use" then that might make sense. Your current answer (symlink firefox.exe) is incomplete (what if there's a firefox.exe and a chrome.exe, or lynx or...?) so if you want a full answer that might be worth asking. Commented Jan 17 at 20:21

2 Answers 2

1

Exported variables are visible to child processes. If you don't need to specifically export a variable for it be used by a child process it means it has already been exported before.

You can verify by starting a new bash session and examining value of BROWSER:

env | grep ^BROWSER=

Notice also that on Linux and possibly Cywin some programs will use xdg-open to open a web browser or simply hard-code a browser to firefox. I have verified that xpdf version 4.05 on my Linux system indeed uses xdg-open using strace -f xpdf sed.pdf. It prints a lot of output and makes xpdf much slower but if you press the link you'll see:

[pid 32675] execve("/usr/bin/xdg-open", ["/usr/bin/xdg-open", "https://en.wikipedia.org/wiki/Qu"...], 0x7ffc65f08a30 /* 65 vars */ <unfinished ...>

This part of xpdf manpage is outdated but it's also not so simple:

Clicking on a hyperlink will jump to the link's destination. A link to another PDF document will make xpdf load that document. A ´launch' link to an executable program will display a dialog, and if you click ´ok', execute the program. URL links are opened in a system-dependent way. (On UNIX, Qt uses the $BROWSER environment variable.)

xdg-open indeed uses BROWSER in some places:

$ grep -F '$BROWSER' "$(command -v xdg-open)"
    for browser in $BROWSER; do
    if [ -n "$BROWSER" ]; then
    if [ x"$BROWSER" = x"" ]; then
            BROWSER=x-www-browser:firefox:iceweasel:seamonkey:mozilla:epiphany:konqueror:chromium:chromium-browser:google-chrome:$BROWSER
        BROWSER="$(echo "$BROWSER" | sed -e 's|:xdg-open||g' -e 's|xdg-open:||g')"

But it's a complex script, doing various things on different window and desktop managers. I use i3 and here value of $BROWSERE is not taken into account by xdg-open and it always exits in open_generic().

You can use this to find what will be picked by xdg-open for a given type:

$ XDG_UTILS_DEBUG_LEVEL=10 xdg-mime query default x-scheme-handler/https
Checking /home/ja/.config/mimeapps.list
userapp-Firefox-9Y4BR2.desktop

xpdf manpage could be updated to say that it uses xdg-open, it would clear all confusion.

6
  • That's one possibility, but in my case, I never set BROWSER before. My comments under the originally posted question shows that it somehow knows to look for firefox in ~/bin. I think it's just shelling out using $BROWSER to compose the command to be run. It relies on PATH to find the executable. Commented Jan 17 at 20:15
  • You may not have set $BROWSER yourself but it might be set by some initialization scripts delivered with the system. xpdf cannot use $BROWSER if it's not set of course, if that's the case it must use a different method for selecting a web browser such as xdg-open. Commented Jan 17 at 20:22
  • I have to admit I'm not familiar with the xdg. I know that BROWSER was not set at the Bash command line from where I issue xpdf. If xpdf is somehow using BROWSER=firefox, then it got this setting from somewhere else. In fact, from Bash, printenv | grep -i firefox comes up empty. So I could be wrong about xpdf using BROWSER to create a command before shelling out. Unless it got the BROWSER setting from somewhere outside of my control. I need to read up on xdg to understand the latter part of your answer. I am trying to find how xdg-open gets the preferred app to run. Commented Jan 17 at 20:54
  • Still have yet to figure out how xdg-open determines the preferred app to run, but if that's the answer, it seems to contradict the man page, which says that the environment variable determines the browser, at least for Unix (I'm not saying that the man page is exclusively right!). Regarding the passage URL handing is system-dependent, I don't think that the host Windows environment contains anything that would indicate firefox as the default browser. Commented Jan 18 at 19:30
  • I found what I think is clear evidence that xdg-open is not being used in my situation. I'll post the URL handling behaviour that I empirically found as a separate answer. I tried your suggestion XDG_UTILS_DEBUG_LEVEL=10 xdg-mime query default x-scheme-handler/https and got the response bash: xdg-mime: command not found, which corroborates with my suspicion that xdg-utils is not installed. I also tried your suggestion strace -f xpdf MyFile.pdf. As you said, there's lots of output, but it ends in Segmentation fault. Thanks. Commented Jan 18 at 19:57
0

This answer is an addendum to Arkadiusz Drabczyk's answer. While Cygwin might use xdg-open if it is installed, I am finding that it is not the explanation for my case. The only Cygwin package containing xdg-open is xdg-utils. The path is /usr/bin/xdg-open, which I don't have.

From trial and error, here is my black-box model of how the browser is chosen in the absence of xdg-open:

  • If BROWSER is not set, it looks for Firefox
  • If BROWSER is set, it looks for that
  • It looks for the browser in PATH
  • If ~/bin is in PATH, then the selected browser can be made findable by creating a symbolical link in ~/bin to the executable (e.g., firefox.exe, chrome.exe)
  • If the executable cannot be found, the URL handling fails
  • If the selected browser isn't Firefox and it can't initially be found, it will try launching Firefox
  • Whatever browser is found or not found upon the 1st click on a URL, xpdf will not try finding a different browser on the 2nd click, e.g., if the browser availability in PATH is changed in the interim

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.