1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker // Define _GNU_SOURCE to ensure that <errno.h> defines
8*6777b538SAndroid Build Coastguard Worker // program_invocation_short_name. Keep this at the top of the file since some
9*6777b538SAndroid Build Coastguard Worker // system headers might include <errno.h> and the header could be skipped on
10*6777b538SAndroid Build Coastguard Worker // subsequent includes.
11*6777b538SAndroid Build Coastguard Worker #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && !defined(_GNU_SOURCE)
12*6777b538SAndroid Build Coastguard Worker #define _GNU_SOURCE
13*6777b538SAndroid Build Coastguard Worker #endif
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker #include "base/process/set_process_title.h"
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_SOLARIS)
20*6777b538SAndroid Build Coastguard Worker #include <limits.h>
21*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
22*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Worker #include <string>
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
27*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_SOLARIS)
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
30*6777b538SAndroid Build Coastguard Worker #include <errno.h> // Get program_invocation_short_name declaration.
31*6777b538SAndroid Build Coastguard Worker #include <sys/prctl.h>
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
35*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
36*6777b538SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
37*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
38*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
39*6777b538SAndroid Build Coastguard Worker // Linux/glibc doesn't natively have setproctitle().
40*6777b538SAndroid Build Coastguard Worker #include "base/process/set_process_title_linux.h"
41*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker namespace base {
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker // TODO(jrg): Find out if setproctitle or equivalent is available on Android.
46*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_SOLARIS) && \
47*6777b538SAndroid Build Coastguard Worker !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_NACL)
48*6777b538SAndroid Build Coastguard Worker
SetProcessTitleFromCommandLine(const char ** main_argv)49*6777b538SAndroid Build Coastguard Worker void SetProcessTitleFromCommandLine(const char** main_argv) {
50*6777b538SAndroid Build Coastguard Worker // Build a single string which consists of all the arguments separated
51*6777b538SAndroid Build Coastguard Worker // by spaces. We can't actually keep them separate due to the way the
52*6777b538SAndroid Build Coastguard Worker // setproctitle() function works.
53*6777b538SAndroid Build Coastguard Worker std::string title;
54*6777b538SAndroid Build Coastguard Worker bool have_argv0 = false;
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
57*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(base::PlatformThread::CurrentId(), getpid());
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker if (main_argv)
60*6777b538SAndroid Build Coastguard Worker setproctitle_init(main_argv);
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker // In Linux we sometimes exec ourselves from /proc/self/exe, but this makes us
63*6777b538SAndroid Build Coastguard Worker // show up as "exe" in process listings. Read the symlink /proc/self/exe and
64*6777b538SAndroid Build Coastguard Worker // use the path it points at for our process title. Note that this is only for
65*6777b538SAndroid Build Coastguard Worker // display purposes and has no TOCTTOU security implications.
66*6777b538SAndroid Build Coastguard Worker base::FilePath target;
67*6777b538SAndroid Build Coastguard Worker base::FilePath self_exe(base::kProcSelfExe);
68*6777b538SAndroid Build Coastguard Worker if (base::ReadSymbolicLink(self_exe, &target)) {
69*6777b538SAndroid Build Coastguard Worker have_argv0 = true;
70*6777b538SAndroid Build Coastguard Worker title = target.value();
71*6777b538SAndroid Build Coastguard Worker // If the binary has since been deleted, Linux appends " (deleted)" to the
72*6777b538SAndroid Build Coastguard Worker // symlink target. Remove it, since this is not really part of our name.
73*6777b538SAndroid Build Coastguard Worker const std::string kDeletedSuffix = " (deleted)";
74*6777b538SAndroid Build Coastguard Worker if (base::EndsWith(title, kDeletedSuffix, base::CompareCase::SENSITIVE))
75*6777b538SAndroid Build Coastguard Worker title.resize(title.size() - kDeletedSuffix.size());
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker base::FilePath::StringType base_name =
78*6777b538SAndroid Build Coastguard Worker base::FilePath(title).BaseName().value();
79*6777b538SAndroid Build Coastguard Worker // PR_SET_NAME is available in Linux 2.6.9 and newer.
80*6777b538SAndroid Build Coastguard Worker // When available at run time, this sets the short process name that shows
81*6777b538SAndroid Build Coastguard Worker // when the full command line is not being displayed in most process
82*6777b538SAndroid Build Coastguard Worker // listings.
83*6777b538SAndroid Build Coastguard Worker prctl(PR_SET_NAME, base_name.c_str());
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard Worker // This prevents program_invocation_short_name from being broken by
86*6777b538SAndroid Build Coastguard Worker // setproctitle().
87*6777b538SAndroid Build Coastguard Worker static base::NoDestructor<base::FilePath::StringType> base_name_storage;
88*6777b538SAndroid Build Coastguard Worker *base_name_storage = std::move(base_name);
89*6777b538SAndroid Build Coastguard Worker program_invocation_short_name = &(*base_name_storage)[0];
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
92*6777b538SAndroid Build Coastguard Worker
93*6777b538SAndroid Build Coastguard Worker const base::CommandLine* command_line =
94*6777b538SAndroid Build Coastguard Worker base::CommandLine::ForCurrentProcess();
95*6777b538SAndroid Build Coastguard Worker for (size_t i = 1; i < command_line->argv().size(); ++i) {
96*6777b538SAndroid Build Coastguard Worker if (!title.empty())
97*6777b538SAndroid Build Coastguard Worker title += " ";
98*6777b538SAndroid Build Coastguard Worker title += command_line->argv()[i];
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker // Disable prepending argv[0] with '-' if we prepended it ourselves above.
101*6777b538SAndroid Build Coastguard Worker setproctitle(have_argv0 ? "-%s" : "%s", title.c_str());
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker
104*6777b538SAndroid Build Coastguard Worker #else
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker // All other systems (basically Windows & Mac) have no need or way to implement
107*6777b538SAndroid Build Coastguard Worker // this function.
108*6777b538SAndroid Build Coastguard Worker void SetProcessTitleFromCommandLine(const char** /* main_argv */) {}
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker #endif
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker } // namespace base
113