]>
Commit | Line | Data |
---|---|---|
fd67aa11 | 1 | /* Copyright (C) 2021-2024 Free Software Foundation, Inc. |
bb368aad VM |
2 | Contributed by Oracle. |
3 | ||
4 | This file is part of GNU Binutils. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3, or (at your option) | |
9 | any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, 51 Franklin Street - Fifth Floor, Boston, | |
19 | MA 02110-1301, USA. */ | |
20 | ||
21 | #include "config.h" | |
22 | #include <stdlib.h> | |
23 | #include <strings.h> | |
24 | #include <sys/param.h> | |
25 | #include <sys/stat.h> | |
26 | #include <unistd.h> | |
27 | ||
28 | #include "Application.h" | |
29 | #include "Settings.h" | |
30 | #include "i18n.h" | |
31 | #include "util.h" | |
32 | ||
33 | Application::ProgressFunc Application::progress_func = NULL; | |
34 | Application *theApplication; | |
35 | ||
36 | Application::Application (int argc, char *argv[], char *fdhome) | |
37 | { | |
38 | theApplication = this; | |
39 | cur_dir = NULL; | |
40 | prog_version = dbe_strdup (VERSION); | |
41 | set_name (strchr (argv[0], '/') ? argv[0] : NULL); | |
42 | whoami = get_basename (get_name ()); | |
43 | ||
44 | // set up a queue for comments | |
45 | commentq = new Emsgqueue (NTXT ("app_commentq")); | |
46 | ||
47 | // Locate where the binaries are installed | |
48 | set_run_dir (fdhome); | |
49 | ||
50 | // Initialize I18N | |
51 | init_locale (run_dir); | |
52 | ||
53 | // Initialize licensing data | |
54 | lic_found = 0; | |
55 | lic_err = NULL; | |
56 | ||
57 | // Initialize worker threads | |
58 | number_of_worker_threads = 1; | |
59 | #if DEBUG | |
60 | char *use_worker_threads = getenv (NTXT ("SP_USE_WORKER_THREADS")); | |
61 | if ((NULL != use_worker_threads) && (0 == strcasecmp (use_worker_threads, NTXT ("no")))) | |
62 | { | |
63 | number_of_worker_threads = 0; | |
64 | } | |
65 | #endif /* DEBUG */ | |
66 | settings = new Settings (this); | |
67 | } | |
68 | ||
69 | Application::~Application () | |
70 | { | |
71 | delete commentq; | |
72 | delete settings; | |
73 | free (prog_version); | |
74 | free (cur_dir); | |
75 | free (prog_name); | |
76 | free (run_dir); | |
77 | } | |
78 | ||
79 | // Set the name of the application (for messages) | |
80 | void | |
81 | Application::set_name (const char *_name) | |
82 | { | |
83 | prog_name = get_realpath (_name); | |
84 | } | |
85 | ||
86 | char * | |
87 | Application::get_realpath (const char *_name) | |
88 | { | |
89 | if (_name == NULL) | |
90 | _name = "/proc/self/exe"; | |
91 | char *exe_name = realpath (_name, NULL); | |
92 | if (exe_name) | |
93 | return exe_name; | |
94 | if (strchr (_name, '/') == NULL) | |
95 | { | |
96 | char *path = getenv ("PATH"); | |
97 | if (path) | |
98 | for (char *s = path;; s++) | |
99 | if (*s == ':' || *s == 0) | |
100 | { | |
101 | if (path != s) | |
102 | { | |
e15197c8 VM |
103 | char *nm = dbe_sprintf (NTXT ("%.*s/%s"), (int) (s - path), |
104 | path, _name); | |
bb368aad VM |
105 | exe_name = realpath (nm, NULL); |
106 | free (nm); | |
107 | if (exe_name) | |
108 | return exe_name; | |
109 | } | |
110 | if (*s == 0) | |
111 | break; | |
112 | path = s + 1; | |
113 | } | |
114 | } | |
115 | return strdup (_name); | |
116 | } | |
117 | ||
118 | // Set the directory where all binaries are found | |
119 | void | |
120 | Application::set_run_dir (char *fdhome) | |
121 | { | |
122 | run_dir_with_spaces = NULL; | |
123 | if (fdhome) | |
124 | { | |
125 | char *path = dbe_sprintf ("%s/bin", fdhome); | |
126 | struct stat sbuf; | |
127 | if (stat (path, &sbuf) != -1) | |
128 | run_dir = path; | |
129 | else | |
130 | { | |
131 | free (path); | |
132 | run_dir = dbe_strdup (fdhome); | |
133 | } | |
134 | } | |
135 | else | |
136 | { | |
137 | run_dir = realpath (prog_name, NULL); | |
138 | if (run_dir == NULL) | |
139 | { | |
140 | fprintf (stderr, // I18N won't work here -- not catopen yet. | |
141 | GTXT ("Can't find location of %s\n"), prog_name); | |
142 | run_dir = dbe_strdup (get_cur_dir ()); | |
143 | } | |
144 | else | |
145 | { | |
146 | char *d = strrchr (run_dir, '/'); | |
147 | if (d) | |
148 | *d = 0; | |
149 | // Check if the installation path contains spaces | |
150 | if (strchr (run_dir, ' ') != NULL) | |
151 | { | |
152 | // Create a symbolic link without spaces | |
153 | const char *dir = NTXT ("/tmp/.gprofngLinks"); | |
154 | char *symbolic_link = dbe_create_symlink_to_path (run_dir, dir); | |
155 | if (NULL != symbolic_link) | |
156 | { | |
157 | // Save old path to avoid memory leak | |
158 | run_dir_with_spaces = run_dir; | |
159 | // Use the path through symbolic link | |
160 | run_dir = symbolic_link; | |
161 | } | |
162 | } | |
163 | } | |
164 | } | |
165 | } | |
166 | ||
167 | char * | |
168 | Application::get_cur_dir () | |
169 | { | |
170 | if (cur_dir == NULL) | |
171 | { | |
172 | char cwd[MAXPATHLEN]; | |
173 | if (getcwd (cwd, sizeof (cwd)) == NULL) | |
174 | { | |
175 | perror (prog_name); | |
176 | exit (1); | |
177 | } | |
178 | cur_dir = dbe_strdup (canonical_path (cwd)); | |
179 | } | |
180 | return cur_dir; | |
181 | } | |
182 | ||
183 | /** | |
184 | * Get number of worker threads | |
185 | * This is used to decide if it is ok to use worker threads for stat() | |
186 | * and other actions that can hang for a long time | |
187 | * @return number_of_worker_threads | |
188 | */ | |
189 | int | |
190 | Application::get_number_of_worker_threads () | |
191 | { | |
192 | return number_of_worker_threads; | |
193 | } | |
194 | ||
195 | int | |
196 | Application::check_args (int argc, char *argv[]) | |
197 | { | |
198 | int opt; | |
199 | // Parsing the command line | |
200 | opterr = 0; | |
201 | while ((opt = getopt (argc, argv, "V")) != EOF) | |
202 | switch (opt) | |
203 | { | |
204 | case 'V': | |
205 | // Ruud | |
206 | Application::print_version_info (); | |
207 | /* | |
208 | printf (NTXT ("GNU %s version %s\n"), get_basename (prog_name), VERSION); | |
209 | */ | |
210 | exit (0); | |
211 | default: | |
212 | usage (); | |
213 | } | |
214 | return optind; | |
215 | } | |
216 | ||
217 | Emsg * | |
218 | Application::fetch_comments () | |
219 | { | |
220 | if (commentq == NULL) | |
221 | return NULL; | |
222 | return commentq->fetch (); | |
223 | } | |
224 | ||
225 | void | |
226 | Application::queue_comment (Emsg *m) | |
227 | { | |
228 | commentq->append (m); | |
229 | } | |
230 | ||
231 | void | |
232 | Application::delete_comments () | |
233 | { | |
234 | if (commentq != NULL) | |
235 | { | |
236 | delete commentq; | |
237 | commentq = new Emsgqueue (NTXT ("app_commentq")); | |
238 | } | |
239 | } | |
240 | ||
241 | int | |
242 | Application::set_progress (int percentage, const char *proc_str) | |
243 | { | |
244 | if (progress_func != NULL) | |
245 | return progress_func (percentage, proc_str); | |
246 | return 0; | |
247 | } | |
248 | ||
249 | // Ruud | |
250 | void | |
251 | Application::print_version_info () | |
252 | { | |
253 | printf ( GTXT ( | |
254 | "GNU %s binutils version %s\n" | |
fd67aa11 | 255 | "Copyright (C) 2024 Free Software Foundation, Inc.\n" |
bb368aad VM |
256 | "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\n" |
257 | "This is free software: you are free to change and redistribute it.\n" | |
258 | "There is NO WARRANTY, to the extent permitted by law.\n"), | |
259 | get_basename (prog_name), VERSION); | |
260 | } |