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