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