1 /**
2  * Open an online manual page.
3  *
4  * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
5  * Authors:   Walter Bright, https://www.digitalmars.com
6  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/man.d, root/_man.d)
8  * Documentation:  https://dlang.org/phobos/dmd_root_man.html
9  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/man.d
10  */
11 
12 module dmd.root.man;
13 
14 import core.stdc.stdio;
15 import core.stdc.stdlib;
16 import core.stdc.string;
17 import core.sys.posix.unistd;
18 
19 version (Windows)
20 {
21     import core.sys.windows.shellapi;
22     import core.sys.windows.winuser;
23 
24     extern (C++) void browse(const(char)* url) nothrow @nogc
25     in
26     {
27         assert(strncmp(url, "http://", 7) == 0 || strncmp(url, "https://", 8) == 0);
28     }
29     do
30     {
31         ShellExecuteA(null, "open", url, null, null, SW_SHOWNORMAL);
32     }
33 }
34 else version (OSX)
35 {
36     extern (C++) void browse(const(char)* url) nothrow @nogc
37     in
38     {
39         assert(strncmp(url, "http://", 7) == 0 || strncmp(url, "https://", 8) == 0);
40     }
41     do
42     {
43         pid_t childpid;
44         const(char)*[5] args;
45         char* browser = getenv("BROWSER");
46         if (browser)
47         {
48             browser = strdup(browser);
49             args[0] = browser;
50             args[1] = url;
51             args[2] = null;
52         }
53         else
54         {
55             args[0] = "open";
56             args[1] = url;
57             args[2] = null;
58         }
59         childpid = fork();
60         if (childpid == 0)
61         {
62             execvp(args[0], cast(char**)args);
63             perror(args[0]); // failed to execute
64             return;
65         }
66     }
67 }
68 else version (Posix)
69 {
70     extern (C++) void browse(const(char)* url) nothrow @nogc
71     in
72     {
73         assert(strncmp(url, "http://", 7) == 0 || strncmp(url, "https://", 8) == 0);
74     }
75     do
76     {
77         pid_t childpid;
78         const(char)*[3] args;
79         const(char)* browser = getenv("BROWSER");
80         if (browser)
81             browser = strdup(browser);
82         else
83             browser = "xdg-open";
84         args[0] = browser;
85         args[1] = url;
86         args[2] = null;
87         childpid = fork();
88         if (childpid == 0)
89         {
90             execvp(args[0], cast(char**)args);
91             perror(args[0]); // failed to execute
92             return;
93         }
94     }
95 }