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