Fork me on GitHub

root/fs/procfs/data.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. data_proc_self
  2. data_proc_cmdline
  3. data_proc_cpuinfo
  4. data_proc_devices
  5. data_proc_dma
  6. data_proc_filesystems
  7. data_proc_interrupts
  8. data_proc_loadavg
  9. data_proc_locks
  10. data_proc_meminfo
  11. data_proc_mounts
  12. data_proc_partitions
  13. data_proc_rtc
  14. data_proc_stat
  15. data_proc_uptime
  16. data_proc_fullversion
  17. data_proc_domainname
  18. data_proc_filemax
  19. data_proc_filenr
  20. data_proc_hostname
  21. data_proc_inodemax
  22. data_proc_inodenr
  23. data_proc_osrelease
  24. data_proc_ostype
  25. data_proc_version
  26. data_proc_pid_cmdline
  27. data_proc_pid_cwd
  28. data_proc_pid_environ
  29. data_proc_pid_exe
  30. data_proc_pid_maps
  31. data_proc_pid_mountinfo
  32. data_proc_pid_root
  33. data_proc_pid_stat
  34. data_proc_pid_statm
  35. data_proc_pid_status

   1 /*
   2  * fiwix/fs/procfs/data.c
   3  *
   4  * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/kernel.h>
   9 #include <fiwix/system.h>
  10 #include <fiwix/types.h>
  11 #include <fiwix/process.h>
  12 #include <fiwix/cmos.h>
  13 #include <fiwix/dma.h>
  14 #include <fiwix/ide.h>
  15 #include <fiwix/fs.h>
  16 #include <fiwix/filesystems.h>
  17 #include <fiwix/devices.h>
  18 #include <fiwix/locks.h>
  19 #include <fiwix/mm.h>
  20 #include <fiwix/mman.h>
  21 #include <fiwix/fs_proc.h>
  22 #include <fiwix/cpu.h>
  23 #include <fiwix/pic.h>
  24 #include <fiwix/sched.h>
  25 #include <fiwix/timer.h>
  26 #include <fiwix/utsname.h>
  27 #include <fiwix/version.h>
  28 #include <fiwix/errno.h>
  29 #include <fiwix/stdio.h>
  30 #include <fiwix/string.h>
  31 
  32 #define FSHIFT16        16
  33 #define FIXED16_1       (1 << FSHIFT16)
  34 #define LOAD_INT(x)     ((x) >> FSHIFT16)
  35 #define LOAD_FRAC(x)    LOAD_INT(((x) & (FIXED16_1 - 1)) * 100)
  36 
  37 static const char *pstate[] = {
  38         "? (unused!)",
  39         "R (running)",
  40         "S (sleeping)",
  41         "Z (zombie)",
  42         "T (stopped)",
  43         "D (idle)",
  44 };
  45 
  46 /*
  47  * procfs root directory related functions
  48  * ---------------------------------------
  49  */
  50 int data_proc_self(char *buffer, __pid_t pid)
  51 {
  52         return sprintk(buffer, "%s", current->pidstr);
  53 }
  54 
  55 int data_proc_cmdline(char *buffer, __pid_t pid)
  56 {
  57         return sprintk(buffer, "%s\n", cmdline);
  58 }
  59 
  60 int data_proc_cpuinfo(char *buffer, __pid_t pid)
  61 {
  62         int size;
  63 
  64         size = sprintk(buffer, "processor       : 0\n");
  65         size += sprintk(buffer + size, "cpu family      : %d86\n", cpu_table.family <= 6 ? cpu_table.family : 6);
  66         if(cpu_table.model >= 0) {
  67                 size += sprintk(buffer + size, "model           : %d\n", cpu_table.model);
  68         } else {
  69                 size += sprintk(buffer + size, "model           : unknown\n");
  70         }
  71 
  72         if(cpu_table.vendor_id) {
  73                 size += sprintk(buffer + size, "vendor_id       : %s\n", cpu_table.vendor_id);
  74         }
  75         if(cpu_table.model_name) {
  76                 size += sprintk(buffer + size, "model name      : %s\n", cpu_table.model_name);
  77         }
  78         if(cpu_table.stepping >= 0) {
  79                 size += sprintk(buffer + size, "stepping        : %d\n", cpu_table.stepping);
  80         } else {
  81                 size += sprintk(buffer + size, "stepping        : unknown\n");
  82         }
  83 
  84         size += sprintk(buffer + size, "cpu MHz         : ");
  85         if(cpu_table.hz) {
  86                 size += sprintk(buffer + size, "%d.%d\n", (cpu_table.hz / 1000000), ((cpu_table.hz % 1000000) / 100000));
  87         } else {
  88                 size += sprintk(buffer + size, "unknown\n");
  89         }
  90         if(cpu_table.cache) {
  91                 size += sprintk(buffer + size, "cache size      : %s\n", cpu_table.cache);
  92         }
  93         size += sprintk(buffer + size, "cpuid           : %s\n", cpu_table.has_cpuid ? "yes" : "no");
  94         size += sprintk(buffer + size, "fpu             : %s\n", cpu_table.has_fpu ? "yes" : "no");
  95         size += get_cpu_flags(buffer, size);
  96         return size;
  97 }
  98 
  99 int data_proc_devices(char *buffer, __pid_t pid)
 100 {
 101         int n, size;
 102         struct device *d;
 103 
 104         size = sprintk(buffer, "Character devices:\n");
 105         for(n = 0; n < NR_CHRDEV; n++) {
 106                 d = chr_device_table[n];
 107                 while(d) {
 108                         size += sprintk(buffer + size, "%3d %s\n", d->major, d->name);
 109                         d = d->next;
 110                 }
 111         }
 112 
 113         size += sprintk(buffer + size, "\nBlock devices:\n");
 114         for(n = 0; n < NR_BLKDEV; n++) {
 115                 d = blk_device_table[n];
 116                 while(d) {
 117                         size += sprintk(buffer + size, "%3d %s\n", d->major, d->name);
 118                         d = d->next;
 119                 }
 120         }
 121         return size;
 122 }
 123 
 124 int data_proc_dma(char *buffer, __pid_t pid)
 125 {
 126         int n, size;
 127 
 128         size = 0;
 129         for(n = 0; n < DMA_CHANNELS; n++) {
 130                 if(dma_resources[n]) {
 131                         size += sprintk(buffer + size, "%2d: %s\n", n, dma_resources[n]);
 132                 }
 133         }
 134         return size;
 135 }
 136 
 137 int data_proc_filesystems(char *buffer, __pid_t pid)
 138 {
 139         int n, size;
 140         int nodev;
 141 
 142         size = 0;
 143         for(n = 0; n < NR_FILESYSTEMS; n++) {
 144                 if(filesystems_table[n].name) {
 145                         nodev = 0;
 146                         if(filesystems_table[n].fsop->flags != FSOP_REQUIRES_DEV) {
 147                                 nodev = 1;
 148                         }
 149                         size += sprintk(buffer + size, "%s %s\n", nodev ? "nodev" : "     ", filesystems_table[n].name);
 150                 }
 151         }
 152         return size;
 153 }
 154 
 155 int data_proc_interrupts(char *buffer, __pid_t pid)
 156 {
 157         struct interrupt *irq;
 158         int n, size;
 159 
 160         size = 0;
 161         for(n = 0; n < NR_IRQS; n++) {
 162                 if((irq = irq_table[n])) {
 163                         size += sprintk(buffer + size, "%3d: %9u %s", n, irq->ticks, irq->name);
 164                         while((irq = irq->next)) {
 165                                 size += sprintk(buffer + size, ",%s", irq->name);
 166                         }
 167                         size += sprintk(buffer + size, "\n");
 168                 }
 169         }
 170         size += sprintk(buffer + size, "SPU: %9u %s\n", kstat.sirqs, "Spurious interrupts");
 171         return size;
 172 }
 173 
 174 int data_proc_loadavg(char *buffer, __pid_t pid)
 175 {
 176         int a, b, c;
 177         int size;
 178         struct proc *p;
 179         int nrun = 0;
 180         int nprocs = 0;
 181 
 182         a = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
 183         b = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
 184         c = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
 185 
 186         FOR_EACH_PROCESS(p) {
 187                 nprocs++;
 188                 if(p->state == PROC_RUNNING) {
 189                         nrun++;
 190                 }
 191                 p = p->next;
 192         }
 193 
 194         size = sprintk(buffer, "%d.%02d %d.%02d %d.%02d %d/%d %d\n", LOAD_INT(a), LOAD_FRAC(a), LOAD_INT(b), LOAD_FRAC(b), LOAD_INT(c), LOAD_FRAC(c), nrun, nprocs, lastpid);
 195         return size;
 196 }
 197 
 198 int data_proc_locks(char *buffer, __pid_t pid)
 199 {
 200         int n, size;
 201         struct flock_file *ff;
 202 
 203         size = 0;
 204 
 205         for(n = 0; n < NR_FLOCKS; n++) {
 206                 ff = &flock_file_table[n];
 207                 if(ff->inode) {
 208                         size += sprintk(buffer + size, "%d: FLOCK  ADVISORY  %s ", n + 1, ff->type & LOCK_SH ? "READ " : "WRITE");
 209                         size += sprintk(buffer + size, "%d %x:%d:%d 0 EOF\n", ff->proc->pid, MAJOR(ff->inode->dev), MINOR(ff->inode->dev), ff->inode->inode);
 210                 }
 211         }
 212 
 213         return size;
 214 }
 215 
 216 int data_proc_meminfo(char *buffer, __pid_t pid)
 217 {
 218         struct page *pg;
 219         int n, size;
 220 
 221         kstat.shared = 0;
 222         for(n = 0; n < kstat.physical_pages; n++) {
 223                 pg = &page_table[n];
 224                 if(pg->flags & PAGE_RESERVED) {
 225                         continue;
 226                 }
 227                 if(!pg->count) {
 228                         continue;
 229                 }
 230                 kstat.shared += pg->count - 1;
 231         }
 232 
 233         size = 0;
 234         size += sprintk(buffer + size, "        total:    used:    free:  shared: buffers:  cached:\n");
 235         size += sprintk(buffer + size, "Mem:  %8u %8u %8u %8u %8u %8u\n", kstat.total_mem_pages << PAGE_SHIFT, (kstat.total_mem_pages << PAGE_SHIFT) - (kstat.free_pages << PAGE_SHIFT), kstat.free_pages << PAGE_SHIFT, kstat.shared * 1024, kstat.buffers * 1024, kstat.cached * 1024);
 236         size += sprintk(buffer + size, "Swap: %8u %8u %8u\n", 0, 0, 0);
 237         size += sprintk(buffer + size, "MemTotal: %9d kB\n", kstat.total_mem_pages << 2);
 238         size += sprintk(buffer + size, "MemFree:  %9d kB\n", kstat.free_pages << 2);
 239         size += sprintk(buffer + size, "MemShared:%9d kB\n", kstat.shared);
 240         size += sprintk(buffer + size, "Buffers:  %9d kB\n", kstat.buffers);
 241         size += sprintk(buffer + size, "Cached:   %9d kB\n", kstat.cached);
 242         size += sprintk(buffer + size, "SwapTotal:%9d kB\n", 0);
 243         size += sprintk(buffer + size, "SwapFree: %9d kB\n", 0);
 244         size += sprintk(buffer + size, "Dirty:    %9d kB\n", kstat.dirty);
 245         return size;
 246 }
 247 
 248 int data_proc_mounts(char *buffer, __pid_t pid)
 249 {
 250         int n, size;
 251         char *flag;
 252 
 253         size = 0;
 254         for(n = 0; n < NR_MOUNT_POINTS; n++) {
 255                 if(mount_table[n].used) {
 256                         if(mount_table[n].fs->fsop->flags != FSOP_KERN_MOUNT) {
 257                                 flag = "rw";
 258                                 if(mount_table[n].sb.flags & MS_RDONLY) {
 259                                         flag = "ro";
 260                                 }
 261                                 size += sprintk(buffer + size, "%s %s %s %s 0 0\n", mount_table[n].devname, mount_table[n].dirname, mount_table[n].fs->name, flag);
 262                         }
 263                 }
 264         }
 265         return size;
 266 }
 267 
 268 int data_proc_partitions(char *buffer, __pid_t pid)
 269 {
 270         int n, ctrl, drv, size;
 271         int minor, major;
 272         unsigned int blocks;
 273         struct ide *ide;
 274         struct ide_drv *drive;
 275 
 276         size = 0;
 277         size += sprintk(buffer + size, "major minor  #blocks  name\n\n");
 278 
 279         for(ctrl = 0; ctrl < NR_IDE_CTRLS; ctrl++) {
 280                 ide = &ide_table[ctrl];
 281                 for(drv = 0; drv < NR_IDE_DRVS; drv++) {
 282                         drive = &ide->drive[drv];
 283                         if(!drive->nr_sects) {
 284                                 continue;
 285                         }
 286                         if(drive->flags & DEVICE_IS_DISK) {
 287                                 major = (int)drive->major;
 288                                 minor = (int)drive->minor_shift;
 289                                 blocks = drive->nr_sects / 2;
 290                                 size += sprintk(buffer + size, "%4d  %4d  %9d %s\n", major, 0, blocks, drive->dev_name);
 291                                 for(n = 0; n < NR_PARTITIONS; n++) {
 292                                         if(drive->part_table[n].type) {
 293                                                 blocks = drive->part_table[n].nr_sects / 2;
 294                                                 size += sprintk(buffer + size, "%4d  %4d  %9u %s%d\n", major, (n + 1) << minor, blocks, drive->dev_name, n + 1);
 295                                         }
 296                                 }
 297                         }
 298                 }
 299         }
 300         return size;
 301 }
 302 
 303 int data_proc_rtc(char *buffer, __pid_t pid)
 304 {
 305         int size;
 306         short int sec, min, hour;
 307         short int day, month, year, century;
 308 
 309         sec = cmos_read_date(CMOS_SEC);
 310         min = cmos_read_date(CMOS_MIN);
 311         hour = cmos_read_date(CMOS_HOUR);
 312         day = cmos_read_date(CMOS_DAY);
 313         month = cmos_read_date(CMOS_MONTH);
 314         year = cmos_read_date(CMOS_YEAR);
 315         century = cmos_read_date(CMOS_CENTURY);
 316         year += century * 100;
 317 
 318         size = 0;
 319         size += sprintk(buffer + size, "rtc_time\t: %02d:%02d:%02d\n", hour, min, sec);
 320         size += sprintk(buffer + size, "rtc_date\t: %02d-%02d-%02d\n", year, month, day);
 321         sec = cmos_read_date(CMOS_ASEC);
 322         min = cmos_read_date(CMOS_AMIN);
 323         hour = cmos_read_date(CMOS_AHOUR);
 324         size += sprintk(buffer + size, "alarm\t\t: %02d:%02d:%02d\n", hour, min, sec);
 325         size += sprintk(buffer + size, "DST_enable\t: %s\n", cmos_read(CMOS_STATB) & CMOS_STATB_DSE ? "yes" : "no");
 326         size += sprintk(buffer + size, "BCD\t\t: %s\n", cmos_read(CMOS_STATB) & CMOS_STATB_DM ? "no" : "yes");
 327         size += sprintk(buffer + size, "24hr\t\t: %s\n", cmos_read(CMOS_STATB) & CMOS_STATB_24H ? "yes" : "no");
 328         size += sprintk(buffer + size, "square_wave\t: %s\n", cmos_read(CMOS_STATB) & CMOS_STATB_SQWE ? "yes" : "no");
 329         size += sprintk(buffer + size, "alarm_IRQ\t: %s\n", cmos_read(CMOS_STATB) & CMOS_STATB_AIE ? "yes" : "no");
 330         size += sprintk(buffer + size, "update_IRQ\t: %s\n", cmos_read(CMOS_STATB) & CMOS_STATB_UIE ? "yes" : "no");
 331         size += sprintk(buffer + size, "periodic_IRQ\t: %s\n", cmos_read(CMOS_STATB) & CMOS_STATB_PIE ? "yes" : "no");
 332         size += sprintk(buffer + size, "periodic_freq\t: %s\n", (cmos_read(CMOS_STATA) & CMOS_STATA_IRQF) == 0x6 ? "1024" : "?");
 333         size += sprintk(buffer + size, "batt_status\t: %s\n", cmos_read(CMOS_STATD) & CMOS_STATD_VRT ? "okay" : "dead");
 334         return size;
 335 }
 336 
 337 int data_proc_stat(char *buffer, __pid_t pid)
 338 {
 339         int n, size;
 340         unsigned int idle;
 341         struct interrupt *irq;
 342 
 343         idle = kstat.ticks - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system);
 344         size = 0;
 345         size += sprintk(buffer + size, "cpu %d %d %d %d\n", kstat.cpu_user, kstat.cpu_nice, kstat.cpu_system, idle);
 346         size += sprintk(buffer + size, "disk 0 0 0 0\n");
 347         size += sprintk(buffer + size, "page 0 0\n");
 348         size += sprintk(buffer + size, "swap 0 0\n");
 349         size += sprintk(buffer + size, "intr %u", kstat.irqs);
 350         for(n = 0; n < NR_IRQS; n++) {
 351                 irq = irq_table[n];
 352                 if(irq) {
 353                         size += sprintk(buffer + size, " %u", irq->ticks);
 354                 }
 355         }
 356         size += sprintk(buffer + size, "\n");
 357         size += sprintk(buffer + size, "ctxt %u\n", kstat.ctxt);
 358         size += sprintk(buffer + size, "btime %d\n", kstat.boot_time);
 359         size += sprintk(buffer + size, "processes %d\n", kstat.processes);
 360         return size;
 361 }
 362 
 363 int data_proc_uptime(char *buffer, __pid_t pid)
 364 {
 365         struct proc *p;
 366         unsigned long int idle;
 367 
 368         p = &proc_table[IDLE];
 369         idle = tv2ticks(&p->usage.ru_utime);
 370         idle += tv2ticks(&p->usage.ru_stime);
 371         return sprintk(buffer, "%u.%02u %u.%02u\n", kstat.uptime, kstat.ticks % HZ, idle / HZ, idle % HZ);
 372 }
 373 
 374 int data_proc_fullversion(char *buffer, __pid_t pid)
 375 {
 376         return sprintk(buffer, "Fiwix version %s %s\n", UTS_RELEASE, UTS_VERSION);
 377 }
 378 
 379 int data_proc_domainname(char *buffer, __pid_t pid)
 380 {
 381         return sprintk(buffer, "%s\n", sys_utsname.domainname);
 382 }
 383 
 384 int data_proc_filemax(char *buffer, __pid_t pid)
 385 {
 386         return sprintk(buffer, "%d\n", NR_OPENS);
 387 }
 388 
 389 int data_proc_filenr(char *buffer, __pid_t pid)
 390 {
 391         int n, nr;
 392 
 393         nr = 0;
 394         for(n = 1; n < NR_OPENS; n++) {
 395                 if(fd_table[n].count != 0) {
 396                         nr++;
 397                 }
 398         }
 399         return sprintk(buffer, "%d\n", nr);
 400 }
 401 
 402 int data_proc_hostname(char *buffer, __pid_t pid)
 403 {
 404         return sprintk(buffer, "%s\n", sys_utsname.nodename);
 405 }
 406 
 407 int data_proc_inodemax(char *buffer, __pid_t pid)
 408 {
 409         return sprintk(buffer, "%d\n", inode_table_size / sizeof(struct inode));
 410 }
 411 
 412 int data_proc_inodenr(char *buffer, __pid_t pid)
 413 {
 414         return sprintk(buffer, "%d\n", (inode_table_size / sizeof(struct inode)) - kstat.free_inodes);
 415 }
 416 
 417 int data_proc_osrelease(char *buffer, __pid_t pid)
 418 {
 419         return sprintk(buffer, "%s\n", UTS_RELEASE);
 420 }
 421 
 422 int data_proc_ostype(char *buffer, __pid_t pid)
 423 {
 424         return sprintk(buffer, "%s\n", UTS_SYSNAME);
 425 }
 426 
 427 int data_proc_version(char *buffer, __pid_t pid)
 428 {
 429         return sprintk(buffer, "%s\n", UTS_VERSION);
 430 }
 431 
 432 
 433 /*
 434  * PID directory related functions
 435  * -------------------------------
 436  */
 437 int data_proc_pid_cmdline(char *buffer, __pid_t pid)
 438 {
 439         int n, size;
 440         char *arg;
 441         char **argv;
 442         unsigned int addr, offset;
 443         struct proc *p;
 444 
 445         size = 0;
 446         if((p = get_proc_by_pid(pid))) {
 447                 for(n = 0; n < p->argc && (p->argv + n); n++) {
 448                         argv = p->argv + n;
 449                         offset = (int)argv & ~PAGE_MASK;
 450                         addr = get_mapped_addr(p, (int)argv) & PAGE_MASK;
 451                         addr = P2V(addr);
 452                         argv = (char **)(addr + offset);
 453                         offset = (int)argv[0] & ~PAGE_MASK;
 454                         addr = get_mapped_addr(p, (int)argv[0]) & PAGE_MASK;
 455                         addr = P2V(addr);
 456                         arg = (char *)(addr + offset);
 457                         if(size + strlen(arg) < (PAGE_SIZE - 1)) {
 458                                 size += sprintk(buffer + size, "%s", arg);
 459                                 buffer[size++] = NULL;
 460                         } else {
 461                                 break;
 462                         }
 463                 }
 464         }
 465         return size;
 466 }
 467 
 468 int data_proc_pid_cwd(char *buffer, __pid_t pid)
 469 {
 470         int size;
 471         struct proc *p;
 472         struct inode *i;
 473 
 474         size = 0;
 475         if((p = get_proc_by_pid(pid))) {
 476 
 477                 /* zombie processes don't have current working directory */
 478                 if(!p->pwd) {
 479                         return -ENOENT;
 480                 }
 481 
 482                 i = p->pwd;
 483                 size = sprintk(buffer, "[%02d%02d]:%d", MAJOR(i->rdev), MINOR(i->rdev), i->inode);
 484         }
 485         return size;
 486 }
 487 
 488 int data_proc_pid_environ(char *buffer, __pid_t pid)
 489 {
 490         int n, size;
 491         char *env;
 492         char **envp;
 493         unsigned int addr, offset;
 494         struct proc *p;
 495 
 496         size = 0;
 497         if((p = get_proc_by_pid(pid))) {
 498                 for(n = 0; n < p->envc && (p->envp + n); n++) {
 499                         envp = p->envp + n;
 500                         offset = (int)envp & ~PAGE_MASK;
 501                         addr = get_mapped_addr(p, (int)envp) & PAGE_MASK;
 502                         addr = P2V(addr);
 503                         envp = (char **)(addr + offset);
 504                         offset = (int)envp[0] & ~PAGE_MASK;
 505                         addr = get_mapped_addr(p, (int)envp[0]) & PAGE_MASK;
 506                         addr = P2V(addr);
 507                         env = (char *)(addr + offset);
 508                         if(size + strlen(env) < (PAGE_SIZE - 1)) {
 509                                 size += sprintk(buffer + size, "%s", env);
 510                                 buffer[size++] = NULL;
 511                         } else {
 512                                 break;
 513                         }
 514                 }
 515         }
 516         return size;
 517 }
 518 
 519 int data_proc_pid_exe(char *buffer, __pid_t pid)
 520 {
 521         int size;
 522         struct proc *p;
 523         struct inode *i;
 524 
 525         size = 0;
 526         if((p = get_proc_by_pid(pid))) {
 527 
 528                 /* kernel and zombie processes are programless */
 529                 if(!p->vma || !p->vma->inode) {
 530                         return -ENOENT;
 531                 }
 532 
 533                 i = p->vma->inode;
 534                 size = sprintk(buffer, "[%02d%02d]:%d", MAJOR(i->rdev), MINOR(i->rdev), i->inode);
 535         }
 536         return size;
 537 }
 538 
 539 int data_proc_pid_maps(char *buffer, __pid_t pid)
 540 {
 541         unsigned int n;
 542         int size, len;
 543         __ino_t inode;
 544         int major, minor;
 545         char *section;
 546         char r, w, x, f;
 547         struct proc *p;
 548         struct vma *vma;
 549 
 550         size = 0;
 551         if((p = get_proc_by_pid(pid))) {
 552                 if(!p->vma) {
 553                         return 0;
 554                 }
 555                 vma = p->vma;
 556                 for(n = 0; n < VMA_REGIONS && vma->start; n++, vma++) {
 557                         r = vma->prot & PROT_READ ? 'r' : '-';
 558                         w = vma->prot & PROT_WRITE ? 'w' : '-';
 559                         x = vma->prot & PROT_EXEC ? 'x' : '-';
 560                         if(vma->flags & MAP_SHARED) {
 561                                 f = 's';
 562                         } else if(vma->flags & MAP_PRIVATE) {
 563                                 f = 'p';
 564                         } else {
 565                                 f = '-';
 566                         }
 567                         switch(vma->s_type) {
 568                                 case P_TEXT:    section = "text";
 569                                                 break;
 570                                 case P_DATA:    section = "data";
 571                                                 break;
 572                                 case P_BSS:     section = "bss";
 573                                                 break;
 574                                 case P_HEAP:    section = "heap";
 575                                                 break;
 576                                 case P_STACK:   section = "stack";
 577                                                 break;
 578                                 case P_MMAP:    section = "mmap";
 579                                                 break;
 580                                 default:
 581                                         section = NULL;
 582                                         break;
 583                         }
 584                         inode = major = minor = 0;
 585                         if(vma->inode) {
 586                                 inode = vma->inode->inode;
 587                                 major = MAJOR(vma->inode->dev);
 588                                 minor = MINOR(vma->inode->dev);
 589                         }
 590                         len = sprintk(buffer + size, "%08x-%08x %c%c%c%c %08x %02d:%02d %- 10u [%s]\n", vma->start, vma->end, r, w, x, f, vma->offset, major, minor, inode, section);
 591                         size += len;
 592                 }
 593         }
 594         return size;
 595 }
 596 
 597 int data_proc_pid_mountinfo(char *buffer, __pid_t pid)
 598 {
 599         int n, size;
 600         char *flag, *devname;
 601 
 602         size = 0;
 603         for(n = 0; n < NR_MOUNT_POINTS; n++) {
 604                 if(mount_table[n].used) {
 605                         if(mount_table[n].fs->fsop->flags != FSOP_KERN_MOUNT) {
 606                                 flag = "rw";
 607                                 if(mount_table[n].sb.flags & MS_RDONLY) {
 608                                         flag = "ro";
 609                                 }
 610                                 devname = mount_table[n].devname;
 611                                 if(!strcmp(mount_table[n].devname, "/dev/root")) {
 612                                         devname = _rootdevname;
 613                                 }
 614                                 size += sprintk(buffer + size, "%d 0 %d:%d %s %s %s - %s %s %s\n", n, MAJOR(mount_table[n].dev), MINOR(mount_table[n].dev), "/", mount_table[n].dirname, flag, mount_table[n].fs->name, devname, flag);
 615                         }
 616                 }
 617         }
 618         return size;
 619 }
 620 
 621 int data_proc_pid_root(char *buffer, __pid_t pid)
 622 {
 623         int size;
 624         struct proc *p;
 625         struct inode *i;
 626 
 627         size = 0;
 628         if((p = get_proc_by_pid(pid))) {
 629 
 630                 /* zombie processes don't have root directory */
 631                 if(!p->root) {
 632                         return -ENOENT;
 633                 }
 634 
 635                 i = p->root;
 636                 size = sprintk(buffer, "[%02d%02d]:%d", MAJOR(i->rdev), MINOR(i->rdev), i->inode);
 637         }
 638         return size;
 639 }
 640 
 641 int data_proc_pid_stat(char *buffer, __pid_t pid)
 642 {
 643         int n, size, vma_start, vma_end;
 644         unsigned int esp, eip;
 645         int signum, mask;
 646         __sigset_t sigignored, sigcaught;
 647         struct proc *p;
 648         struct sigcontext *sc;
 649         struct vma *vma;
 650         int text, data, stack, mmap;
 651 
 652         size = text = data = stack = mmap = 0;
 653         if((p = get_proc_by_pid(pid))) {
 654                 if(!p->vma) {
 655                         return 0;
 656                 }
 657                 vma_start = p->vma[0].start;
 658                 vma_end = p->vma[0].end;
 659 
 660                 vma = p->vma;
 661                 for(n = 0; n < VMA_REGIONS && vma->start; n++, vma++) {
 662                         switch(vma->s_type) {
 663                                 case P_TEXT:
 664                                         text += vma->end - vma->start;
 665                                         break;
 666                                 case P_HEAP:
 667                                         data += vma->end - vma->start;
 668                                         break;
 669                                 case P_STACK:
 670                                         stack += vma->end - vma->start;
 671                                         break;
 672                                 case P_MMAP:
 673                                         mmap += vma->end - vma->start;
 674                                         break;
 675                         }
 676                 }
 677 
 678                 sigignored = sigcaught = 0;
 679                 for(signum = 0, mask = 1; signum < NSIG; signum++, mask <<= 1) {
 680                         if(p->sigaction[signum].sa_handler == SIG_IGN) {
 681                                 sigignored |= mask;
 682                         }
 683                         if(p->sigaction[signum].sa_handler == SIG_DFL) {
 684                                 sigcaught |= mask;
 685                         }
 686                 }
 687 
 688                 esp = eip = 0;
 689                 if(p->sp) {
 690                         sc = (struct sigcontext *)p->sp;
 691                         esp = sc->oldesp;
 692                         eip = sc->eip;
 693                 }
 694                 size = sprintk(buffer, "%d (%s) %c %d %d %d %d %d %d %d %d %d %d %u %u %u %u %d %d %d %d %d %d %u %u %u %u %u %u %u %d %d %u %u %u\n",
 695                 p->pid,
 696                 p->argv0,
 697                 pstate[p->state][0],
 698                 p->ppid, p->pgid, p->sid,
 699                 p->ctty ? p->ctty->dev : 0,
 700                 p->ctty ? p->ctty->pgid : - 1,
 701                 0,                      /* flags */
 702                 0, 0, 0, 0,             /* minflt, cminflt, majflt, cmajflt */
 703                 tv2ticks(&p->usage.ru_utime),
 704                 tv2ticks(&p->usage.ru_stime),
 705                 tv2ticks(&p->cusage.ru_utime),
 706                 tv2ticks(&p->cusage.ru_stime),
 707                 0,                      /* counter */
 708                 0,                      /* priority */
 709                 0,                      /* timeout */
 710                 0,                      /* itrealvalue */
 711                 p->start_time,
 712                 text + data + stack + mmap,
 713                 p->rss,
 714                 0x7FFFFFFF,             /* rlim */
 715                 vma_start,              /* startcode */
 716                 vma_end,                /* endcode */
 717                 KERNEL_BASE_ADDR - 1,   /* startstack */
 718                 esp,                    /* kstkesp */
 719                 eip,                    /* kstkeip */
 720                 p->sigpending,
 721                 p->sigblocked,
 722                 sigignored,
 723                 sigcaught,
 724                 p->sleep_address
 725                 );
 726         }
 727         return size;
 728 }
 729 
 730 int data_proc_pid_statm(char *buffer, __pid_t pid)
 731 {
 732         int n, size;
 733         struct proc *p;
 734         struct vma *vma;
 735         int text, data, stack, mmap;
 736 
 737         size = text = data = stack = mmap = 0;
 738         if((p = get_proc_by_pid(pid))) {
 739                 if(!p->vma) {
 740                         return 0;
 741                 }
 742                 vma = p->vma;
 743                 for(n = 0; n < VMA_REGIONS && vma->start; n++, vma++) {
 744                         switch(vma->s_type) {
 745                                 case P_TEXT:
 746                                         text += vma->end - vma->start;
 747                                         break;
 748                                 case P_HEAP:
 749                                         data += vma->end - vma->start;
 750                                         break;
 751                                 case P_STACK:
 752                                         stack += vma->end - vma->start;
 753                                         break;
 754                                 case P_MMAP:
 755                                         mmap += vma->end - vma->start;
 756                                         break;
 757                         }
 758                 }
 759 
 760                 size = sprintk(buffer, "%d", (text + data + stack + mmap) / PAGE_SIZE);
 761                 size += sprintk(buffer + size, " %d", p->rss);
 762                 size += sprintk(buffer + size, " 0");   /* shared mappings */
 763                 size += sprintk(buffer + size, " %d", text / PAGE_SIZE);
 764                 size += sprintk(buffer + size, " 0");
 765                 size += sprintk(buffer + size, " %d", (data + stack) / PAGE_SIZE);
 766                 size += sprintk(buffer + size, " 0\n");
 767         }
 768         return size;
 769 }
 770 
 771 int data_proc_pid_status(char *buffer, __pid_t pid)
 772 {
 773         int n, size;
 774         int signum, mask;
 775         __sigset_t sigignored, sigcaught;
 776         struct proc *p;
 777         struct vma *vma;
 778         int text, data, stack, mmap;
 779 
 780         size = text = data = stack = mmap = 0;
 781         if((p = get_proc_by_pid(pid))) {
 782                 if(!p->vma) {
 783                         return 0;
 784                 }
 785                 vma = p->vma;
 786                 for(n = 0; n < VMA_REGIONS && vma->start; n++, vma++) {
 787                         switch(vma->s_type) {
 788                                 case P_TEXT:
 789                                         text += vma->end - vma->start;
 790                                         break;
 791                                 case P_HEAP:
 792                                         data += vma->end - vma->start;
 793                                         break;
 794                                 case P_STACK:
 795                                         stack += vma->end - vma->start;
 796                                         break;
 797                                 case P_MMAP:
 798                                         mmap += vma->end - vma->start;
 799                                         break;
 800                         }
 801                 }
 802 
 803                 size = sprintk(buffer, "Name:\t%s\n", p->argv0);
 804                 size += sprintk(buffer + size, "State:\t%s\n", pstate[p->state]);
 805                 size += sprintk(buffer + size, "Pid:\t%d\n", p->pid);
 806                 size += sprintk(buffer + size, "PPid:\t%d\n", p->ppid);
 807                 size += sprintk(buffer + size, "Uid:\t%d\t%d\t%d\t-\n", p->uid, p->euid, p->suid);
 808                 size += sprintk(buffer + size, "Gid:\t%d\t%d\t%d\t-\n", p->gid, p->egid, p->sgid);
 809                 size += sprintk(buffer + size, "VmSize:\t%8d kB\n", (text + data + stack + mmap) / 1024);
 810                 size += sprintk(buffer + size, "VmLck:\t%8d kB\n", 0);
 811                 size += sprintk(buffer + size, "VmRSS:\t%8d kB\n", p->rss << 2);
 812                 size += sprintk(buffer + size, "VmData:\t%8d kB\n", data / 1024);
 813                 size += sprintk(buffer + size, "VmStk:\t%8d kB\n", stack / 1024);
 814                 size += sprintk(buffer + size, "VmExe:\t%8d kB\n", text / 1024);
 815                 size += sprintk(buffer + size, "VmLib:\t%8d kB\n", 0);
 816                 size += sprintk(buffer + size, "SigPnd:\t%08x\n", p->sigpending);
 817                 size += sprintk(buffer + size, "SigBlk:\t%08x\n", p->sigblocked);
 818                 sigignored = sigcaught = 0;
 819                 for(signum = 0, mask = 1; signum < NSIG; signum++, mask <<= 1) {
 820                         if(p->sigaction[signum].sa_handler == SIG_IGN) {
 821                                 sigignored |= mask;
 822                         }
 823                         if(p->sigaction[signum].sa_handler == SIG_DFL) {
 824                                 sigcaught |= mask;
 825                         }
 826                 }
 827                 size += sprintk(buffer + size, "SigIgn:\t%08x\n", sigignored);
 828                 size += sprintk(buffer + size, "SigCgt:\t%08x\n", sigcaught);
 829         }
 830         return size;
 831 }

/* [previous][next][first][last][top][bottom][index][help] */