/src/brpc/src/butil/process_util.cc
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | // Process-related Info |
19 | | |
20 | | // Date: Wed Apr 11 14:35:56 CST 2018 |
21 | | |
22 | | #include <fcntl.h> // open |
23 | | #include <stdio.h> // snprintf |
24 | | #include <sys/types.h> |
25 | | #include <sys/uio.h> |
26 | | #include <unistd.h> // read, gitpid |
27 | | #include <sstream> // std::ostringstream |
28 | | #include "butil/fd_guard.h" // butil::fd_guard |
29 | | #include "butil/logging.h" |
30 | | #include "butil/popen.h" // read_command_output |
31 | | #include "butil/process_util.h" |
32 | | |
33 | | #if defined(OS_MACOSX) |
34 | | #include <libproc.h> // proc_pidpath |
35 | | #endif |
36 | | namespace butil { |
37 | | |
38 | 0 | ssize_t ReadCommandLine(char* buf, size_t len, bool with_args) { |
39 | 0 | #if defined(OS_LINUX) |
40 | 0 | butil::fd_guard fd(open("/proc/self/cmdline", O_RDONLY)); |
41 | 0 | if (fd < 0) { |
42 | 0 | LOG(ERROR) << "Fail to open /proc/self/cmdline"; |
43 | 0 | return -1; |
44 | 0 | } |
45 | 0 | ssize_t nr = read(fd, buf, len); |
46 | 0 | if (nr <= 0) { |
47 | 0 | LOG(ERROR) << "Fail to read /proc/self/cmdline"; |
48 | 0 | return -1; |
49 | 0 | } |
50 | | #elif defined(OS_MACOSX) |
51 | | static pid_t pid = getpid(); |
52 | | std::ostringstream oss; |
53 | | char cmdbuf[32]; |
54 | | snprintf(cmdbuf, sizeof(cmdbuf), "ps -p %ld -o command=", (long)pid); |
55 | | if (butil::read_command_output(oss, cmdbuf) != 0) { |
56 | | LOG(ERROR) << "Fail to read cmdline"; |
57 | | return -1; |
58 | | } |
59 | | const std::string& result = oss.str(); |
60 | | ssize_t nr = std::min(result.size(), len); |
61 | | memcpy(buf, result.data(), nr); |
62 | | #else |
63 | | #error Not Implemented |
64 | | #endif |
65 | | |
66 | 0 | if (with_args) { |
67 | 0 | if ((size_t)nr == len) { |
68 | 0 | return len; |
69 | 0 | } |
70 | 0 | for (ssize_t i = 0; i < nr; ++i) { |
71 | 0 | if (buf[i] == '\0') { |
72 | 0 | buf[i] = '\n'; |
73 | 0 | } |
74 | 0 | } |
75 | 0 | return nr; |
76 | 0 | } else { |
77 | 0 | for (ssize_t i = 0; i < nr; ++i) { |
78 | | // The command in macos is separated with space and ended with '\n' |
79 | 0 | if (buf[i] == '\0' || buf[i] == '\n' || buf[i] == ' ') { |
80 | 0 | return i; |
81 | 0 | } |
82 | 0 | } |
83 | 0 | if ((size_t)nr == len) { |
84 | 0 | LOG(ERROR) << "buf is not big enough"; |
85 | 0 | return -1; |
86 | 0 | } |
87 | 0 | return nr; |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | 0 | ssize_t GetProcessAbsolutePath(char *buf, size_t len) { |
92 | 0 | #if defined(OS_LINUX) |
93 | 0 | memset(buf, 0, len); |
94 | 0 | ssize_t nr = readlink("/proc/self/exe", buf, len); |
95 | 0 | return nr; |
96 | | #elif defined(OS_MACOSX) |
97 | | memset(buf, 0, len); |
98 | | int ret = proc_pidpath(getpid(), buf, len); |
99 | | return ret; |
100 | | #endif |
101 | 0 | } |
102 | | |
103 | | } // namespace butil |