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