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