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