elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
elkscmd
/
sys_utils
/
ps.c
File editor
/* * ps.c * Copyright 1998 Alistair Riddoch * ajr@ecs.soton.ac.uk * * This file may be distributed under the terms of the GNU General Public * License v2, or at your option any later version. * * This is a small version of ps for use in the ELKS project. * Enhanced by Greg Haerr 17 Apr 2020 */ #define __KERNEL__ #include <linuxmt/ntty.h> /* for struct tty */ #undef __KERNEL__ #include <autoconf.h> /* for CONFIG_ options */ #include <linuxmt/mm.h> #include <linuxmt/mem.h> #include <linuxmt/major.h> #include <linuxmt/sched.h> #include <linuxmt/fixedpt.h> #include <arch/irq.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/types.h> #include <string.h> #include <dirent.h> #include <pwd.h> #include <getopt.h> #include <paths.h> #include <libgen.h> #define LINEARADDRESS(off, seg) ((off_t) (((off_t)seg << 4) + off)) #define MK_FP(seg,off) ((void __far *)((((unsigned long)(seg))<<16) | ((unsigned)(off)))) static int maxtasks; int memread(int fd, word_t off, word_t seg, void *buf, int size) { if (lseek(fd, LINEARADDRESS(off, seg), SEEK_SET) == -1) return 0; if (read(fd, buf, size) != size) return 0; return 1; } word_t getword(int fd, word_t off, word_t seg) { word_t word; if (!memread(fd, off, seg, &word, sizeof(word))) return 0; return word; } void process_name(int fd, unsigned int off, unsigned int seg) { word_t argc, argv; char buf[80]; argc = getword(fd, off, seg); while (argc-- > 0) { off += 2; argv = getword(fd, off, seg); if (!memread(fd, argv, seg, buf, sizeof(buf))) return; printf("%s ",buf); } } /* fast cached version of devname() */ char *dev_name(unsigned int minor) { struct dirent *d; dev_t ttydev = MKDEV(TTY_MAJOR, minor); static dev_t prevdev = -1; static DIR *fp = NULL; struct stat st; static char path[MAXNAMLEN+6] = _PATH_DEVSL; /* /dev/ */ #define NAMEOFF (sizeof(_PATH_DEVSL) - 1) if (prevdev == ttydev) return path+NAMEOFF+3; if (!fp) { if (!(fp = opendir(_PATH_DEV))) return "??"; } else rewinddir(fp); while ((d = readdir(fp)) != 0) { if (d->d_name[0] == '.') continue; if (strncmp(d->d_name, "tty", 3)) continue; strcpy(&path[NAMEOFF], d->d_name); if (!stat(path, &st) && st.st_rdev == ttydev) { prevdev = ttydev; return path+NAMEOFF+3; } } return "?"; } char *tty_name(int fd, unsigned int off, unsigned int seg) { off_t addr = ((off_t)seg << 4) + off; struct tty tty; if (off == 0) return ""; if (lseek(fd, addr, SEEK_SET) == -1) return "?"; if (read(fd, &tty, sizeof(tty)) != sizeof(tty)) return "?"; return dev_name(tty.minor); } int main(int argc, char **argv) { int c, fd; unsigned int j, ds, off; word_t cseg, dseg; struct passwd * pwent; int f_listall = 0; char *progname; int f_uptime; struct task_struct task_table; if ((progname = strrchr(argv[0], '/')) != NULL) progname++; else progname = argv[0]; f_uptime = !strcmp(progname, "uptime"); while ((c = getopt(argc, argv, "lu")) != -1) { switch (c) { case 'l': /* list all - CSEG/DSEG */ f_listall = 1; break; case 'u': /* uptime */ f_uptime = 1; break; default: printf("Usage: %s: [-lu]\n", progname); return 1; } } if ((fd = open("/dev/kmem", O_RDONLY)) < 0) { printf("no /dev/kmem\n"); return 1; } if (ioctl(fd, MEM_GETDS, &ds) < 0 || ioctl(fd, MEM_GETMAXTASKS, &maxtasks) < 0) { printf("no mem_getds\n"); return 1; } if (f_uptime) { jiff_t uptime; unsigned int upoff; if (ioctl(fd, MEM_GETUPTIME, &upoff) < 0) { printf("no mem_getuptime\n"); return 1; } jiff_t __far *puptime = MK_FP(ds, upoff); clr_irq(); uptime = *puptime; set_irq(); unsigned long n = uptime / HZ; int days = n / (24 * 3600L); n = n % (24 * 3600L); int hours = n / 3600L; n %= 3600; int minutes = n / 60 ; printf("up for %d days, %d hour%s, and %d minute%s\n", days, hours, hours == 1? "": "s", minutes, minutes == 1? "": "s"); return 0; } if (ioctl(fd, MEM_GETTASK, &off) < 0) { printf("no mem_gettask\n"); return 1; } printf(" PID"); if (f_listall) printf(" PPID"); printf(" GRP TTY USER STAT "); printf(f_listall? "TSK": "CPU"); printf(" "); if (f_listall) printf("CSEG DSEG "); printf(" HEAP FREE SIZE COMMAND\n"); for (j = 0; j < maxtasks; j++) { if (!memread(fd, off + j*sizeof(struct task_struct), ds, &task_table, sizeof(task_table))) { printf("no memread\n"); return 1; } switch (task_table.state) { case TASK_UNUSED: continue; case TASK_RUNNING: c = 'R'; break; case TASK_INTERRUPTIBLE: c = 'S'; break; case TASK_UNINTERRUPTIBLE: c = 's'; break; case TASK_STOPPED: c = 'T'; break; case TASK_ZOMBIE: c = 'Z'; break; case TASK_EXITING: c = 'E'; break; default: c = '?'; break; } if (task_table.kstack_magic != KSTACK_MAGIC) { printf("Recompile ps, mismatched task structure\n"); return 1; } pwent = getpwuid(task_table.uid); /* pid grp tty user stat*/ printf("%5d", task_table.pid); if (f_listall) printf(" %5d", task_table.ppid); printf(" %5d %4s %-8s%c ", task_table.pgrp, tty_name(fd, (unsigned int)task_table.tty, ds), (pwent ? pwent->pw_name : "unknown"), c); if (f_listall) printf("%3d ", j); else { /* Round up, then divide by 2 for %. Change if SAMP_FREQ not 2 */ unsigned long cpu_percent = (task_table.average + FIXED_HALF) >> 1; printf("%3d", FIXED_INT(cpu_percent)); } /* CSEG*/ cseg = (word_t)task_table.mm[SEG_CODE]; if (f_listall) printf(" %4x ", cseg? getword(fd, (word_t)cseg+offsetof(struct segment, base), ds): 0); /* DSEG*/ dseg = (word_t)task_table.mm[SEG_DATA]; if (f_listall) printf("%4x", dseg? getword(fd, (word_t)dseg+offsetof(struct segment, base), ds): 0); if (dseg) { /* heap*/ printf(" %5u ", (word_t)(task_table.t_endbrk - task_table.t_enddata)); /* free*/ printf("%5u ", (word_t)(task_table.t_regs.sp - task_table.t_endbrk)); /* stack*/ //printf("%5u ", (word_t)(task_table.t_begstack - task_table.t_regs.sp)); /* size*/ segext_t size = getword(fd, (word_t)cseg+offsetof(struct segment, size), ds) + getword(fd, (word_t)dseg+offsetof(struct segment, size), ds); printf("%6ld ", (long)size << 4); process_name(fd, task_table.t_begstack, task_table.t_regs.ss); } printf("\n"); } return 0; }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history