]> Git Repo - binutils.git/blob - gprofng/src/Application.cc
Automatic date update in version.in
[binutils.git] / gprofng / src / Application.cc
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
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                 {
103                   char *nm = dbe_sprintf (NTXT ("%.*s/%s"), (int) (path - s - 1), path, _name);
104                   exe_name = realpath (nm, NULL);
105                   free (nm);
106                   if (exe_name)
107                     return exe_name;
108                 }
109               if (*s == 0)
110                 break;
111               path = s + 1;
112             }
113     }
114   return strdup (_name);
115 }
116
117 // Set the directory where all binaries are found
118 void
119 Application::set_run_dir (char *fdhome)
120 {
121   run_dir_with_spaces = NULL;
122   if (fdhome)
123     {
124       char *path = dbe_sprintf ("%s/bin", fdhome);
125       struct stat sbuf;
126       if (stat (path, &sbuf) != -1)
127         run_dir = path;
128       else
129         {
130           free (path);
131           run_dir = dbe_strdup (fdhome);
132         }
133     }
134   else
135     {
136       run_dir = realpath (prog_name, NULL);
137       if (run_dir == NULL)
138         {
139           fprintf (stderr, // I18N won't work here -- not catopen yet.
140                    GTXT ("Can't find location of %s\n"), prog_name);
141           run_dir = dbe_strdup (get_cur_dir ());
142         }
143       else
144         {
145           char *d = strrchr (run_dir, '/');
146           if (d)
147             *d = 0;
148           // Check if the installation path contains spaces
149           if (strchr (run_dir, ' ') != NULL)
150             {
151               // Create a symbolic link without spaces
152               const char *dir = NTXT ("/tmp/.gprofngLinks");
153               char *symbolic_link = dbe_create_symlink_to_path (run_dir, dir);
154               if (NULL != symbolic_link)
155                 {
156                   // Save old path to avoid memory leak
157                   run_dir_with_spaces = run_dir;
158                   // Use the path through symbolic link
159                   run_dir = symbolic_link;
160                 }
161             }
162         }
163     }
164 }
165
166 char *
167 Application::get_cur_dir ()
168 {
169   if (cur_dir == NULL)
170     {
171       char cwd[MAXPATHLEN];
172       if (getcwd (cwd, sizeof (cwd)) == NULL)
173         {
174           perror (prog_name);
175           exit (1);
176         }
177       cur_dir = dbe_strdup (canonical_path (cwd));
178     }
179   return cur_dir;
180 }
181
182 /**
183  * Get number of worker threads
184  * This is used to decide if it is ok to use worker threads for stat()
185  * and other actions that can hang for a long time
186  * @return number_of_worker_threads
187  */
188 int
189 Application::get_number_of_worker_threads ()
190 {
191   return number_of_worker_threads;
192 }
193
194 int
195 Application::check_args (int argc, char *argv[])
196 {
197   int opt;
198   // Parsing the command line
199   opterr = 0;
200   while ((opt = getopt (argc, argv, "V")) != EOF)
201     switch (opt)
202       {
203       case 'V':
204 // Ruud
205         Application::print_version_info ();
206 /*
207         printf (NTXT ("GNU %s version %s\n"), get_basename (prog_name), VERSION);
208 */
209         exit (0);
210       default:
211         usage ();
212       }
213   return optind;
214 }
215
216 Emsg *
217 Application::fetch_comments ()
218 {
219   if (commentq == NULL)
220     return NULL;
221   return commentq->fetch ();
222 }
223
224 void
225 Application::queue_comment (Emsg *m)
226 {
227   commentq->append (m);
228 }
229
230 void
231 Application::delete_comments ()
232 {
233   if (commentq != NULL)
234     {
235       delete commentq;
236       commentq = new Emsgqueue (NTXT ("app_commentq"));
237     }
238 }
239
240 int
241 Application::set_progress (int percentage, const char *proc_str)
242 {
243   if (progress_func != NULL)
244     return progress_func (percentage, proc_str);
245   return 0;
246 }
247
248 // Ruud
249 void
250 Application::print_version_info ()
251 {
252   printf ( GTXT (
253     "GNU %s binutils version %s\n"
254     "Copyright (C) 2021 Free Software Foundation, Inc.\n"
255     "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\n"
256     "This is free software: you are free to change and redistribute it.\n"
257     "There is NO WARRANTY, to the extent permitted by law.\n"),
258     get_basename (prog_name), VERSION);
259 }
This page took 0.037572 seconds and 4 git commands to generate.