xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/nat/linux-osdata.c (revision 8ecbf5f02b752fcb7debe1a8fab1dc82602bc760)
1 /* Linux-specific functions to retrieve OS data.
2 
3    Copyright (C) 2009-2017 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
61 linux_common_core_of_thread (ptid_t ptid)
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 = (char *) 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 *
156 commandline_from_pid (PID_T pid)
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
291 linux_xfer_osdata_processes (gdb_byte *readbuf,
292 			     ULONGEST offset, ULONGEST len)
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 = XCNEWVEC (int, num_cores);
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 
359 	      buffer_xml_printf (
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
439 linux_xfer_osdata_processgroups (gdb_byte *readbuf,
440 				 ULONGEST offset, ULONGEST len)
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 = XNEWVEC (PID_T, list_block_size * 2);
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),
499 		 compare_processes);
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 
511 	      buffer_xml_printf (
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
555 linux_xfer_osdata_threads (gdb_byte *readbuf,
556 			   ULONGEST offset, ULONGEST len)
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 	      xsnprintf (procentry, sizeof (procentry), "/proc/%s",
589 			 dp->d_name);
590 	      if (stat (procentry, &statbuf) == 0
591 		  && S_ISDIR (statbuf.st_mode))
592 		{
593 		  DIR *dirp2;
594 		  char *pathname;
595 		  PID_T pid;
596 		  char command[32];
597 
598 		  pathname = xstrprintf ("/proc/%s/task", dp->d_name);
599 
600 		  pid = atoi (dp->d_name);
601 		  command_from_pid (command, sizeof (command), pid);
602 
603 		  dirp2 = opendir (pathname);
604 
605 		  if (dirp2)
606 		    {
607 		      struct dirent *dp2;
608 
609 		      while ((dp2 = readdir (dirp2)) != NULL)
610 			{
611 			  PID_T tid;
612 			  int core;
613 
614 			  if (!isdigit (dp2->d_name[0])
615 			      || NAMELEN (dp2) > sizeof ("4294967295") - 1)
616 			    continue;
617 
618 			  tid = atoi (dp2->d_name);
619 			  core = linux_common_core_of_thread (ptid_build (pid, tid, 0));
620 
621 			  buffer_xml_printf (
622 			    &buffer,
623 			    "<item>"
624 			    "<column name=\"pid\">%lld</column>"
625 			    "<column name=\"command\">%s</column>"
626 			    "<column name=\"tid\">%lld</column>"
627 			    "<column name=\"core\">%d</column>"
628 			    "</item>",
629 			    pid,
630 			    command,
631 			    tid,
632 			    core);
633 			}
634 
635 		      closedir (dirp2);
636 		    }
637 
638 		  xfree (pathname);
639 		}
640 	    }
641 
642 	  closedir (dirp);
643 	}
644 
645       buffer_grow_str0 (&buffer, "</osdata>\n");
646       buf = buffer_finish (&buffer);
647       len_avail = strlen (buf);
648     }
649 
650   if (offset >= len_avail)
651     {
652       /* Done.  Get rid of the buffer.  */
653       buffer_free (&buffer);
654       buf = NULL;
655       len_avail = 0;
656       return 0;
657     }
658 
659   if (len > len_avail - offset)
660     len = len_avail - offset;
661   memcpy (readbuf, buf + offset, len);
662 
663   return len;
664 }
665 
666 /* Collect data about the cpus/cores on the system */
667 
668 static LONGEST
669 linux_xfer_osdata_cpus (gdb_byte *readbuf,
670 			   ULONGEST offset, ULONGEST len)
671 {
672   static const char *buf;
673   static LONGEST len_avail = -1;
674   static struct buffer buffer;
675 
676   if (offset == 0)
677     {
678       FILE *fp;
679       int first_item = 1;
680 
681       if (len_avail != -1 && len_avail != 0)
682 	buffer_free (&buffer);
683       len_avail = 0;
684       buf = NULL;
685       buffer_init (&buffer);
686       buffer_grow_str (&buffer, "<osdata type=\"cpus\">\n");
687 
688       fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
689       if (fp != NULL)
690 	{
691 	  char buf[8192];
692 
693 	  do
694 	    {
695 	      if (fgets (buf, sizeof (buf), fp))
696 		{
697 		  char *key, *value;
698 		  int i = 0;
699 
700 		  key = strtok (buf, ":");
701 		  if (key == NULL)
702 		    continue;
703 
704 		  value = strtok (NULL, ":");
705 		  if (value == NULL)
706 		    continue;
707 
708 		  while (key[i] != '\t' && key[i] != '\0')
709 		    i++;
710 
711 		  key[i] = '\0';
712 
713 		  i = 0;
714 		  while (value[i] != '\t' && value[i] != '\0')
715 		    i++;
716 
717 		  value[i] = '\0';
718 
719 		  if (strcmp (key, "processor") == 0)
720 		    {
721 		      if (first_item)
722 			buffer_grow_str (&buffer, "<item>");
723 		      else
724 			buffer_grow_str (&buffer, "</item><item>");
725 
726 		      first_item = 0;
727 		    }
728 
729 		  buffer_xml_printf (&buffer,
730 				     "<column name=\"%s\">%s</column>",
731 				     key,
732 				     value);
733 		}
734 	    }
735 	  while (!feof (fp));
736 
737 	  if (first_item == 0)
738 	    buffer_grow_str (&buffer, "</item>");
739 
740 	  fclose (fp);
741 	}
742 
743       buffer_grow_str0 (&buffer, "</osdata>\n");
744       buf = buffer_finish (&buffer);
745       len_avail = strlen (buf);
746     }
747 
748   if (offset >= len_avail)
749     {
750       /* Done.  Get rid of the buffer.  */
751       buffer_free (&buffer);
752       buf = NULL;
753       len_avail = 0;
754       return 0;
755     }
756 
757   if (len > len_avail - offset)
758     len = len_avail - offset;
759   memcpy (readbuf, buf + offset, len);
760 
761   return len;
762 }
763 
764 /* Collect all the open file descriptors found in /proc and put the details
765    found about them into READBUF.  */
766 
767 static LONGEST
768 linux_xfer_osdata_fds (gdb_byte *readbuf,
769 		       ULONGEST offset, ULONGEST len)
770 {
771   /* We make the process list snapshot when the object starts to be read.  */
772   static const char *buf;
773   static LONGEST len_avail = -1;
774   static struct buffer buffer;
775 
776   if (offset == 0)
777     {
778       DIR *dirp;
779 
780       if (len_avail != -1 && len_avail != 0)
781 	buffer_free (&buffer);
782       len_avail = 0;
783       buf = NULL;
784       buffer_init (&buffer);
785       buffer_grow_str (&buffer, "<osdata type=\"files\">\n");
786 
787       dirp = opendir ("/proc");
788       if (dirp)
789 	{
790 	  struct dirent *dp;
791 
792 	  while ((dp = readdir (dirp)) != NULL)
793 	    {
794 	      struct stat statbuf;
795 	      char procentry[sizeof ("/proc/4294967295")];
796 
797 	      if (!isdigit (dp->d_name[0])
798 		  || NAMELEN (dp) > sizeof ("4294967295") - 1)
799 		continue;
800 
801 	      xsnprintf (procentry, sizeof (procentry), "/proc/%s",
802 			 dp->d_name);
803 	      if (stat (procentry, &statbuf) == 0
804 		  && S_ISDIR (statbuf.st_mode))
805 		{
806 		  char *pathname;
807 		  DIR *dirp2;
808 		  PID_T pid;
809 		  char command[32];
810 
811 		  pid = atoi (dp->d_name);
812 		  command_from_pid (command, sizeof (command), pid);
813 
814 		  pathname = xstrprintf ("/proc/%s/fd", dp->d_name);
815 		  dirp2 = opendir (pathname);
816 
817 		  if (dirp2)
818 		    {
819 		      struct dirent *dp2;
820 
821 		      while ((dp2 = readdir (dirp2)) != NULL)
822 			{
823 			  char *fdname;
824 			  char buf[1000];
825 			  ssize_t rslt;
826 
827 			  if (!isdigit (dp2->d_name[0]))
828 			    continue;
829 
830 			  fdname = xstrprintf ("%s/%s", pathname, dp2->d_name);
831 			  rslt = readlink (fdname, buf, sizeof (buf) - 1);
832 			  if (rslt >= 0)
833 			    buf[rslt] = '\0';
834 
835 			  buffer_xml_printf (
836 			    &buffer,
837 			    "<item>"
838 			    "<column name=\"pid\">%s</column>"
839 			    "<column name=\"command\">%s</column>"
840 			    "<column name=\"file descriptor\">%s</column>"
841 			    "<column name=\"name\">%s</column>"
842 			    "</item>",
843 			    dp->d_name,
844 			    command,
845 			    dp2->d_name,
846 			    (rslt >= 0 ? buf : dp2->d_name));
847 			}
848 
849 		      closedir (dirp2);
850 		    }
851 
852 		  xfree (pathname);
853 		}
854 	    }
855 
856 	  closedir (dirp);
857 	}
858 
859       buffer_grow_str0 (&buffer, "</osdata>\n");
860       buf = buffer_finish (&buffer);
861       len_avail = strlen (buf);
862     }
863 
864   if (offset >= len_avail)
865     {
866       /* Done.  Get rid of the buffer.  */
867       buffer_free (&buffer);
868       buf = NULL;
869       len_avail = 0;
870       return 0;
871     }
872 
873   if (len > len_avail - offset)
874     len = len_avail - offset;
875   memcpy (readbuf, buf + offset, len);
876 
877   return len;
878 }
879 
880 /* Returns the socket state STATE in textual form.  */
881 
882 static const char *
883 format_socket_state (unsigned char state)
884 {
885   /* Copied from include/net/tcp_states.h in the Linux kernel sources.  */
886   enum {
887     TCP_ESTABLISHED = 1,
888     TCP_SYN_SENT,
889     TCP_SYN_RECV,
890     TCP_FIN_WAIT1,
891     TCP_FIN_WAIT2,
892     TCP_TIME_WAIT,
893     TCP_CLOSE,
894     TCP_CLOSE_WAIT,
895     TCP_LAST_ACK,
896     TCP_LISTEN,
897     TCP_CLOSING
898   };
899 
900   switch (state)
901     {
902     case TCP_ESTABLISHED:
903       return "ESTABLISHED";
904     case TCP_SYN_SENT:
905       return "SYN_SENT";
906     case TCP_SYN_RECV:
907       return "SYN_RECV";
908     case TCP_FIN_WAIT1:
909       return "FIN_WAIT1";
910     case TCP_FIN_WAIT2:
911       return "FIN_WAIT2";
912     case TCP_TIME_WAIT:
913       return "TIME_WAIT";
914     case TCP_CLOSE:
915       return "CLOSE";
916     case TCP_CLOSE_WAIT:
917       return "CLOSE_WAIT";
918     case TCP_LAST_ACK:
919       return "LAST_ACK";
920     case TCP_LISTEN:
921       return "LISTEN";
922     case TCP_CLOSING:
923       return "CLOSING";
924     default:
925       return "(unknown)";
926     }
927 }
928 
929 union socket_addr
930   {
931     struct sockaddr sa;
932     struct sockaddr_in sin;
933     struct sockaddr_in6 sin6;
934   };
935 
936 /* Auxiliary function used by linux_xfer_osdata_isocket.  Formats
937    information for all open internet sockets of type FAMILY on the
938    system into BUFFER.  If TCP is set, only TCP sockets are processed,
939    otherwise only UDP sockets are processed.  */
940 
941 static void
942 print_sockets (unsigned short family, int tcp, struct buffer *buffer)
943 {
944   const char *proc_file;
945   FILE *fp;
946 
947   if (family == AF_INET)
948     proc_file = tcp ? "/proc/net/tcp" : "/proc/net/udp";
949   else if (family == AF_INET6)
950     proc_file = tcp ? "/proc/net/tcp6" : "/proc/net/udp6";
951   else
952     return;
953 
954   fp = gdb_fopen_cloexec (proc_file, "r");
955   if (fp)
956     {
957       char buf[8192];
958 
959       do
960 	{
961 	  if (fgets (buf, sizeof (buf), fp))
962 	    {
963 	      uid_t uid;
964 	      unsigned int local_port, remote_port, state;
965 	      char local_address[NI_MAXHOST], remote_address[NI_MAXHOST];
966 	      int result;
967 
968 #if NI_MAXHOST <= 32
969 #error "local_address and remote_address buffers too small"
970 #endif
971 
972 	      result = sscanf (buf,
973 			       "%*d: %32[0-9A-F]:%X %32[0-9A-F]:%X %X %*X:%*X %*X:%*X %*X %d %*d %*u %*s\n",
974 			       local_address, &local_port,
975 			       remote_address, &remote_port,
976 			       &state,
977 			       &uid);
978 
979 	      if (result == 6)
980 		{
981 		  union socket_addr locaddr, remaddr;
982 		  size_t addr_size;
983 		  char user[UT_NAMESIZE];
984 		  char local_service[NI_MAXSERV], remote_service[NI_MAXSERV];
985 
986 		  if (family == AF_INET)
987 		    {
988 		      sscanf (local_address, "%X",
989 			      &locaddr.sin.sin_addr.s_addr);
990 		      sscanf (remote_address, "%X",
991 			      &remaddr.sin.sin_addr.s_addr);
992 
993 		      locaddr.sin.sin_port = htons (local_port);
994 		      remaddr.sin.sin_port = htons (remote_port);
995 
996 		      addr_size = sizeof (struct sockaddr_in);
997 		    }
998 		  else
999 		    {
1000 		      sscanf (local_address, "%8X%8X%8X%8X",
1001 			      locaddr.sin6.sin6_addr.s6_addr32,
1002 			      locaddr.sin6.sin6_addr.s6_addr32 + 1,
1003 			      locaddr.sin6.sin6_addr.s6_addr32 + 2,
1004 			      locaddr.sin6.sin6_addr.s6_addr32 + 3);
1005 		      sscanf (remote_address, "%8X%8X%8X%8X",
1006 			      remaddr.sin6.sin6_addr.s6_addr32,
1007 			      remaddr.sin6.sin6_addr.s6_addr32 + 1,
1008 			      remaddr.sin6.sin6_addr.s6_addr32 + 2,
1009 			      remaddr.sin6.sin6_addr.s6_addr32 + 3);
1010 
1011 		      locaddr.sin6.sin6_port = htons (local_port);
1012 		      remaddr.sin6.sin6_port = htons (remote_port);
1013 
1014 		      locaddr.sin6.sin6_flowinfo = 0;
1015 		      remaddr.sin6.sin6_flowinfo = 0;
1016 		      locaddr.sin6.sin6_scope_id = 0;
1017 		      remaddr.sin6.sin6_scope_id = 0;
1018 
1019 		      addr_size = sizeof (struct sockaddr_in6);
1020 		    }
1021 
1022 		  locaddr.sa.sa_family = remaddr.sa.sa_family = family;
1023 
1024 		  result = getnameinfo (&locaddr.sa, addr_size,
1025 					local_address, sizeof (local_address),
1026 					local_service, sizeof (local_service),
1027 					NI_NUMERICHOST | NI_NUMERICSERV
1028 					| (tcp ? 0 : NI_DGRAM));
1029 		  if (result)
1030 		    continue;
1031 
1032 		  result = getnameinfo (&remaddr.sa, addr_size,
1033 					remote_address,
1034 					sizeof (remote_address),
1035 					remote_service,
1036 					sizeof (remote_service),
1037 					NI_NUMERICHOST | NI_NUMERICSERV
1038 					| (tcp ? 0 : NI_DGRAM));
1039 		  if (result)
1040 		    continue;
1041 
1042 		  user_from_uid (user, sizeof (user), uid);
1043 
1044 		  buffer_xml_printf (
1045 		      buffer,
1046 		      "<item>"
1047 		      "<column name=\"local address\">%s</column>"
1048 		      "<column name=\"local port\">%s</column>"
1049 		      "<column name=\"remote address\">%s</column>"
1050 		      "<column name=\"remote port\">%s</column>"
1051 		      "<column name=\"state\">%s</column>"
1052 		      "<column name=\"user\">%s</column>"
1053 		      "<column name=\"family\">%s</column>"
1054 		      "<column name=\"protocol\">%s</column>"
1055 		      "</item>",
1056 		      local_address,
1057 		      local_service,
1058 		      remote_address,
1059 		      remote_service,
1060 		      format_socket_state (state),
1061 		      user,
1062 		      (family == AF_INET) ? "INET" : "INET6",
1063 		      tcp ? "STREAM" : "DGRAM");
1064 		}
1065 	    }
1066 	}
1067       while (!feof (fp));
1068 
1069       fclose (fp);
1070     }
1071 }
1072 
1073 /* Collect data about internet sockets and write it into READBUF.  */
1074 
1075 static LONGEST
1076 linux_xfer_osdata_isockets (gdb_byte *readbuf,
1077 			    ULONGEST offset, ULONGEST len)
1078 {
1079   static const char *buf;
1080   static LONGEST len_avail = -1;
1081   static struct buffer buffer;
1082 
1083   if (offset == 0)
1084     {
1085       if (len_avail != -1 && len_avail != 0)
1086 	buffer_free (&buffer);
1087       len_avail = 0;
1088       buf = NULL;
1089       buffer_init (&buffer);
1090       buffer_grow_str (&buffer, "<osdata type=\"I sockets\">\n");
1091 
1092       print_sockets (AF_INET, 1, &buffer);
1093       print_sockets (AF_INET, 0, &buffer);
1094       print_sockets (AF_INET6, 1, &buffer);
1095       print_sockets (AF_INET6, 0, &buffer);
1096 
1097       buffer_grow_str0 (&buffer, "</osdata>\n");
1098       buf = buffer_finish (&buffer);
1099       len_avail = strlen (buf);
1100     }
1101 
1102   if (offset >= len_avail)
1103     {
1104       /* Done.  Get rid of the buffer.  */
1105       buffer_free (&buffer);
1106       buf = NULL;
1107       len_avail = 0;
1108       return 0;
1109     }
1110 
1111   if (len > len_avail - offset)
1112     len = len_avail - offset;
1113   memcpy (readbuf, buf + offset, len);
1114 
1115   return len;
1116 }
1117 
1118 /* Converts the time SECONDS into textual form and copies it into a
1119    buffer TIME, with at most MAXLEN characters copied.  */
1120 
1121 static void
1122 time_from_time_t (char *time, int maxlen, TIME_T seconds)
1123 {
1124   if (!seconds)
1125     time[0] = '\0';
1126   else
1127     {
1128       time_t t = (time_t) seconds;
1129 
1130       strncpy (time, ctime (&t), maxlen);
1131       time[maxlen - 1] = '\0';
1132     }
1133 }
1134 
1135 /* Finds the group name for the group GID and copies it into GROUP.
1136    At most MAXLEN characters are copied.  */
1137 
1138 static void
1139 group_from_gid (char *group, int maxlen, gid_t gid)
1140 {
1141   struct group *grentry = getgrgid (gid);
1142 
1143   if (grentry)
1144     {
1145       strncpy (group, grentry->gr_name, maxlen);
1146       /* Ensure that the group name is null-terminated.  */
1147       group[maxlen - 1] = '\0';
1148     }
1149   else
1150     group[0] = '\0';
1151 }
1152 
1153 /* Collect data about shared memory recorded in /proc and write it
1154    into READBUF.  */
1155 
1156 static LONGEST
1157 linux_xfer_osdata_shm (gdb_byte *readbuf,
1158 		       ULONGEST offset, ULONGEST len)
1159 {
1160   static const char *buf;
1161   static LONGEST len_avail = -1;
1162   static struct buffer buffer;
1163 
1164   if (offset == 0)
1165     {
1166       FILE *fp;
1167 
1168       if (len_avail != -1 && len_avail != 0)
1169 	buffer_free (&buffer);
1170       len_avail = 0;
1171       buf = NULL;
1172       buffer_init (&buffer);
1173       buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n");
1174 
1175       fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
1176       if (fp)
1177 	{
1178 	  char buf[8192];
1179 
1180 	  do
1181 	    {
1182 	      if (fgets (buf, sizeof (buf), fp))
1183 		{
1184 		  key_t key;
1185 		  uid_t uid, cuid;
1186 		  gid_t gid, cgid;
1187 		  PID_T cpid, lpid;
1188 		  int shmid, size, nattch;
1189 		  TIME_T atime, dtime, ctime;
1190 		  unsigned int perms;
1191 		  int items_read;
1192 
1193 		  items_read = sscanf (buf,
1194 				       "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
1195 				       &key, &shmid, &perms, &size,
1196 				       &cpid, &lpid,
1197 				       &nattch,
1198 				       &uid, &gid, &cuid, &cgid,
1199 				       &atime, &dtime, &ctime);
1200 
1201 		  if (items_read == 14)
1202 		    {
1203 		      char user[UT_NAMESIZE], group[UT_NAMESIZE];
1204 		      char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1205 		      char ccmd[32], lcmd[32];
1206 		      char atime_str[32], dtime_str[32], ctime_str[32];
1207 
1208 		      user_from_uid (user, sizeof (user), uid);
1209 		      group_from_gid (group, sizeof (group), gid);
1210 		      user_from_uid (cuser, sizeof (cuser), cuid);
1211 		      group_from_gid (cgroup, sizeof (cgroup), cgid);
1212 
1213 		      command_from_pid (ccmd, sizeof (ccmd), cpid);
1214 		      command_from_pid (lcmd, sizeof (lcmd), lpid);
1215 
1216 		      time_from_time_t (atime_str, sizeof (atime_str), atime);
1217 		      time_from_time_t (dtime_str, sizeof (dtime_str), dtime);
1218 		      time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1219 
1220 		      buffer_xml_printf (
1221 		          &buffer,
1222 			  "<item>"
1223 			  "<column name=\"key\">%d</column>"
1224 			  "<column name=\"shmid\">%d</column>"
1225 			  "<column name=\"permissions\">%o</column>"
1226 			  "<column name=\"size\">%d</column>"
1227 			  "<column name=\"creator command\">%s</column>"
1228 			  "<column name=\"last op. command\">%s</column>"
1229 			  "<column name=\"num attached\">%d</column>"
1230 			  "<column name=\"user\">%s</column>"
1231 			  "<column name=\"group\">%s</column>"
1232 			  "<column name=\"creator user\">%s</column>"
1233 			  "<column name=\"creator group\">%s</column>"
1234 			  "<column name=\"last shmat() time\">%s</column>"
1235 			  "<column name=\"last shmdt() time\">%s</column>"
1236 			  "<column name=\"last shmctl() time\">%s</column>"
1237 			  "</item>",
1238 			  key,
1239 			  shmid,
1240 			  perms,
1241 			  size,
1242 			  ccmd,
1243 			  lcmd,
1244 			  nattch,
1245 			  user,
1246 			  group,
1247 			  cuser,
1248 			  cgroup,
1249 			  atime_str,
1250 			  dtime_str,
1251 			  ctime_str);
1252 		    }
1253 		}
1254 	    }
1255 	  while (!feof (fp));
1256 
1257 	  fclose (fp);
1258 	}
1259 
1260       buffer_grow_str0 (&buffer, "</osdata>\n");
1261       buf = buffer_finish (&buffer);
1262       len_avail = strlen (buf);
1263     }
1264 
1265   if (offset >= len_avail)
1266     {
1267       /* Done.  Get rid of the buffer.  */
1268       buffer_free (&buffer);
1269       buf = NULL;
1270       len_avail = 0;
1271       return 0;
1272     }
1273 
1274   if (len > len_avail - offset)
1275     len = len_avail - offset;
1276   memcpy (readbuf, buf + offset, len);
1277 
1278   return len;
1279 }
1280 
1281 /* Collect data about semaphores recorded in /proc and write it
1282    into READBUF.  */
1283 
1284 static LONGEST
1285 linux_xfer_osdata_sem (gdb_byte *readbuf,
1286 		       ULONGEST offset, ULONGEST len)
1287 {
1288   static const char *buf;
1289   static LONGEST len_avail = -1;
1290   static struct buffer buffer;
1291 
1292   if (offset == 0)
1293     {
1294       FILE *fp;
1295 
1296       if (len_avail != -1 && len_avail != 0)
1297 	buffer_free (&buffer);
1298       len_avail = 0;
1299       buf = NULL;
1300       buffer_init (&buffer);
1301       buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n");
1302 
1303       fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
1304       if (fp)
1305 	{
1306 	  char buf[8192];
1307 
1308 	  do
1309 	    {
1310 	      if (fgets (buf, sizeof (buf), fp))
1311 		{
1312 		  key_t key;
1313 		  uid_t uid, cuid;
1314 		  gid_t gid, cgid;
1315 		  unsigned int perms, nsems;
1316 		  int semid;
1317 		  TIME_T otime, ctime;
1318 		  int items_read;
1319 
1320 		  items_read = sscanf (buf,
1321 				       "%d %d %o %u %d %d %d %d %lld %lld",
1322 				       &key, &semid, &perms, &nsems,
1323 				       &uid, &gid, &cuid, &cgid,
1324 				       &otime, &ctime);
1325 
1326 		  if (items_read == 10)
1327 		    {
1328 		      char user[UT_NAMESIZE], group[UT_NAMESIZE];
1329 		      char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1330 		      char otime_str[32], ctime_str[32];
1331 
1332 		      user_from_uid (user, sizeof (user), uid);
1333 		      group_from_gid (group, sizeof (group), gid);
1334 		      user_from_uid (cuser, sizeof (cuser), cuid);
1335 		      group_from_gid (cgroup, sizeof (cgroup), cgid);
1336 
1337 		      time_from_time_t (otime_str, sizeof (otime_str), otime);
1338 		      time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1339 
1340 		      buffer_xml_printf (
1341 			  &buffer,
1342 			  "<item>"
1343 			  "<column name=\"key\">%d</column>"
1344 			  "<column name=\"semid\">%d</column>"
1345 			  "<column name=\"permissions\">%o</column>"
1346 			  "<column name=\"num semaphores\">%u</column>"
1347 			  "<column name=\"user\">%s</column>"
1348 			  "<column name=\"group\">%s</column>"
1349 			  "<column name=\"creator user\">%s</column>"
1350 			  "<column name=\"creator group\">%s</column>"
1351 			  "<column name=\"last semop() time\">%s</column>"
1352 			  "<column name=\"last semctl() time\">%s</column>"
1353 			  "</item>",
1354 			  key,
1355 			  semid,
1356 			  perms,
1357 			  nsems,
1358 			  user,
1359 			  group,
1360 			  cuser,
1361 			  cgroup,
1362 			  otime_str,
1363 			  ctime_str);
1364 		    }
1365 		}
1366 	    }
1367 	  while (!feof (fp));
1368 
1369 	  fclose (fp);
1370 	}
1371 
1372       buffer_grow_str0 (&buffer, "</osdata>\n");
1373       buf = buffer_finish (&buffer);
1374       len_avail = strlen (buf);
1375     }
1376 
1377   if (offset >= len_avail)
1378     {
1379       /* Done.  Get rid of the buffer.  */
1380       buffer_free (&buffer);
1381       buf = NULL;
1382       len_avail = 0;
1383       return 0;
1384     }
1385 
1386   if (len > len_avail - offset)
1387     len = len_avail - offset;
1388   memcpy (readbuf, buf + offset, len);
1389 
1390   return len;
1391 }
1392 
1393 /* Collect data about message queues recorded in /proc and write it
1394    into READBUF.  */
1395 
1396 static LONGEST
1397 linux_xfer_osdata_msg (gdb_byte *readbuf,
1398 		       ULONGEST offset, ULONGEST len)
1399 {
1400   static const char *buf;
1401   static LONGEST len_avail = -1;
1402   static struct buffer buffer;
1403 
1404   if (offset == 0)
1405     {
1406       FILE *fp;
1407 
1408       if (len_avail != -1 && len_avail != 0)
1409 	buffer_free (&buffer);
1410       len_avail = 0;
1411       buf = NULL;
1412       buffer_init (&buffer);
1413       buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n");
1414 
1415       fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
1416       if (fp)
1417 	{
1418 	  char buf[8192];
1419 
1420 	  do
1421 	    {
1422 	      if (fgets (buf, sizeof (buf), fp))
1423 		{
1424 		  key_t key;
1425 		  PID_T lspid, lrpid;
1426 		  uid_t uid, cuid;
1427 		  gid_t gid, cgid;
1428 		  unsigned int perms, cbytes, qnum;
1429 		  int msqid;
1430 		  TIME_T stime, rtime, ctime;
1431 		  int items_read;
1432 
1433 		  items_read = sscanf (buf,
1434 				       "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
1435 				       &key, &msqid, &perms, &cbytes, &qnum,
1436 				       &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
1437 				       &stime, &rtime, &ctime);
1438 
1439 		  if (items_read == 14)
1440 		    {
1441 		      char user[UT_NAMESIZE], group[UT_NAMESIZE];
1442 		      char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1443 		      char lscmd[32], lrcmd[32];
1444 		      char stime_str[32], rtime_str[32], ctime_str[32];
1445 
1446 		      user_from_uid (user, sizeof (user), uid);
1447 		      group_from_gid (group, sizeof (group), gid);
1448 		      user_from_uid (cuser, sizeof (cuser), cuid);
1449 		      group_from_gid (cgroup, sizeof (cgroup), cgid);
1450 
1451 		      command_from_pid (lscmd, sizeof (lscmd), lspid);
1452 		      command_from_pid (lrcmd, sizeof (lrcmd), lrpid);
1453 
1454 		      time_from_time_t (stime_str, sizeof (stime_str), stime);
1455 		      time_from_time_t (rtime_str, sizeof (rtime_str), rtime);
1456 		      time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1457 
1458 		      buffer_xml_printf (
1459 			  &buffer,
1460 			  "<item>"
1461 			  "<column name=\"key\">%d</column>"
1462 			  "<column name=\"msqid\">%d</column>"
1463 			  "<column name=\"permissions\">%o</column>"
1464 			  "<column name=\"num used bytes\">%u</column>"
1465 			  "<column name=\"num messages\">%u</column>"
1466 			  "<column name=\"last msgsnd() command\">%s</column>"
1467 			  "<column name=\"last msgrcv() command\">%s</column>"
1468 			  "<column name=\"user\">%s</column>"
1469 			  "<column name=\"group\">%s</column>"
1470 			  "<column name=\"creator user\">%s</column>"
1471 			  "<column name=\"creator group\">%s</column>"
1472 			  "<column name=\"last msgsnd() time\">%s</column>"
1473 			  "<column name=\"last msgrcv() time\">%s</column>"
1474 			  "<column name=\"last msgctl() time\">%s</column>"
1475 			  "</item>",
1476 			  key,
1477 			  msqid,
1478 			  perms,
1479 			  cbytes,
1480 			  qnum,
1481 			  lscmd,
1482 			  lrcmd,
1483 			  user,
1484 			  group,
1485 			  cuser,
1486 			  cgroup,
1487 			  stime_str,
1488 			  rtime_str,
1489 			  ctime_str);
1490 		    }
1491 		}
1492 	    }
1493 	  while (!feof (fp));
1494 
1495 	  fclose (fp);
1496 	}
1497 
1498       buffer_grow_str0 (&buffer, "</osdata>\n");
1499       buf = buffer_finish (&buffer);
1500       len_avail = strlen (buf);
1501     }
1502 
1503   if (offset >= len_avail)
1504     {
1505       /* Done.  Get rid of the buffer.  */
1506       buffer_free (&buffer);
1507       buf = NULL;
1508       len_avail = 0;
1509       return 0;
1510     }
1511 
1512   if (len > len_avail - offset)
1513     len = len_avail - offset;
1514   memcpy (readbuf, buf + offset, len);
1515 
1516   return len;
1517 }
1518 
1519 /* Collect data about loaded kernel modules and write it into
1520    READBUF.  */
1521 
1522 static LONGEST
1523 linux_xfer_osdata_modules (gdb_byte *readbuf,
1524 			   ULONGEST offset, ULONGEST len)
1525 {
1526   static const char *buf;
1527   static LONGEST len_avail = -1;
1528   static struct buffer buffer;
1529 
1530   if (offset == 0)
1531     {
1532       FILE *fp;
1533 
1534       if (len_avail != -1 && len_avail != 0)
1535 	buffer_free (&buffer);
1536       len_avail = 0;
1537       buf = NULL;
1538       buffer_init (&buffer);
1539       buffer_grow_str (&buffer, "<osdata type=\"modules\">\n");
1540 
1541       fp = gdb_fopen_cloexec ("/proc/modules", "r");
1542       if (fp)
1543 	{
1544 	  char buf[8192];
1545 
1546 	  do
1547 	    {
1548 	      if (fgets (buf, sizeof (buf), fp))
1549 		{
1550 		  char *name, *dependencies, *status, *tmp;
1551 		  unsigned int size;
1552 		  unsigned long long address;
1553 		  int uses;
1554 
1555 		  name = strtok (buf, " ");
1556 		  if (name == NULL)
1557 		    continue;
1558 
1559 		  tmp = strtok (NULL, " ");
1560 		  if (tmp == NULL)
1561 		    continue;
1562 		  if (sscanf (tmp, "%u", &size) != 1)
1563 		    continue;
1564 
1565 		  tmp = strtok (NULL, " ");
1566 		  if (tmp == NULL)
1567 		    continue;
1568 		  if (sscanf (tmp, "%d", &uses) != 1)
1569 		    continue;
1570 
1571 		  dependencies = strtok (NULL, " ");
1572 		  if (dependencies == NULL)
1573 		    continue;
1574 
1575 		  status = strtok (NULL, " ");
1576 		  if (status == NULL)
1577 		    continue;
1578 
1579 		  tmp = strtok (NULL, "\n");
1580 		  if (tmp == NULL)
1581 		    continue;
1582 		  if (sscanf (tmp, "%llx", &address) != 1)
1583 		    continue;
1584 
1585 		  buffer_xml_printf (
1586 			&buffer,
1587 			"<item>"
1588 			"<column name=\"name\">%s</column>"
1589 			"<column name=\"size\">%u</column>"
1590 			"<column name=\"num uses\">%d</column>"
1591 			"<column name=\"dependencies\">%s</column>"
1592 			"<column name=\"status\">%s</column>"
1593 			"<column name=\"address\">%llx</column>"
1594 			"</item>",
1595 			name,
1596 			size,
1597 			uses,
1598 			dependencies,
1599 			status,
1600 			address);
1601 		}
1602 	    }
1603 	  while (!feof (fp));
1604 
1605 	  fclose (fp);
1606 	}
1607 
1608       buffer_grow_str0 (&buffer, "</osdata>\n");
1609       buf = buffer_finish (&buffer);
1610       len_avail = strlen (buf);
1611     }
1612 
1613   if (offset >= len_avail)
1614     {
1615       /* Done.  Get rid of the buffer.  */
1616       buffer_free (&buffer);
1617       buf = NULL;
1618       len_avail = 0;
1619       return 0;
1620     }
1621 
1622   if (len > len_avail - offset)
1623     len = len_avail - offset;
1624   memcpy (readbuf, buf + offset, len);
1625 
1626   return len;
1627 }
1628 
1629 struct osdata_type {
1630   const char *type;
1631   const char *title;
1632   const char *description;
1633   LONGEST (*getter) (gdb_byte *readbuf, ULONGEST offset, ULONGEST len);
1634 } osdata_table[] = {
1635   { "cpus", "CPUs", "Listing of all cpus/cores on the system",
1636     linux_xfer_osdata_cpus },
1637   { "files", "File descriptors", "Listing of all file descriptors",
1638     linux_xfer_osdata_fds },
1639   { "modules", "Kernel modules", "Listing of all loaded kernel modules",
1640     linux_xfer_osdata_modules },
1641   { "msg", "Message queues", "Listing of all message queues",
1642     linux_xfer_osdata_msg },
1643   { "processes", "Processes", "Listing of all processes",
1644     linux_xfer_osdata_processes },
1645   { "procgroups", "Process groups", "Listing of all process groups",
1646     linux_xfer_osdata_processgroups },
1647   { "semaphores", "Semaphores", "Listing of all semaphores",
1648     linux_xfer_osdata_sem },
1649   { "shm", "Shared-memory regions", "Listing of all shared-memory regions",
1650     linux_xfer_osdata_shm },
1651   { "sockets", "Sockets", "Listing of all internet-domain sockets",
1652     linux_xfer_osdata_isockets },
1653   { "threads", "Threads", "Listing of all threads",
1654     linux_xfer_osdata_threads },
1655   { NULL, NULL, NULL }
1656 };
1657 
1658 LONGEST
1659 linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
1660 			  ULONGEST offset, ULONGEST len)
1661 {
1662   if (!annex || *annex == '\0')
1663     {
1664       static const char *buf;
1665       static LONGEST len_avail = -1;
1666       static struct buffer buffer;
1667 
1668       if (offset == 0)
1669 	{
1670 	  int i;
1671 
1672 	  if (len_avail != -1 && len_avail != 0)
1673 	    buffer_free (&buffer);
1674 	  len_avail = 0;
1675 	  buf = NULL;
1676 	  buffer_init (&buffer);
1677 	  buffer_grow_str (&buffer, "<osdata type=\"types\">\n");
1678 
1679 	  for (i = 0; osdata_table[i].type; ++i)
1680 	    buffer_xml_printf (
1681 			       &buffer,
1682 			       "<item>"
1683 			       "<column name=\"Type\">%s</column>"
1684 			       "<column name=\"Description\">%s</column>"
1685 			       "<column name=\"Title\">%s</column>"
1686 			       "</item>",
1687 			       osdata_table[i].type,
1688 			       osdata_table[i].description,
1689 			       osdata_table[i].title);
1690 
1691 	  buffer_grow_str0 (&buffer, "</osdata>\n");
1692 	  buf = buffer_finish (&buffer);
1693 	  len_avail = strlen (buf);
1694 	}
1695 
1696       if (offset >= len_avail)
1697 	{
1698 	  /* Done.  Get rid of the buffer.  */
1699 	  buffer_free (&buffer);
1700 	  buf = NULL;
1701 	  len_avail = 0;
1702 	  return 0;
1703 	}
1704 
1705       if (len > len_avail - offset)
1706 	len = len_avail - offset;
1707       memcpy (readbuf, buf + offset, len);
1708 
1709       return len;
1710     }
1711   else
1712     {
1713       int i;
1714 
1715       for (i = 0; osdata_table[i].type; ++i)
1716 	{
1717 	  if (strcmp (annex, osdata_table[i].type) == 0)
1718 	    {
1719 	      gdb_assert (readbuf);
1720 
1721 	      return (osdata_table[i].getter) (readbuf, offset, len);
1722 	    }
1723 	}
1724 
1725       return 0;
1726     }
1727 }
1728 
1729