GDB (xrefs)
linux-osdata.c
Go to the documentation of this file.
1 /* Linux-specific functions to retrieve OS data.
2 
3  Copyright (C) 2009-2015 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "common-defs.h"
21 #include "linux-osdata.h"
22 
23 #include <sys/types.h>
24 #include <sys/sysinfo.h>
25 #include <ctype.h>
26 #include <utmp.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <pwd.h>
30 #include <grp.h>
31 #include <netdb.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 
35 #include "xml-utils.h"
36 #include "buffer.h"
37 #include <dirent.h>
38 #include <sys/stat.h>
39 #include "filestuff.h"
40 
41 #define NAMELEN(dirent) strlen ((dirent)->d_name)
42 
43 /* Define PID_T to be a fixed size that is at least as large as pid_t,
44  so that reading pid values embedded in /proc works
45  consistently. */
46 
47 typedef long long PID_T;
48 
49 /* Define TIME_T to be at least as large as time_t, so that reading
50  time values embedded in /proc works consistently. */
51 
52 typedef long long TIME_T;
53 
54 #define MAX_PID_T_STRLEN (sizeof ("-9223372036854775808") - 1)
55 
56 /* Returns the CPU core that thread PTID is currently running on. */
57 
58 /* Compute and return the processor core of a given thread. */
59 
60 int
62 {
63  char filename[sizeof ("/proc//task//stat") + 2 * MAX_PID_T_STRLEN];
64  FILE *f;
65  char *content = NULL;
66  char *p;
67  char *ts = 0;
68  int content_read = 0;
69  int i;
70  int core;
71 
72  sprintf (filename, "/proc/%lld/task/%lld/stat",
73  (PID_T) ptid_get_pid (ptid), (PID_T) ptid_get_lwp (ptid));
74  f = gdb_fopen_cloexec (filename, "r");
75  if (!f)
76  return -1;
77 
78  for (;;)
79  {
80  int n;
81  content = xrealloc (content, content_read + 1024);
82  n = fread (content + content_read, 1, 1024, f);
83  content_read += n;
84  if (n < 1024)
85  {
86  content[content_read] = '\0';
87  break;
88  }
89  }
90 
91  /* ps command also relies on no trailing fields ever contain ')'. */
92  p = strrchr (content, ')');
93  if (p != NULL)
94  p++;
95 
96  /* If the first field after program name has index 0, then core number is
97  the field with index 36. There's no constant for that anywhere. */
98  if (p != NULL)
99  p = strtok_r (p, " ", &ts);
100  for (i = 0; p != NULL && i != 36; ++i)
101  p = strtok_r (NULL, " ", &ts);
102 
103  if (p == NULL || sscanf (p, "%d", &core) == 0)
104  core = -1;
105 
106  xfree (content);
107  fclose (f);
108 
109  return core;
110 }
111 
112 /* Finds the command-line of process PID and copies it into COMMAND.
113  At most MAXLEN characters are copied. If the command-line cannot
114  be found, PID is copied into command in text-form. */
115 
116 static void
117 command_from_pid (char *command, int maxlen, PID_T pid)
118 {
119  char *stat_path = xstrprintf ("/proc/%lld/stat", pid);
120  FILE *fp = gdb_fopen_cloexec (stat_path, "r");
121 
122  command[0] = '\0';
123 
124  if (fp)
125  {
126  /* sizeof (cmd) should be greater or equal to TASK_COMM_LEN (in
127  include/linux/sched.h in the Linux kernel sources) plus two
128  (for the brackets). */
129  char cmd[18];
130  PID_T stat_pid;
131  int items_read = fscanf (fp, "%lld %17s", &stat_pid, cmd);
132 
133  if (items_read == 2 && pid == stat_pid)
134  {
135  cmd[strlen (cmd) - 1] = '\0'; /* Remove trailing parenthesis. */
136  strncpy (command, cmd + 1, maxlen); /* Ignore leading parenthesis. */
137  }
138 
139  fclose (fp);
140  }
141  else
142  {
143  /* Return the PID if a /proc entry for the process cannot be found. */
144  snprintf (command, maxlen, "%lld", pid);
145  }
146 
147  command[maxlen - 1] = '\0'; /* Ensure string is null-terminated. */
148 
149  xfree (stat_path);
150 }
151 
152 /* Returns the command-line of the process with the given PID. The
153  returned string needs to be freed using xfree after use. */
154 
155 static char *
157 {
158  char *pathname = xstrprintf ("/proc/%lld/cmdline", pid);
159  char *commandline = NULL;
160  FILE *f = gdb_fopen_cloexec (pathname, "r");
161 
162  if (f)
163  {
164  size_t len = 0;
165 
166  while (!feof (f))
167  {
168  char buf[1024];
169  size_t read_bytes = fread (buf, 1, sizeof (buf), f);
170 
171  if (read_bytes)
172  {
173  commandline = (char *) xrealloc (commandline, len + read_bytes + 1);
174  memcpy (commandline + len, buf, read_bytes);
175  len += read_bytes;
176  }
177  }
178 
179  fclose (f);
180 
181  if (commandline)
182  {
183  size_t i;
184 
185  /* Replace null characters with spaces. */
186  for (i = 0; i < len; ++i)
187  if (commandline[i] == '\0')
188  commandline[i] = ' ';
189 
190  commandline[len] = '\0';
191  }
192  else
193  {
194  /* Return the command in square brackets if the command-line
195  is empty. */
196  commandline = (char *) xmalloc (32);
197  commandline[0] = '[';
198  command_from_pid (commandline + 1, 31, pid);
199 
200  len = strlen (commandline);
201  if (len < 31)
202  strcat (commandline, "]");
203  }
204  }
205 
206  xfree (pathname);
207 
208  return commandline;
209 }
210 
211 /* Finds the user name for the user UID and copies it into USER. At
212  most MAXLEN characters are copied. */
213 
214 static void
215 user_from_uid (char *user, int maxlen, uid_t uid)
216 {
217  struct passwd *pwentry = getpwuid (uid);
218 
219  if (pwentry)
220  {
221  strncpy (user, pwentry->pw_name, maxlen);
222  /* Ensure that the user name is null-terminated. */
223  user[maxlen - 1] = '\0';
224  }
225  else
226  user[0] = '\0';
227 }
228 
229 /* Finds the owner of process PID and returns the user id in OWNER.
230  Returns 0 if the owner was found, -1 otherwise. */
231 
232 static int
233 get_process_owner (uid_t *owner, PID_T pid)
234 {
235  struct stat statbuf;
236  char procentry[sizeof ("/proc/") + MAX_PID_T_STRLEN];
237 
238  sprintf (procentry, "/proc/%lld", pid);
239 
240  if (stat (procentry, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
241  {
242  *owner = statbuf.st_uid;
243  return 0;
244  }
245  else
246  return -1;
247 }
248 
249 /* Find the CPU cores used by process PID and return them in CORES.
250  CORES points to an array of NUM_CORES elements. */
251 
252 static int
253 get_cores_used_by_process (PID_T pid, int *cores, const int num_cores)
254 {
255  char taskdir[sizeof ("/proc/") + MAX_PID_T_STRLEN + sizeof ("/task") - 1];
256  DIR *dir;
257  struct dirent *dp;
258  int task_count = 0;
259 
260  sprintf (taskdir, "/proc/%lld/task", pid);
261  dir = opendir (taskdir);
262  if (dir)
263  {
264  while ((dp = readdir (dir)) != NULL)
265  {
266  PID_T tid;
267  int core;
268 
269  if (!isdigit (dp->d_name[0])
270  || NAMELEN (dp) > MAX_PID_T_STRLEN)
271  continue;
272 
273  sscanf (dp->d_name, "%lld", &tid);
274  core = linux_common_core_of_thread (ptid_build ((pid_t) pid,
275  (pid_t) tid, 0));
276 
277  if (core >= 0 && core < num_cores)
278  {
279  ++cores[core];
280  ++task_count;
281  }
282  }
283 
284  closedir (dir);
285  }
286 
287  return task_count;
288 }
289 
290 static LONGEST
293 {
294  /* We make the process list snapshot when the object starts to be read. */
295  static const char *buf;
296  static LONGEST len_avail = -1;
297  static struct buffer buffer;
298 
299  if (offset == 0)
300  {
301  DIR *dirp;
302 
303  if (len_avail != -1 && len_avail != 0)
304  buffer_free (&buffer);
305  len_avail = 0;
306  buf = NULL;
307  buffer_init (&buffer);
308  buffer_grow_str (&buffer, "<osdata type=\"processes\">\n");
309 
310  dirp = opendir ("/proc");
311  if (dirp)
312  {
313  const int num_cores = sysconf (_SC_NPROCESSORS_ONLN);
314  struct dirent *dp;
315 
316  while ((dp = readdir (dirp)) != NULL)
317  {
318  PID_T pid;
319  uid_t owner;
320  char user[UT_NAMESIZE];
321  char *command_line;
322  int *cores;
323  int task_count;
324  char *cores_str;
325  int i;
326 
327  if (!isdigit (dp->d_name[0])
328  || NAMELEN (dp) > MAX_PID_T_STRLEN)
329  continue;
330 
331  sscanf (dp->d_name, "%lld", &pid);
332  command_line = commandline_from_pid (pid);
333 
334  if (get_process_owner (&owner, pid) == 0)
335  user_from_uid (user, sizeof (user), owner);
336  else
337  strcpy (user, "?");
338 
339  /* Find CPU cores used by the process. */
340  cores = (int *) xcalloc (num_cores, sizeof (int));
341  task_count = get_cores_used_by_process (pid, cores, num_cores);
342  cores_str = (char *) xcalloc (task_count, sizeof ("4294967295") + 1);
343 
344  for (i = 0; i < num_cores && task_count > 0; ++i)
345  if (cores[i])
346  {
347  char core_str[sizeof ("4294967295")];
348 
349  sprintf (core_str, "%d", i);
350  strcat (cores_str, core_str);
351 
352  task_count -= cores[i];
353  if (task_count > 0)
354  strcat (cores_str, ",");
355  }
356 
357  xfree (cores);
358 
360  &buffer,
361  "<item>"
362  "<column name=\"pid\">%lld</column>"
363  "<column name=\"user\">%s</column>"
364  "<column name=\"command\">%s</column>"
365  "<column name=\"cores\">%s</column>"
366  "</item>",
367  pid,
368  user,
369  command_line ? command_line : "",
370  cores_str);
371 
372  xfree (command_line);
373  xfree (cores_str);
374  }
375 
376  closedir (dirp);
377  }
378 
379  buffer_grow_str0 (&buffer, "</osdata>\n");
380  buf = buffer_finish (&buffer);
381  len_avail = strlen (buf);
382  }
383 
384  if (offset >= len_avail)
385  {
386  /* Done. Get rid of the buffer. */
387  buffer_free (&buffer);
388  buf = NULL;
389  len_avail = 0;
390  return 0;
391  }
392 
393  if (len > len_avail - offset)
394  len = len_avail - offset;
395  memcpy (readbuf, buf + offset, len);
396 
397  return len;
398 }
399 
400 /* Auxiliary function used by qsort to sort processes by process
401  group. Compares two processes with ids PROCESS1 and PROCESS2.
402  PROCESS1 comes before PROCESS2 if it has a lower process group id.
403  If they belong to the same process group, PROCESS1 comes before
404  PROCESS2 if it has a lower process id or is the process group
405  leader. */
406 
407 static int
408 compare_processes (const void *process1, const void *process2)
409 {
410  PID_T pid1 = *((PID_T *) process1);
411  PID_T pid2 = *((PID_T *) process2);
412  PID_T pgid1 = *((PID_T *) process1 + 1);
413  PID_T pgid2 = *((PID_T *) process2 + 1);
414 
415  /* Sort by PGID. */
416  if (pgid1 < pgid2)
417  return -1;
418  else if (pgid1 > pgid2)
419  return 1;
420  else
421  {
422  /* Process group leaders always come first, else sort by PID. */
423  if (pid1 == pgid1)
424  return -1;
425  else if (pid2 == pgid2)
426  return 1;
427  else if (pid1 < pid2)
428  return -1;
429  else if (pid1 > pid2)
430  return 1;
431  else
432  return 0;
433  }
434 }
435 
436 /* Collect all process groups from /proc. */
437 
438 static LONGEST
441 {
442  /* We make the process list snapshot when the object starts to be read. */
443  static const char *buf;
444  static LONGEST len_avail = -1;
445  static struct buffer buffer;
446 
447  if (offset == 0)
448  {
449  DIR *dirp;
450 
451  if (len_avail != -1 && len_avail != 0)
452  buffer_free (&buffer);
453  len_avail = 0;
454  buf = NULL;
455  buffer_init (&buffer);
456  buffer_grow_str (&buffer, "<osdata type=\"process groups\">\n");
457 
458  dirp = opendir ("/proc");
459  if (dirp)
460  {
461  struct dirent *dp;
462  const size_t list_block_size = 512;
463  PID_T *process_list = (PID_T *) xmalloc (list_block_size * 2 * sizeof (PID_T));
464  size_t process_count = 0;
465  size_t i;
466 
467  /* Build list consisting of PIDs followed by their
468  associated PGID. */
469  while ((dp = readdir (dirp)) != NULL)
470  {
471  PID_T pid, pgid;
472 
473  if (!isdigit (dp->d_name[0])
474  || NAMELEN (dp) > MAX_PID_T_STRLEN)
475  continue;
476 
477  sscanf (dp->d_name, "%lld", &pid);
478  pgid = getpgid (pid);
479 
480  if (pgid > 0)
481  {
482  process_list[2 * process_count] = pid;
483  process_list[2 * process_count + 1] = pgid;
484  ++process_count;
485 
486  /* Increase the size of the list if necessary. */
487  if (process_count % list_block_size == 0)
488  process_list = (PID_T *) xrealloc (
489  process_list,
490  (process_count + list_block_size)
491  * 2 * sizeof (PID_T));
492  }
493  }
494 
495  closedir (dirp);
496 
497  /* Sort the process list. */
498  qsort (process_list, process_count, 2 * sizeof (PID_T),
500 
501  for (i = 0; i < process_count; ++i)
502  {
503  PID_T pid = process_list[2 * i];
504  PID_T pgid = process_list[2 * i + 1];
505  char leader_command[32];
506  char *command_line;
507 
508  command_from_pid (leader_command, sizeof (leader_command), pgid);
509  command_line = commandline_from_pid (pid);
510 
512  &buffer,
513  "<item>"
514  "<column name=\"pgid\">%lld</column>"
515  "<column name=\"leader command\">%s</column>"
516  "<column name=\"pid\">%lld</column>"
517  "<column name=\"command line\">%s</column>"
518  "</item>",
519  pgid,
520  leader_command,
521  pid,
522  command_line ? command_line : "");
523 
524  xfree (command_line);
525  }
526 
527  xfree (process_list);
528  }
529 
530  buffer_grow_str0 (&buffer, "</osdata>\n");
531  buf = buffer_finish (&buffer);
532  len_avail = strlen (buf);
533  }
534 
535  if (offset >= len_avail)
536  {
537  /* Done. Get rid of the buffer. */
538  buffer_free (&buffer);
539  buf = NULL;
540  len_avail = 0;
541  return 0;
542  }
543 
544  if (len > len_avail - offset)
545  len = len_avail - offset;
546  memcpy (readbuf, buf + offset, len);
547 
548  return len;
549 }
550 
551 /* Collect all the threads in /proc by iterating through processes and
552  then tasks within each process. */
553 
554 static LONGEST
557 {
558  /* We make the process list snapshot when the object starts to be read. */
559  static const char *buf;
560  static LONGEST len_avail = -1;
561  static struct buffer buffer;
562 
563  if (offset == 0)
564  {
565  DIR *dirp;
566 
567  if (len_avail != -1 && len_avail != 0)
568  buffer_free (&buffer);
569  len_avail = 0;
570  buf = NULL;
571  buffer_init (&buffer);
572  buffer_grow_str (&buffer, "<osdata type=\"threads\">\n");
573 
574  dirp = opendir ("/proc");
575  if (dirp)
576  {
577  struct dirent *dp;
578 
579  while ((dp = readdir (dirp)) != NULL)
580  {
581  struct stat statbuf;
582  char procentry[sizeof ("/proc/4294967295")];
583 
584  if (!isdigit (dp->d_name[0])
585  || NAMELEN (dp) > sizeof ("4294967295") - 1)
586  continue;
587 
588  sprintf (procentry, "/proc/%s", dp->d_name);
589  if (stat (procentry, &statbuf) == 0
590  && S_ISDIR (statbuf.st_mode))
591  {
592  DIR *dirp2;
593  char *pathname;
594  PID_T pid;
595  char command[32];
596 
597  pathname = xstrprintf ("/proc/%s/task", dp->d_name);
598 
599  pid = atoi (dp->d_name);
600  command_from_pid (command, sizeof (command), pid);
601 
602  dirp2 = opendir (pathname);
603 
604  if (dirp2)
605  {
606  struct dirent *dp2;
607 
608  while ((dp2 = readdir (dirp2)) != NULL)
609  {
610  PID_T tid;
611  int core;
612 
613  if (!isdigit (dp2->d_name[0])
614  || NAMELEN (dp2) > sizeof ("4294967295") - 1)
615  continue;
616 
617  tid = atoi (dp2->d_name);
618  core = linux_common_core_of_thread (ptid_build (pid, tid, 0));
619 
621  &buffer,
622  "<item>"
623  "<column name=\"pid\">%lld</column>"
624  "<column name=\"command\">%s</column>"
625  "<column name=\"tid\">%lld</column>"
626  "<column name=\"core\">%d</column>"
627  "</item>",
628  pid,
629  command,
630  tid,
631  core);
632  }
633 
634  closedir (dirp2);
635  }
636 
637  xfree (pathname);
638  }
639  }
640 
641  closedir (dirp);
642  }
643 
644  buffer_grow_str0 (&buffer, "</osdata>\n");
645  buf = buffer_finish (&buffer);
646  len_avail = strlen (buf);
647  }
648 
649  if (offset >= len_avail)
650  {
651  /* Done. Get rid of the buffer. */
652  buffer_free (&buffer);
653  buf = NULL;
654  len_avail = 0;
655  return 0;
656  }
657 
658  if (len > len_avail - offset)
659  len = len_avail - offset;
660  memcpy (readbuf, buf + offset, len);
661 
662  return len;
663 }
664 
665 /* Collect data about the cpus/cores on the system */
666 
667 static LONGEST
670 {
671  static const char *buf;
672  static LONGEST len_avail = -1;
673  static struct buffer buffer;
674 
675  if (offset == 0)
676  {
677  FILE *fp;
678  int first_item = 1;
679 
680  if (len_avail != -1 && len_avail != 0)
681  buffer_free (&buffer);
682  len_avail = 0;
683  buf = NULL;
684  buffer_init (&buffer);
685  buffer_grow_str (&buffer, "<osdata type=\"cpus\">\n");
686 
687  fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
688  if (fp != NULL)
689  {
690  char buf[8192];
691 
692  do
693  {
694  if (fgets (buf, sizeof (buf), fp))
695  {
696  char *key, *value;
697  int i = 0;
698 
699  key = strtok (buf, ":");
700  if (key == NULL)
701  continue;
702 
703  value = strtok (NULL, ":");
704  if (value == NULL)
705  continue;
706 
707  while (key[i] != '\t' && key[i] != '\0')
708  i++;
709 
710  key[i] = '\0';
711 
712  i = 0;
713  while (value[i] != '\t' && value[i] != '\0')
714  i++;
715 
716  value[i] = '\0';
717 
718  if (strcmp (key, "processor") == 0)
719  {
720  if (first_item)
721  buffer_grow_str (&buffer, "<item>");
722  else
723  buffer_grow_str (&buffer, "</item><item>");
724 
725  first_item = 0;
726  }
727 
728  buffer_xml_printf (&buffer,
729  "<column name=\"%s\">%s</column>",
730  key,
731  value);
732  }
733  }
734  while (!feof (fp));
735 
736  if (first_item == 0)
737  buffer_grow_str (&buffer, "</item>");
738 
739  fclose (fp);
740  }
741 
742  buffer_grow_str0 (&buffer, "</osdata>\n");
743  buf = buffer_finish (&buffer);
744  len_avail = strlen (buf);
745  }
746 
747  if (offset >= len_avail)
748  {
749  /* Done. Get rid of the buffer. */
750  buffer_free (&buffer);
751  buf = NULL;
752  len_avail = 0;
753  return 0;
754  }
755 
756  if (len > len_avail - offset)
757  len = len_avail - offset;
758  memcpy (readbuf, buf + offset, len);
759 
760  return len;
761 }
762 
763 /* Collect all the open file descriptors found in /proc and put the details
764  found about them into READBUF. */
765 
766 static LONGEST
769 {
770  /* We make the process list snapshot when the object starts to be read. */
771  static const char *buf;
772  static LONGEST len_avail = -1;
773  static struct buffer buffer;
774 
775  if (offset == 0)
776  {
777  DIR *dirp;
778 
779  if (len_avail != -1 && len_avail != 0)
780  buffer_free (&buffer);
781  len_avail = 0;
782  buf = NULL;
783  buffer_init (&buffer);
784  buffer_grow_str (&buffer, "<osdata type=\"files\">\n");
785 
786  dirp = opendir ("/proc");
787  if (dirp)
788  {
789  struct dirent *dp;
790 
791  while ((dp = readdir (dirp)) != NULL)
792  {
793  struct stat statbuf;
794  char procentry[sizeof ("/proc/4294967295")];
795 
796  if (!isdigit (dp->d_name[0])
797  || NAMELEN (dp) > sizeof ("4294967295") - 1)
798  continue;
799 
800  sprintf (procentry, "/proc/%s", dp->d_name);
801  if (stat (procentry, &statbuf) == 0
802  && S_ISDIR (statbuf.st_mode))
803  {
804  char *pathname;
805  DIR *dirp2;
806  PID_T pid;
807  char command[32];
808 
809  pid = atoi (dp->d_name);
810  command_from_pid (command, sizeof (command), pid);
811 
812  pathname = xstrprintf ("/proc/%s/fd", dp->d_name);
813  dirp2 = opendir (pathname);
814 
815  if (dirp2)
816  {
817  struct dirent *dp2;
818 
819  while ((dp2 = readdir (dirp2)) != NULL)
820  {
821  char *fdname;
822  char buf[1000];
823  ssize_t rslt;
824 
825  if (!isdigit (dp2->d_name[0]))
826  continue;
827 
828  fdname = xstrprintf ("%s/%s", pathname, dp2->d_name);
829  rslt = readlink (fdname, buf, sizeof (buf) - 1);
830  if (rslt >= 0)
831  buf[rslt] = '\0';
832 
834  &buffer,
835  "<item>"
836  "<column name=\"pid\">%s</column>"
837  "<column name=\"command\">%s</column>"
838  "<column name=\"file descriptor\">%s</column>"
839  "<column name=\"name\">%s</column>"
840  "</item>",
841  dp->d_name,
842  command,
843  dp2->d_name,
844  (rslt >= 0 ? buf : dp2->d_name));
845  }
846 
847  closedir (dirp2);
848  }
849 
850  xfree (pathname);
851  }
852  }
853 
854  closedir (dirp);
855  }
856 
857  buffer_grow_str0 (&buffer, "</osdata>\n");
858  buf = buffer_finish (&buffer);
859  len_avail = strlen (buf);
860  }
861 
862  if (offset >= len_avail)
863  {
864  /* Done. Get rid of the buffer. */
865  buffer_free (&buffer);
866  buf = NULL;
867  len_avail = 0;
868  return 0;
869  }
870 
871  if (len > len_avail - offset)
872  len = len_avail - offset;
873  memcpy (readbuf, buf + offset, len);
874 
875  return len;
876 }
877 
878 /* Returns the socket state STATE in textual form. */
879 
880 static const char *
881 format_socket_state (unsigned char state)
882 {
883  /* Copied from include/net/tcp_states.h in the Linux kernel sources. */
884  enum {
885  TCP_ESTABLISHED = 1,
886  TCP_SYN_SENT,
887  TCP_SYN_RECV,
888  TCP_FIN_WAIT1,
889  TCP_FIN_WAIT2,
890  TCP_TIME_WAIT,
891  TCP_CLOSE,
892  TCP_CLOSE_WAIT,
893  TCP_LAST_ACK,
894  TCP_LISTEN,
895  TCP_CLOSING
896  };
897 
898  switch (state)
899  {
900  case TCP_ESTABLISHED:
901  return "ESTABLISHED";
902  case TCP_SYN_SENT:
903  return "SYN_SENT";
904  case TCP_SYN_RECV:
905  return "SYN_RECV";
906  case TCP_FIN_WAIT1:
907  return "FIN_WAIT1";
908  case TCP_FIN_WAIT2:
909  return "FIN_WAIT2";
910  case TCP_TIME_WAIT:
911  return "TIME_WAIT";
912  case TCP_CLOSE:
913  return "CLOSE";
914  case TCP_CLOSE_WAIT:
915  return "CLOSE_WAIT";
916  case TCP_LAST_ACK:
917  return "LAST_ACK";
918  case TCP_LISTEN:
919  return "LISTEN";
920  case TCP_CLOSING:
921  return "CLOSING";
922  default:
923  return "(unknown)";
924  }
925 }
926 
928  {
929  struct sockaddr sa;
930  struct sockaddr_in sin;
931  struct sockaddr_in6 sin6;
932  };
933 
934 /* Auxiliary function used by linux_xfer_osdata_isocket. Formats
935  information for all open internet sockets of type FAMILY on the
936  system into BUFFER. If TCP is set, only TCP sockets are processed,
937  otherwise only UDP sockets are processed. */
938 
939 static void
940 print_sockets (unsigned short family, int tcp, struct buffer *buffer)
941 {
942  const char *proc_file;
943  FILE *fp;
944 
945  if (family == AF_INET)
946  proc_file = tcp ? "/proc/net/tcp" : "/proc/net/udp";
947  else if (family == AF_INET6)
948  proc_file = tcp ? "/proc/net/tcp6" : "/proc/net/udp6";
949  else
950  return;
951 
952  fp = gdb_fopen_cloexec (proc_file, "r");
953  if (fp)
954  {
955  char buf[8192];
956 
957  do
958  {
959  if (fgets (buf, sizeof (buf), fp))
960  {
961  uid_t uid;
962  unsigned int local_port, remote_port, state;
963  char local_address[NI_MAXHOST], remote_address[NI_MAXHOST];
964  int result;
965 
966 #if NI_MAXHOST <= 32
967 #error "local_address and remote_address buffers too small"
968 #endif
969 
970  result = sscanf (buf,
971  "%*d: %32[0-9A-F]:%X %32[0-9A-F]:%X %X %*X:%*X %*X:%*X %*X %d %*d %*u %*s\n",
972  local_address, &local_port,
973  remote_address, &remote_port,
974  &state,
975  &uid);
976 
977  if (result == 6)
978  {
979  union socket_addr locaddr, remaddr;
980  size_t addr_size;
981  char user[UT_NAMESIZE];
982  char local_service[NI_MAXSERV], remote_service[NI_MAXSERV];
983 
984  if (family == AF_INET)
985  {
986  sscanf (local_address, "%X",
987  &locaddr.sin.sin_addr.s_addr);
988  sscanf (remote_address, "%X",
989  &remaddr.sin.sin_addr.s_addr);
990 
991  locaddr.sin.sin_port = htons (local_port);
992  remaddr.sin.sin_port = htons (remote_port);
993 
994  addr_size = sizeof (struct sockaddr_in);
995  }
996  else
997  {
998  sscanf (local_address, "%8X%8X%8X%8X",
999  locaddr.sin6.sin6_addr.s6_addr32,
1000  locaddr.sin6.sin6_addr.s6_addr32 + 1,
1001  locaddr.sin6.sin6_addr.s6_addr32 + 2,
1002  locaddr.sin6.sin6_addr.s6_addr32 + 3);
1003  sscanf (remote_address, "%8X%8X%8X%8X",
1004  remaddr.sin6.sin6_addr.s6_addr32,
1005  remaddr.sin6.sin6_addr.s6_addr32 + 1,
1006  remaddr.sin6.sin6_addr.s6_addr32 + 2,
1007  remaddr.sin6.sin6_addr.s6_addr32 + 3);
1008 
1009  locaddr.sin6.sin6_port = htons (local_port);
1010  remaddr.sin6.sin6_port = htons (remote_port);
1011 
1012  locaddr.sin6.sin6_flowinfo = 0;
1013  remaddr.sin6.sin6_flowinfo = 0;
1014  locaddr.sin6.sin6_scope_id = 0;
1015  remaddr.sin6.sin6_scope_id = 0;
1016 
1017  addr_size = sizeof (struct sockaddr_in6);
1018  }
1019 
1020  locaddr.sa.sa_family = remaddr.sa.sa_family = family;
1021 
1022  result = getnameinfo (&locaddr.sa, addr_size,
1023  local_address, sizeof (local_address),
1024  local_service, sizeof (local_service),
1025  NI_NUMERICHOST | NI_NUMERICSERV
1026  | (tcp ? 0 : NI_DGRAM));
1027  if (result)
1028  continue;
1029 
1030  result = getnameinfo (&remaddr.sa, addr_size,
1031  remote_address,
1032  sizeof (remote_address),
1033  remote_service,
1034  sizeof (remote_service),
1035  NI_NUMERICHOST | NI_NUMERICSERV
1036  | (tcp ? 0 : NI_DGRAM));
1037  if (result)
1038  continue;
1039 
1040  user_from_uid (user, sizeof (user), uid);
1041 
1043  buffer,
1044  "<item>"
1045  "<column name=\"local address\">%s</column>"
1046  "<column name=\"local port\">%s</column>"
1047  "<column name=\"remote address\">%s</column>"
1048  "<column name=\"remote port\">%s</column>"
1049  "<column name=\"state\">%s</column>"
1050  "<column name=\"user\">%s</column>"
1051  "<column name=\"family\">%s</column>"
1052  "<column name=\"protocol\">%s</column>"
1053  "</item>",
1054  local_address,
1055  local_service,
1056  remote_address,
1057  remote_service,
1058  format_socket_state (state),
1059  user,
1060  (family == AF_INET) ? "INET" : "INET6",
1061  tcp ? "STREAM" : "DGRAM");
1062  }
1063  }
1064  }
1065  while (!feof (fp));
1066 
1067  fclose (fp);
1068  }
1069 }
1070 
1071 /* Collect data about internet sockets and write it into READBUF. */
1072 
1073 static LONGEST
1076 {
1077  static const char *buf;
1078  static LONGEST len_avail = -1;
1079  static struct buffer buffer;
1080 
1081  if (offset == 0)
1082  {
1083  if (len_avail != -1 && len_avail != 0)
1084  buffer_free (&buffer);
1085  len_avail = 0;
1086  buf = NULL;
1087  buffer_init (&buffer);
1088  buffer_grow_str (&buffer, "<osdata type=\"I sockets\">\n");
1089 
1090  print_sockets (AF_INET, 1, &buffer);
1091  print_sockets (AF_INET, 0, &buffer);
1092  print_sockets (AF_INET6, 1, &buffer);
1093  print_sockets (AF_INET6, 0, &buffer);
1094 
1095  buffer_grow_str0 (&buffer, "</osdata>\n");
1096  buf = buffer_finish (&buffer);
1097  len_avail = strlen (buf);
1098  }
1099 
1100  if (offset >= len_avail)
1101  {
1102  /* Done. Get rid of the buffer. */
1103  buffer_free (&buffer);
1104  buf = NULL;
1105  len_avail = 0;
1106  return 0;
1107  }
1108 
1109  if (len > len_avail - offset)
1110  len = len_avail - offset;
1111  memcpy (readbuf, buf + offset, len);
1112 
1113  return len;
1114 }
1115 
1116 /* Converts the time SECONDS into textual form and copies it into a
1117  buffer TIME, with at most MAXLEN characters copied. */
1118 
1119 static void
1120 time_from_time_t (char *time, int maxlen, TIME_T seconds)
1121 {
1122  if (!seconds)
1123  time[0] = '\0';
1124  else
1125  {
1126  time_t t = (time_t) seconds;
1127 
1128  strncpy (time, ctime (&t), maxlen);
1129  time[maxlen - 1] = '\0';
1130  }
1131 }
1132 
1133 /* Finds the group name for the group GID and copies it into GROUP.
1134  At most MAXLEN characters are copied. */
1135 
1136 static void
1137 group_from_gid (char *group, int maxlen, gid_t gid)
1138 {
1139  struct group *grentry = getgrgid (gid);
1140 
1141  if (grentry)
1142  {
1143  strncpy (group, grentry->gr_name, maxlen);
1144  /* Ensure that the group name is null-terminated. */
1145  group[maxlen - 1] = '\0';
1146  }
1147  else
1148  group[0] = '\0';
1149 }
1150 
1151 /* Collect data about shared memory recorded in /proc and write it
1152  into READBUF. */
1153 
1154 static LONGEST
1157 {
1158  static const char *buf;
1159  static LONGEST len_avail = -1;
1160  static struct buffer buffer;
1161 
1162  if (offset == 0)
1163  {
1164  FILE *fp;
1165 
1166  if (len_avail != -1 && len_avail != 0)
1167  buffer_free (&buffer);
1168  len_avail = 0;
1169  buf = NULL;
1170  buffer_init (&buffer);
1171  buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n");
1172 
1173  fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
1174  if (fp)
1175  {
1176  char buf[8192];
1177 
1178  do
1179  {
1180  if (fgets (buf, sizeof (buf), fp))
1181  {
1182  key_t key;
1183  uid_t uid, cuid;
1184  gid_t gid, cgid;
1185  PID_T cpid, lpid;
1186  int shmid, size, nattch;
1187  TIME_T atime, dtime, ctime;
1188  unsigned int perms;
1189  int items_read;
1190 
1191  items_read = sscanf (buf,
1192  "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
1193  &key, &shmid, &perms, &size,
1194  &cpid, &lpid,
1195  &nattch,
1196  &uid, &gid, &cuid, &cgid,
1197  &atime, &dtime, &ctime);
1198 
1199  if (items_read == 14)
1200  {
1201  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1202  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1203  char ccmd[32], lcmd[32];
1204  char atime_str[32], dtime_str[32], ctime_str[32];
1205 
1206  user_from_uid (user, sizeof (user), uid);
1207  group_from_gid (group, sizeof (group), gid);
1208  user_from_uid (cuser, sizeof (cuser), cuid);
1209  group_from_gid (cgroup, sizeof (cgroup), cgid);
1210 
1211  command_from_pid (ccmd, sizeof (ccmd), cpid);
1212  command_from_pid (lcmd, sizeof (lcmd), lpid);
1213 
1214  time_from_time_t (atime_str, sizeof (atime_str), atime);
1215  time_from_time_t (dtime_str, sizeof (dtime_str), dtime);
1216  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1217 
1219  &buffer,
1220  "<item>"
1221  "<column name=\"key\">%d</column>"
1222  "<column name=\"shmid\">%d</column>"
1223  "<column name=\"permissions\">%o</column>"
1224  "<column name=\"size\">%d</column>"
1225  "<column name=\"creator command\">%s</column>"
1226  "<column name=\"last op. command\">%s</column>"
1227  "<column name=\"num attached\">%d</column>"
1228  "<column name=\"user\">%s</column>"
1229  "<column name=\"group\">%s</column>"
1230  "<column name=\"creator user\">%s</column>"
1231  "<column name=\"creator group\">%s</column>"
1232  "<column name=\"last shmat() time\">%s</column>"
1233  "<column name=\"last shmdt() time\">%s</column>"
1234  "<column name=\"last shmctl() time\">%s</column>"
1235  "</item>",
1236  key,
1237  shmid,
1238  perms,
1239  size,
1240  ccmd,
1241  lcmd,
1242  nattch,
1243  user,
1244  group,
1245  cuser,
1246  cgroup,
1247  atime_str,
1248  dtime_str,
1249  ctime_str);
1250  }
1251  }
1252  }
1253  while (!feof (fp));
1254 
1255  fclose (fp);
1256  }
1257 
1258  buffer_grow_str0 (&buffer, "</osdata>\n");
1259  buf = buffer_finish (&buffer);
1260  len_avail = strlen (buf);
1261  }
1262 
1263  if (offset >= len_avail)
1264  {
1265  /* Done. Get rid of the buffer. */
1266  buffer_free (&buffer);
1267  buf = NULL;
1268  len_avail = 0;
1269  return 0;
1270  }
1271 
1272  if (len > len_avail - offset)
1273  len = len_avail - offset;
1274  memcpy (readbuf, buf + offset, len);
1275 
1276  return len;
1277 }
1278 
1279 /* Collect data about semaphores recorded in /proc and write it
1280  into READBUF. */
1281 
1282 static LONGEST
1285 {
1286  static const char *buf;
1287  static LONGEST len_avail = -1;
1288  static struct buffer buffer;
1289 
1290  if (offset == 0)
1291  {
1292  FILE *fp;
1293 
1294  if (len_avail != -1 && len_avail != 0)
1295  buffer_free (&buffer);
1296  len_avail = 0;
1297  buf = NULL;
1298  buffer_init (&buffer);
1299  buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n");
1300 
1301  fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
1302  if (fp)
1303  {
1304  char buf[8192];
1305 
1306  do
1307  {
1308  if (fgets (buf, sizeof (buf), fp))
1309  {
1310  key_t key;
1311  uid_t uid, cuid;
1312  gid_t gid, cgid;
1313  unsigned int perms, nsems;
1314  int semid;
1315  TIME_T otime, ctime;
1316  int items_read;
1317 
1318  items_read = sscanf (buf,
1319  "%d %d %o %u %d %d %d %d %lld %lld",
1320  &key, &semid, &perms, &nsems,
1321  &uid, &gid, &cuid, &cgid,
1322  &otime, &ctime);
1323 
1324  if (items_read == 10)
1325  {
1326  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1327  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1328  char otime_str[32], ctime_str[32];
1329 
1330  user_from_uid (user, sizeof (user), uid);
1331  group_from_gid (group, sizeof (group), gid);
1332  user_from_uid (cuser, sizeof (cuser), cuid);
1333  group_from_gid (cgroup, sizeof (cgroup), cgid);
1334 
1335  time_from_time_t (otime_str, sizeof (otime_str), otime);
1336  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1337 
1339  &buffer,
1340  "<item>"
1341  "<column name=\"key\">%d</column>"
1342  "<column name=\"semid\">%d</column>"
1343  "<column name=\"permissions\">%o</column>"
1344  "<column name=\"num semaphores\">%u</column>"
1345  "<column name=\"user\">%s</column>"
1346  "<column name=\"group\">%s</column>"
1347  "<column name=\"creator user\">%s</column>"
1348  "<column name=\"creator group\">%s</column>"
1349  "<column name=\"last semop() time\">%s</column>"
1350  "<column name=\"last semctl() time\">%s</column>"
1351  "</item>",
1352  key,
1353  semid,
1354  perms,
1355  nsems,
1356  user,
1357  group,
1358  cuser,
1359  cgroup,
1360  otime_str,
1361  ctime_str);
1362  }
1363  }
1364  }
1365  while (!feof (fp));
1366 
1367  fclose (fp);
1368  }
1369 
1370  buffer_grow_str0 (&buffer, "</osdata>\n");
1371  buf = buffer_finish (&buffer);
1372  len_avail = strlen (buf);
1373  }
1374 
1375  if (offset >= len_avail)
1376  {
1377  /* Done. Get rid of the buffer. */
1378  buffer_free (&buffer);
1379  buf = NULL;
1380  len_avail = 0;
1381  return 0;
1382  }
1383 
1384  if (len > len_avail - offset)
1385  len = len_avail - offset;
1386  memcpy (readbuf, buf + offset, len);
1387 
1388  return len;
1389 }
1390 
1391 /* Collect data about message queues recorded in /proc and write it
1392  into READBUF. */
1393 
1394 static LONGEST
1397 {
1398  static const char *buf;
1399  static LONGEST len_avail = -1;
1400  static struct buffer buffer;
1401 
1402  if (offset == 0)
1403  {
1404  FILE *fp;
1405 
1406  if (len_avail != -1 && len_avail != 0)
1407  buffer_free (&buffer);
1408  len_avail = 0;
1409  buf = NULL;
1410  buffer_init (&buffer);
1411  buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n");
1412 
1413  fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
1414  if (fp)
1415  {
1416  char buf[8192];
1417 
1418  do
1419  {
1420  if (fgets (buf, sizeof (buf), fp))
1421  {
1422  key_t key;
1423  PID_T lspid, lrpid;
1424  uid_t uid, cuid;
1425  gid_t gid, cgid;
1426  unsigned int perms, cbytes, qnum;
1427  int msqid;
1428  TIME_T stime, rtime, ctime;
1429  int items_read;
1430 
1431  items_read = sscanf (buf,
1432  "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
1433  &key, &msqid, &perms, &cbytes, &qnum,
1434  &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
1435  &stime, &rtime, &ctime);
1436 
1437  if (items_read == 14)
1438  {
1439  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1440  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1441  char lscmd[32], lrcmd[32];
1442  char stime_str[32], rtime_str[32], ctime_str[32];
1443 
1444  user_from_uid (user, sizeof (user), uid);
1445  group_from_gid (group, sizeof (group), gid);
1446  user_from_uid (cuser, sizeof (cuser), cuid);
1447  group_from_gid (cgroup, sizeof (cgroup), cgid);
1448 
1449  command_from_pid (lscmd, sizeof (lscmd), lspid);
1450  command_from_pid (lrcmd, sizeof (lrcmd), lrpid);
1451 
1452  time_from_time_t (stime_str, sizeof (stime_str), stime);
1453  time_from_time_t (rtime_str, sizeof (rtime_str), rtime);
1454  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1455 
1457  &buffer,
1458  "<item>"
1459  "<column name=\"key\">%d</column>"
1460  "<column name=\"msqid\">%d</column>"
1461  "<column name=\"permissions\">%o</column>"
1462  "<column name=\"num used bytes\">%u</column>"
1463  "<column name=\"num messages\">%u</column>"
1464  "<column name=\"last msgsnd() command\">%s</column>"
1465  "<column name=\"last msgrcv() command\">%s</column>"
1466  "<column name=\"user\">%s</column>"
1467  "<column name=\"group\">%s</column>"
1468  "<column name=\"creator user\">%s</column>"
1469  "<column name=\"creator group\">%s</column>"
1470  "<column name=\"last msgsnd() time\">%s</column>"
1471  "<column name=\"last msgrcv() time\">%s</column>"
1472  "<column name=\"last msgctl() time\">%s</column>"
1473  "</item>",
1474  key,
1475  msqid,
1476  perms,
1477  cbytes,
1478  qnum,
1479  lscmd,
1480  lrcmd,
1481  user,
1482  group,
1483  cuser,
1484  cgroup,
1485  stime_str,
1486  rtime_str,
1487  ctime_str);
1488  }
1489  }
1490  }
1491  while (!feof (fp));
1492 
1493  fclose (fp);
1494  }
1495 
1496  buffer_grow_str0 (&buffer, "</osdata>\n");
1497  buf = buffer_finish (&buffer);
1498  len_avail = strlen (buf);
1499  }
1500 
1501  if (offset >= len_avail)
1502  {
1503  /* Done. Get rid of the buffer. */
1504  buffer_free (&buffer);
1505  buf = NULL;
1506  len_avail = 0;
1507  return 0;
1508  }
1509 
1510  if (len > len_avail - offset)
1511  len = len_avail - offset;
1512  memcpy (readbuf, buf + offset, len);
1513 
1514  return len;
1515 }
1516 
1517 /* Collect data about loaded kernel modules and write it into
1518  READBUF. */
1519 
1520 static LONGEST
1523 {
1524  static const char *buf;
1525  static LONGEST len_avail = -1;
1526  static struct buffer buffer;
1527 
1528  if (offset == 0)
1529  {
1530  FILE *fp;
1531 
1532  if (len_avail != -1 && len_avail != 0)
1533  buffer_free (&buffer);
1534  len_avail = 0;
1535  buf = NULL;
1536  buffer_init (&buffer);
1537  buffer_grow_str (&buffer, "<osdata type=\"modules\">\n");
1538 
1539  fp = gdb_fopen_cloexec ("/proc/modules", "r");
1540  if (fp)
1541  {
1542  char buf[8192];
1543 
1544  do
1545  {
1546  if (fgets (buf, sizeof (buf), fp))
1547  {
1548  char *name, *dependencies, *status, *tmp;
1549  unsigned int size;
1550  unsigned long long address;
1551  int uses;
1552 
1553  name = strtok (buf, " ");
1554  if (name == NULL)
1555  continue;
1556 
1557  tmp = strtok (NULL, " ");
1558  if (tmp == NULL)
1559  continue;
1560  if (sscanf (tmp, "%u", &size) != 1)
1561  continue;
1562 
1563  tmp = strtok (NULL, " ");
1564  if (tmp == NULL)
1565  continue;
1566  if (sscanf (tmp, "%d", &uses) != 1)
1567  continue;
1568 
1569  dependencies = strtok (NULL, " ");
1570  if (dependencies == NULL)
1571  continue;
1572 
1573  status = strtok (NULL, " ");
1574  if (status == NULL)
1575  continue;
1576 
1577  tmp = strtok (NULL, "\n");
1578  if (tmp == NULL)
1579  continue;
1580  if (sscanf (tmp, "%llx", &address) != 1)
1581  continue;
1582 
1584  &buffer,
1585  "<item>"
1586  "<column name=\"name\">%s</column>"
1587  "<column name=\"size\">%u</column>"
1588  "<column name=\"num uses\">%d</column>"
1589  "<column name=\"dependencies\">%s</column>"
1590  "<column name=\"status\">%s</column>"
1591  "<column name=\"address\">%llx</column>"
1592  "</item>",
1593  name,
1594  size,
1595  uses,
1596  dependencies,
1597  status,
1598  address);
1599  }
1600  }
1601  while (!feof (fp));
1602 
1603  fclose (fp);
1604  }
1605 
1606  buffer_grow_str0 (&buffer, "</osdata>\n");
1607  buf = buffer_finish (&buffer);
1608  len_avail = strlen (buf);
1609  }
1610 
1611  if (offset >= len_avail)
1612  {
1613  /* Done. Get rid of the buffer. */
1614  buffer_free (&buffer);
1615  buf = NULL;
1616  len_avail = 0;
1617  return 0;
1618  }
1619 
1620  if (len > len_avail - offset)
1621  len = len_avail - offset;
1622  memcpy (readbuf, buf + offset, len);
1623 
1624  return len;
1625 }
1626 
1627 struct osdata_type {
1628  char *type;
1629  char *title;
1632 } osdata_table[] = {
1633  { "cpus", "CPUs", "Listing of all cpus/cores on the system",
1635  { "files", "File descriptors", "Listing of all file descriptors",
1637  { "modules", "Kernel modules", "Listing of all loaded kernel modules",
1639  { "msg", "Message queues", "Listing of all message queues",
1641  { "processes", "Processes", "Listing of all processes",
1643  { "procgroups", "Process groups", "Listing of all process groups",
1645  { "semaphores", "Semaphores", "Listing of all semaphores",
1647  { "shm", "Shared-memory regions", "Listing of all shared-memory regions",
1649  { "sockets", "Sockets", "Listing of all internet-domain sockets",
1651  { "threads", "Threads", "Listing of all threads",
1653  { NULL, NULL, NULL }
1654 };
1655 
1656 LONGEST
1657 linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
1659 {
1660  if (!annex || *annex == '\0')
1661  {
1662  static const char *buf;
1663  static LONGEST len_avail = -1;
1664  static struct buffer buffer;
1665 
1666  if (offset == 0)
1667  {
1668  int i;
1669 
1670  if (len_avail != -1 && len_avail != 0)
1671  buffer_free (&buffer);
1672  len_avail = 0;
1673  buf = NULL;
1674  buffer_init (&buffer);
1675  buffer_grow_str (&buffer, "<osdata type=\"types\">\n");
1676 
1677  for (i = 0; osdata_table[i].type; ++i)
1679  &buffer,
1680  "<item>"
1681  "<column name=\"Type\">%s</column>"
1682  "<column name=\"Description\">%s</column>"
1683  "<column name=\"Title\">%s</column>"
1684  "</item>",
1685  osdata_table[i].type,
1686  osdata_table[i].description,
1687  osdata_table[i].title);
1688 
1689  buffer_grow_str0 (&buffer, "</osdata>\n");
1690  buf = buffer_finish (&buffer);
1691  len_avail = strlen (buf);
1692  }
1693 
1694  if (offset >= len_avail)
1695  {
1696  /* Done. Get rid of the buffer. */
1697  buffer_free (&buffer);
1698  buf = NULL;
1699  len_avail = 0;
1700  return 0;
1701  }
1702 
1703  if (len > len_avail - offset)
1704  len = len_avail - offset;
1705  memcpy (readbuf, buf + offset, len);
1706 
1707  return len;
1708  }
1709  else
1710  {
1711  int i;
1712 
1713  for (i = 0; osdata_table[i].type; ++i)
1714  {
1715  if (strcmp (annex, osdata_table[i].type) == 0)
1716  {
1717  gdb_assert (readbuf);
1718 
1719  return (osdata_table[i].getter) (readbuf, offset, len);
1720  }
1721  }
1722 
1723  return 0;
1724  }
1725 }
1726 
static int compare_processes(const void *process1, const void *process2)
Definition: linux-osdata.c:408
static void group_from_gid(char *group, int maxlen, gid_t gid)
#define MAX_PID_T_STRLEN
Definition: linux-osdata.c:54
static LONGEST linux_xfer_osdata_modules(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
static LONGEST linux_xfer_osdata_isockets(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
void xfree(void *)
Definition: common-utils.c:97
static LONGEST linux_xfer_osdata_shm(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
struct sockaddr_in6 sin6
Definition: linux-osdata.c:931
static LONGEST linux_xfer_osdata_fds(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:767
void buffer_free(struct buffer *buffer)
Definition: buffer.c:48
static LONGEST linux_xfer_osdata_cpus(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:668
static void user_from_uid(char *user, int maxlen, uid_t uid)
Definition: linux-osdata.c:215
static LONGEST linux_xfer_osdata_msg(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
FILE * gdb_fopen_cloexec(const char *filename, const char *opentype)
Definition: filestuff.c:304
Definition: ptid.h:35
ptid_t ptid_build(int pid, long lwp, long tid)
Definition: ptid.c:31
static LONGEST linux_xfer_osdata_processgroups(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:439
const char *const name
Definition: aarch64-tdep.c:68
struct osdata_type osdata_table[]
static void print_sockets(unsigned short family, int tcp, struct buffer *buffer)
Definition: linux-osdata.c:940
void buffer_xml_printf(struct buffer *buffer, const char *format,...)
Definition: buffer.c:76
static int get_process_owner(uid_t *owner, PID_T pid)
Definition: linux-osdata.c:233
static void command_from_pid(char *command, int maxlen, PID_T pid)
Definition: linux-osdata.c:117
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int status
Definition: gnu-nat.c:1816
struct sockaddr_in sin
Definition: linux-osdata.c:930
Definition: gdbtypes.h:749
#define gdb_assert(expr)
Definition: gdb_assert.h:33
LONGEST(* getter)(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
int linux_common_core_of_thread(ptid_t ptid)
Definition: linux-osdata.c:61
long long PID_T
Definition: linux-osdata.c:47
char * xstrprintf(const char *format,...)
Definition: common-utils.c:107
#define buffer_grow_str(BUFFER, STRING)
Definition: buffer.h:54
void * xmalloc(YYSIZE_T)
static char * commandline_from_pid(PID_T pid)
Definition: linux-osdata.c:156
static LONGEST linux_xfer_osdata_processes(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:291
Definition: value.c:172
LONGEST linux_common_xfer_osdata(const char *annex, gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
PTR xrealloc(PTR ptr, size_t size)
Definition: common-utils.c:51
char * description
struct sockaddr sa
Definition: linux-osdata.c:929
#define buffer_grow_str0(BUFFER, STRING)
Definition: buffer.h:56
bfd_byte gdb_byte
Definition: common-types.h:38
void buffer_init(struct buffer *buffer)
Definition: buffer.c:60
int offset
Definition: agent.c:65
Definition: buffer.h:23
#define qsort
Definition: ada-exp.c:2747
static void time_from_time_t(char *time, int maxlen, TIME_T seconds)
unsigned long long ULONGEST
Definition: common-types.h:53
long ptid_get_lwp(ptid_t ptid)
Definition: ptid.c:60
long long TIME_T
Definition: linux-osdata.c:52
static LONGEST linux_xfer_osdata_threads(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:555
static LONGEST linux_xfer_osdata_sem(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
#define NAMELEN(dirent)
Definition: linux-osdata.c:41
static int get_cores_used_by_process(PID_T pid, int *cores, const int num_cores)
Definition: linux-osdata.c:253
PTR xcalloc(size_t number, size_t size)
Definition: common-utils.c:71
char * buffer_finish(struct buffer *buffer)
Definition: buffer.c:66
size_t size
Definition: go32-nat.c:242
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int int rusage_t pid_t pid
Definition: gnu-nat.c:1818
long long LONGEST
Definition: common-types.h:52
static const char * format_socket_state(unsigned char state)
Definition: linux-osdata.c:881
const ULONGEST const LONGEST len
Definition: target.h:309