Commit | Line | Data |
---|---|---|
13da1c97 | 1 | /* Linux-specific PROCFS manipulation routines. |
32d0add0 | 2 | Copyright (C) 2009-2015 Free Software Foundation, Inc. |
13da1c97 LM |
3 | |
4 | This file is part of GDB. | |
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 of the License, or | |
9 | (at your option) 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, see <http://www.gnu.org/licenses/>. */ | |
18 | ||
727605ca | 19 | #include "common-defs.h" |
13da1c97 | 20 | #include "linux-procfs.h" |
614c279d | 21 | #include "filestuff.h" |
13da1c97 LM |
22 | |
23 | /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not | |
24 | found. */ | |
25 | ||
87b0bb13 JK |
26 | static int |
27 | linux_proc_get_int (pid_t lwpid, const char *field) | |
13da1c97 | 28 | { |
87b0bb13 | 29 | size_t field_len = strlen (field); |
13da1c97 LM |
30 | FILE *status_file; |
31 | char buf[100]; | |
87b0bb13 | 32 | int retval = -1; |
13da1c97 LM |
33 | |
34 | snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid); | |
614c279d | 35 | status_file = gdb_fopen_cloexec (buf, "r"); |
87b0bb13 | 36 | if (status_file == NULL) |
13da1c97 | 37 | { |
87b0bb13 JK |
38 | warning (_("unable to open /proc file '%s'"), buf); |
39 | return -1; | |
13da1c97 LM |
40 | } |
41 | ||
87b0bb13 JK |
42 | while (fgets (buf, sizeof (buf), status_file)) |
43 | if (strncmp (buf, field, field_len) == 0 && buf[field_len] == ':') | |
44 | { | |
45 | retval = strtol (&buf[field_len + 1], NULL, 10); | |
46 | break; | |
47 | } | |
48 | ||
49 | fclose (status_file); | |
50 | return retval; | |
13da1c97 | 51 | } |
644cebc9 | 52 | |
87b0bb13 JK |
53 | /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not |
54 | found. */ | |
644cebc9 PA |
55 | |
56 | int | |
87b0bb13 | 57 | linux_proc_get_tgid (pid_t lwpid) |
644cebc9 | 58 | { |
87b0bb13 JK |
59 | return linux_proc_get_int (lwpid, "Tgid"); |
60 | } | |
644cebc9 | 61 | |
87b0bb13 JK |
62 | /* See linux-procfs.h. */ |
63 | ||
64 | pid_t | |
65 | linux_proc_get_tracerpid (pid_t lwpid) | |
66 | { | |
67 | return linux_proc_get_int (lwpid, "TracerPid"); | |
644cebc9 | 68 | } |
5f572dec | 69 | |
87b0bb13 | 70 | /* Return non-zero if 'State' of /proc/PID/status contains STATE. */ |
5f572dec | 71 | |
87b0bb13 JK |
72 | static int |
73 | linux_proc_pid_has_state (pid_t pid, const char *state) | |
5f572dec JK |
74 | { |
75 | char buffer[100]; | |
76 | FILE *procfile; | |
77 | int retval; | |
78 | int have_state; | |
79 | ||
80 | xsnprintf (buffer, sizeof (buffer), "/proc/%d/status", (int) pid); | |
614c279d | 81 | procfile = gdb_fopen_cloexec (buffer, "r"); |
5f572dec JK |
82 | if (procfile == NULL) |
83 | { | |
84 | warning (_("unable to open /proc file '%s'"), buffer); | |
85 | return 0; | |
86 | } | |
87 | ||
88 | have_state = 0; | |
89 | while (fgets (buffer, sizeof (buffer), procfile) != NULL) | |
90 | if (strncmp (buffer, "State:", 6) == 0) | |
91 | { | |
92 | have_state = 1; | |
93 | break; | |
94 | } | |
87b0bb13 | 95 | retval = (have_state && strstr (buffer, state) != NULL); |
5f572dec JK |
96 | fclose (procfile); |
97 | return retval; | |
98 | } | |
87b0bb13 JK |
99 | |
100 | /* Detect `T (stopped)' in `/proc/PID/status'. | |
101 | Other states including `T (tracing stop)' are reported as false. */ | |
102 | ||
103 | int | |
104 | linux_proc_pid_is_stopped (pid_t pid) | |
105 | { | |
106 | return linux_proc_pid_has_state (pid, "T (stopped)"); | |
107 | } | |
108 | ||
109 | /* See linux-procfs.h declaration. */ | |
110 | ||
111 | int | |
112 | linux_proc_pid_is_zombie (pid_t pid) | |
113 | { | |
114 | return linux_proc_pid_has_state (pid, "Z (zombie)"); | |
115 | } | |
015de688 DC |
116 | |
117 | /* See linux-procfs.h declaration. */ | |
118 | ||
119 | char * | |
120 | linux_proc_pid_get_ns (pid_t pid, const char *ns) | |
121 | { | |
122 | char buf[100]; | |
123 | char nsval[64]; | |
124 | int ret; | |
125 | xsnprintf (buf, sizeof (buf), "/proc/%d/ns/%s", (int) pid, ns); | |
126 | ret = readlink (buf, nsval, sizeof (nsval)); | |
127 | if (0 < ret && ret < sizeof (nsval)) | |
128 | { | |
129 | nsval[ret] = '\0'; | |
130 | return xstrdup (nsval); | |
131 | } | |
132 | ||
133 | return NULL; | |
134 | } |