.include <bsd.own.mk>
PROG= procfs
-SRCS= buf.c main.c pid.c root.c tree.c util.c cpuinfo.c
+SRCS= buf.c cpuinfo.c main.c pid.c root.c tree.c util.c
CPPFLAGS+= -I${NETBSDSRCDIR}/minix
CPPFLAGS+= -I${NETBSDSRCDIR}/minix/fs
-/* ProcFS - buf.c - by Alen Stojanov and David van Moolenbroek */
+/* ProcFS - buf.c - output buffer management for read calls */
#include "inc.h"
#include <stdarg.h>
static size_t left, used;
static off_t skip;
-/*===========================================================================*
- * buf_init *
- *===========================================================================*/
-void buf_init(char *ptr, size_t len, off_t start)
+/*
+ * Initialize the buffer for fresh use. The output is to be stored into 'ptr'
+ * which is BUF_SIZE bytes in size, since that is the size we requested. Due
+ * to the way vsnprintf works, we cannot use the last byte of this buffer. The
+ * first 'start' bytes of the produced output are to be skipped. After that, a
+ * total of 'len' bytes are requested.
+ */
+void
+buf_init(char * ptr, size_t len, off_t start)
{
- /* Initialize the buffer for fresh use. The output is to be stored into
- * 'ptr' which is BUF_SIZE bytes in size, since that is the size we
- * requested. Due to the way vsnprintf works, we cannot use the last
- * byte of this buffer. The first 'start' bytes of the produced output
- * are to be skipped. After that, a total of 'len' bytes are requested.
- */
buf = ptr;
skip = start;
used = 0;
}
-/*===========================================================================*
- * buf_printf *
- *===========================================================================*/
-void buf_printf(char *fmt, ...)
+/*
+ * Add formatted text to the end of the buffer.
+ */
+void
+buf_printf(char * fmt, ...)
{
- /* Add formatted text to the end of the buffer.
- */
va_list args;
ssize_t len, max;
if (left == 0)
return;
- /* There is no way to estimate how much space the result will take, so
+ /*
+ * There is no way to estimate how much space the result will take, so
* we need to produce the string even when skipping part of the start.
* The null terminating character is not part of the result, so room
* must be given for it to be stored after completely filling up the
len = vsnprintf(&buf[used], max, fmt, args);
va_end(args);
- /* The snprintf family returns the number of bytes that would be stored
+ /*
+ * The snprintf family returns the number of bytes that would be stored
* if the buffer were large enough, excluding the null terminator.
*/
if (len >= BUF_SIZE)
assert(len >= 0);
assert((ssize_t) left >= 0);
- if (len > (ssize_t) left)
+ if (len > (ssize_t)left)
len = left;
used += len;
left -= len;
}
-/*===========================================================================*
- * buf_append *
- *===========================================================================*/
-void buf_append(char *data, size_t len)
+/*
+ * Add arbitrary data to the end of the buffer.
+ */
+void
+buf_append(char * data, size_t len)
{
- /* Add arbitrary data to the end of the buffer.
- */
if (left == 0)
return;
if (skip > 0) {
- if (skip >= (ssize_t) len) {
+ if (skip >= (ssize_t)len) {
skip -= len;
return;
left -= len;
}
-/*===========================================================================*
- * buf_result *
- *===========================================================================*/
-ssize_t buf_result(void)
+/*
+ * Return the resulting number of bytes produced, not counting the trailing
+ * null character in the buffer.
+ */
+ssize_t
+buf_result(void)
{
- /* Return the resulting number of bytes produced, not counting the
- * trailing null character in the buffer.
- */
return used;
}
#ifndef _PROCFS_CONST_H
#define _PROCFS_CONST_H
-/* The minimum number of inodes depends on a number of factors:
- * - Each statically created inode (e.g., /proc/hz) needs an inode. As of
+/*
+ * The minimum number of inodes depends on a number of factors:
+ * - Each statically created inode (e.g., /proc/hz) needs an inode. As of
* writing, this requires about a dozen inodes.
- * - Deleted inodes that are still in use by VFS must be retained. For deleted
+ * - Deleted inodes that are still in use by VFS must be retained. For deleted
* directories, all their containing directories up to the root must be
- * retained as well (to allow the user to "cd .." out). VTreeFS already takes
- * care of this. In the case of ProcFS, only PID-based directories can be
- * deleted; no other directories are dynamically created. These directories
- * currently do not contain subdirectories, either. Hence, for deleted open
- * inodes, we need to reserve at most NR_VNODES inodes in the worst case.
+ * retained as well (to allow the user to "cd .." out). VTreeFS already
+ * takes care of this. In the case of ProcFS, only PID-based directories can
+ * be deleted; no other directories are dynamically created. These
+ * directories currently do not contain subdirectories, either. Hence, for
+ * deleted open inodes, we need to reserve at most NR_VNODES inodes in the
+ * worst case.
* - In order for getdents to be able to return all PID-based directories,
* inodes must not be recycled while generating the list of these PID-based
- * directories. In the worst case, this means (NR_TASKS + NR_PROCS) extra
+ * directories. In the worst case, this means (NR_TASKS + NR_PROCS) extra
* inodes.
* The sum of these is the bare minimum for correct operation in all possible
- * circumstances. In practice, not all open files will be deleted files in
+ * circumstances. In practice, not all open files will be deleted files in
* ProcFS, and not all process slots will be in use either, so the average use
- * will be a lot less. However, setting the value too low allows for a
+ * will be a lot less. However, setting the value too low allows for a
* potential denial-of-service attack by a non-root user.
*
* For the moment, we simply set this value to something reasonable.
+/* ProcFS - cpuinfo.c - generator for the cpuinfo file */
+
#include "inc.h"
+
#if defined(__i386__)
#include "../../kernel/arch/i386/include/archconst.h"
#endif
"",
};
-static void print_x86_cpu_flags(u32_t * flags)
+/*
+ * Output a space-separated list of supported CPU flags. x86 only.
+ */
+static void
+print_x86_cpu_flags(u32_t * flags)
{
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 32; j++) {
- if (flags[i] & (1 << j) &&
- x86_flag[i * 32 + j][0])
+ if (flags[i] & (1 << j) && x86_flag[i * 32 + j][0])
buf_printf("%s ", x86_flag[i * 32 + j]);
}
}
}
#endif
-static void print_cpu(struct cpu_info * cpu_info, unsigned id)
+/*
+ * Print information for a single CPU.
+ */
+static void
+print_cpu(struct cpu_info * cpu_info, unsigned id)
{
+
buf_printf("%-16s: %d\n", "processor", id);
#if defined(__i386__)
switch (cpu_info->vendor) {
- case CPU_VENDOR_INTEL:
- buf_printf("%-16s: %s\n", "vendor_id", "GenuineIntel");
- buf_printf("%-16s: %s\n", "model name", "Intel");
- break;
- case CPU_VENDOR_AMD:
- buf_printf("%-16s: %s\n", "vendor_id", "AuthenticAMD");
- buf_printf("%-16s: %s\n", "model name", "AMD");
- break;
- default:
- buf_printf("%-16: %s\n", "vendor_id", "unknown");
+ case CPU_VENDOR_INTEL:
+ buf_printf("%-16s: %s\n", "vendor_id", "GenuineIntel");
+ buf_printf("%-16s: %s\n", "model name", "Intel");
+ break;
+ case CPU_VENDOR_AMD:
+ buf_printf("%-16s: %s\n", "vendor_id", "AuthenticAMD");
+ buf_printf("%-16s: %s\n", "model name", "AMD");
+ break;
+ default:
+ buf_printf("%-16s: %s\n", "vendor_id", "unknown");
}
buf_printf("%-16s: %d\n", "cpu family", cpu_info->family);
#endif
}
-void root_cpuinfo(void)
+/*
+ * Generate the contents of /proc/cpuinfo.
+ */
+void
+root_cpuinfo(void)
{
struct cpu_info cpu_info[CONFIG_MAX_CPUS];
struct machine machine;
- unsigned c;
+ unsigned int c;
if (sys_getmachine(&machine)) {
printf("PROCFS: cannot get machine\n");
return;
}
if (sys_getcpuinfo(&cpu_info)) {
- printf("PROCFS: cannot get cpu info\n");
+ printf("PROCFS: cannot get CPU info\n");
return;
}
+++ /dev/null
-#ifndef __PROCFS_CPUINFO_H__
-#define __PROCFS_CPUINFO_H__
-
-void root_cpuinfo(void);
-
-#endif /* __PROCFS_CPUINFO_H__ */
#ifndef _PROCFS_INC_H
#define _PROCFS_INC_H
-#define _SYSTEM 1
-
-#include <minix/config.h>
-#include <limits.h>
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <lib.h>
-#include <minix/timers.h>
-#include <sys/dirent.h>
-
-#include <minix/callnr.h>
-#include <minix/type.h>
-#include <minix/const.h>
-#include <minix/com.h>
-#include <minix/syslib.h>
-#include <minix/sysutil.h>
-#include <minix/bitmap.h>
-#include <minix/vfsif.h>
-#include <minix/endpoint.h>
+#include <minix/drivers.h>
#include <minix/sysinfo.h>
-#include <minix/u64.h>
-#include <minix/sysinfo.h>
-#include <minix/type.h>
-#include <minix/ipc.h>
-
-#include <sys/utsname.h>
-#include <sys/time.h>
-#include <sys/times.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
+#include <minix/vtreefs.h>
+#include <minix/procfs.h>
+#include <assert.h>
#include <machine/archtypes.h>
#include "kernel/const.h"
#include "vfs/fproc.h"
#include "vfs/dmap.h"
-#include <minix/vtreefs.h>
-#include <minix/procfs.h>
-
#include "const.h"
#include "type.h"
#include "proto.h"
-/* ProcFS - main.c - by Alen Stojanov and David van Moolenbroek */
+/* ProcFS - main.c - main functions of the process file system */
#include "inc.h"
-#include "cpuinfo.h"
static void init_hook(void);
.rdlink_hook = rdlink_hook,
};
-/*===========================================================================*
- * construct_tree *
- *===========================================================================*/
-static void construct_tree(struct inode *dir, struct file *files)
+/*
+ * Construct a tree of static files from a null-terminated array of file
+ * structures, recursively creating directories which have their associated
+ * data point to child file structures.
+ */
+static void
+construct_tree(struct inode * dir, struct file * files)
{
- /* Construct a tree of static files from a null-terminated array of
- * file structures, recursively creating directories which have their
- * associated data point to child file structures.
- */
struct file *file;
struct inode *node;
struct inode_stat stat;
for (file = files; file->name != NULL; file++) {
stat.mode = file->mode;
- node = add_inode(dir, file->name, NO_INDEX, &stat, (index_t) 0,
- (cbdata_t) file->data);
+ node = add_inode(dir, file->name, NO_INDEX, &stat, (index_t)0,
+ (cbdata_t)file->data);
assert(node != NULL);
if (S_ISDIR(file->mode))
- construct_tree(node, (struct file *) file->data);
+ construct_tree(node, (struct file *)file->data);
}
}
-/*===========================================================================*
- * init_hook *
- *===========================================================================*/
-static void init_hook(void)
+/*
+ * Initialization hook. Generate the static part of the tree.
+ */
+static void
+init_hook(void)
{
- /* Initialization hook. Generate the static part of the tree.
- */
static int first_time = 1;
struct inode *root;
}
}
-/*===========================================================================*
- * main *
- *===========================================================================*/
+/*
+ * ProcFS entry point.
+ */
int main(void)
{
- /* ProcFS entry point.
- */
struct inode_stat stat;
int r;
- /* Initialize some state. If we are incompatible with the kernel, exit
+ /*
+ * Initialize some state. If we are incompatible with the kernel, exit
* immediately.
*/
if ((r = init_tree()) != OK)
-/* ProcFS - pid.c - by Alen Stojanov and David van Moolenbroek */
+/* ProcFS - pid.c - generators for PID-specific files */
#include "inc.h"
static void pid_environ(int slot);
static void pid_map(int slot);
-/* The files that are dynamically created in each PID directory. The data field
- * contains each file's read function. Subdirectories are not yet supported.
+/*
+ * The files that are dynamically created in each PID directory. The data
+ * field contains each file's read function. Subdirectories are not yet
+ * supported.
*/
struct file pid_files[] = {
{ "psinfo", REG_ALL_MODE, (data_t) pid_psinfo },
{ NULL, 0, (data_t) NULL }
};
-/*===========================================================================*
- * is_zombie *
- *===========================================================================*/
-static int is_zombie(int slot)
+/*
+ * Is the given slot a zombie process?
+ */
+static int
+is_zombie(int slot)
{
- /* Is the given slot a zombie process?
- */
return (slot >= NR_TASKS &&
(mproc[slot - NR_TASKS].mp_flags & (TRACE_ZOMBIE | ZOMBIE)));
}
-/*===========================================================================*
- * pid_psinfo *
- *===========================================================================*/
-static void pid_psinfo(int i)
+/*
+ * Print information used by ps(1) and top(1).
+ */
+static void
+pid_psinfo(int i)
{
- /* Print information used by ps(1) and top(1).
- */
int pi, task, state, type, p_state, f_state;
char name[PROC_NAME_LEN+1], *p;
struct vm_usage_info vui;
else if (proc[i].p_rts_flags == 0)
state = STATE_RUN; /* in run-queue */
else if (fp_is_blocked(&fproc[pi]) ||
- (mproc[pi].mp_flags & (WAITING | SIGSUSPENDED)))
+ (mproc[pi].mp_flags & (WAITING | SIGSUSPENDED)))
state = STATE_SLEEP; /* sleeping */
else
state = STATE_WAIT; /* waiting */
}
/* We assume that even if a process has become a zombie, its kernel
- * proc entry still contains the old (but valid) information. Currently
- * this is true, but in the future we may have to filter some fields.
+ * proc entry still contains the old (although valid) information.
+ * Currently this is true, but in the future we may have to filter some
+ * fields.
*/
buf_printf("%d %c %d %s %c %d %d %lu %lu %lu %lu",
- PSINFO_VERSION, /* information version */
- type, /* process type */
- (int) proc[i].p_endpoint, /* process endpoint */
- name, /* process name */
- state, /* process state letter */
- (int) P_BLOCKEDON(&proc[i]), /* endpt blocked on, or NONE */
- (int) proc[i].p_priority, /* process priority */
- (long) proc[i].p_user_time, /* user time */
- (long) proc[i].p_sys_time, /* system time */
- ex64hi(proc[i].p_cycles), /* execution cycles */
- ex64lo(proc[i].p_cycles)
+ PSINFO_VERSION, /* information version */
+ type, /* process type */
+ (int)proc[i].p_endpoint, /* process endpoint */
+ name, /* process name */
+ state, /* process state letter */
+ (int)P_BLOCKEDON(&proc[i]), /* endpt blocked on, or NONE */
+ (int)proc[i].p_priority, /* process priority */
+ (long)proc[i].p_user_time, /* user time */
+ (long)proc[i].p_sys_time, /* system time */
+ ex64hi(proc[i].p_cycles), /* execution cycles */
+ ex64lo(proc[i].p_cycles)
);
memset(&vui, 0, sizeof(vui));
if (!is_zombie(i)) {
/* We don't care if this fails. */
- (void) vm_info_usage(proc[i].p_endpoint, &vui);
+ (void)vm_info_usage(proc[i].p_endpoint, &vui);
}
/* If the process is not a kernel task, we add some extra info. */
default: f_state = FSTATE_UNKNOWN;
}
- buf_printf(" %lu %lu %lu %c %d %u %u %u %d %c %d %u",
- vui.vui_total, /* total memory */
- vui.vui_common, /* common memory */
- vui.vui_shared, /* shared memory */
- p_state, /* sleep state */
- ppid, /* parent PID */
- mproc[pi].mp_realuid, /* real UID */
- mproc[pi].mp_effuid, /* effective UID */
- mproc[pi].mp_procgrp, /* process group */
- mproc[pi].mp_nice, /* nice value */
- f_state, /* VFS block state */
- (int) (fproc[pi].fp_blocked_on == FP_BLOCKED_ON_OTHER)
- ? fproc[pi].fp_task : NONE, /* block proc */
- fproc[pi].fp_tty /* controlling tty */
+ buf_printf(" %lu %lu %lu %c %d %u %u %u %d %c %d %llu",
+ vui.vui_total, /* total memory */
+ vui.vui_common, /* common memory */
+ vui.vui_shared, /* shared memory */
+ p_state, /* sleep state */
+ ppid, /* parent PID */
+ mproc[pi].mp_realuid, /* real UID */
+ mproc[pi].mp_effuid, /* effective UID */
+ mproc[pi].mp_procgrp, /* process group */
+ mproc[pi].mp_nice, /* nice value */
+ f_state, /* VFS block state */
+ (int)(fproc[pi].fp_blocked_on == FP_BLOCKED_ON_OTHER) ?
+ fproc[pi].fp_task : NONE, /* block proc */
+ fproc[pi].fp_tty /* controlling tty */
);
}
- /* always add kernel cycles */
+ /* Always add kernel cycles. */
buf_printf(" %lu %lu %lu %lu",
- ex64hi(proc[i].p_kipc_cycles),
- ex64lo(proc[i].p_kipc_cycles),
- ex64hi(proc[i].p_kcall_cycles),
- ex64lo(proc[i].p_kcall_cycles));
+ ex64hi(proc[i].p_kipc_cycles),
+ ex64lo(proc[i].p_kipc_cycles),
+ ex64hi(proc[i].p_kcall_cycles),
+ ex64lo(proc[i].p_kcall_cycles));
- /* add total memory for tasks at the end */
- if(task) buf_printf(" %lu", vui.vui_total);
+ /* Add total memory for tasks at the end. */
+ if (task)
+ buf_printf(" %lu", vui.vui_total);
/* Newline at the end of the file. */
buf_printf("\n");
}
-/*===========================================================================*
- * put_frame *
- *===========================================================================*/
-static void put_frame(void)
+/*
+ * If we allocated memory dynamically during a call to get_frame(), free it up
+ * here.
+ */
+static void
+put_frame(void)
{
- /* If we allocated memory dynamically during a call to get_frame(),
- * free it up here.
- */
if (frame != s_frame)
free(frame);
}
-/*===========================================================================*
- * get_frame *
- *===========================================================================*/
-static int get_frame(int slot, vir_bytes *basep, vir_bytes *sizep,
- size_t *nargsp)
+/*
+ * Get the execution frame from the top of the given process's stack. It may
+ * be very large, in which case we temporarily allocate memory for it (up to a
+ * certain size).
+ */
+static int
+get_frame(int slot, vir_bytes * basep, vir_bytes * sizep, size_t * nargsp)
{
- /* Get the execution frame from the top of the given process's stack.
- * It may be very large, in which case we temporarily allocate memory
- * for it (up to a certain size).
- */
vir_bytes base, size;
size_t nargs;
if (proc[slot].p_nr < 0 || is_zombie(slot))
return FALSE;
- /* Get the frame base address and size. Limit the size to whatever we
- * can handle. If our static buffer is not sufficiently large to store
- * the entire frame, allocate memory dynamically. It is then later
+ /*
+ * Get the frame base address and size. Limit the size to whatever we
+ * can handle. If our static buffer is not sufficiently large to store
+ * the entire frame, allocate memory dynamically. It is then later
* freed by put_frame().
*/
base = mproc[slot - NR_TASKS].mp_frame_addr;
if (frame == NULL)
return FALSE;
- }
- else frame = s_frame;
+ } else
+ frame = s_frame;
/* Copy in the complete process frame. */
- if (sys_datacopy(proc[slot].p_endpoint, base,
- SELF, (vir_bytes) frame, (phys_bytes) size) != OK) {
+ if (sys_datacopy(proc[slot].p_endpoint, base, SELF, (vir_bytes)frame,
+ (phys_bytes)size) != OK) {
put_frame();
return FALSE;
frame[size] = 0; /* terminate any last string */
- nargs = * (size_t *) frame;
- if (nargs < 1 || sizeof(size_t) + sizeof(char *) * (nargs + 1) > size) {
+ nargs = *(size_t *)frame;
+ if (nargs < 1 ||
+ sizeof(size_t) + sizeof(char *) * (nargs + 1) > size) {
put_frame();
return FALSE;
return TRUE;
}
-/*===========================================================================*
- * pid_cmdline *
- *===========================================================================*/
-static void pid_cmdline(int slot)
+/*
+ * Dump the process's command line as it is contained in the process itself.
+ * Each argument is terminated with a null character.
+ */
+static void
+pid_cmdline(int slot)
{
- /* Dump the process's command line as it is contained in the process
- * itself. Each argument is terminated with a null character.
- */
vir_bytes base, size, ptr;
size_t i, len, nargs;
char **argv;
if (!get_frame(slot, &base, &size, &nargs))
return;
- argv = (char **) &frame[sizeof(size_t)];
+ argv = (char **)&frame[sizeof(size_t)];
for (i = 0; i < nargs; i++) {
- ptr = (vir_bytes) argv[i] - base;
+ ptr = (vir_bytes)argv[i] - base;
/* Check for bad pointers. */
- if ((long) ptr < 0L || ptr >= size)
+ if ((long)ptr < 0L || ptr >= size)
break;
len = strlen(&frame[ptr]) + 1;
put_frame();
}
-/*===========================================================================*
- * pid_environ *
- *===========================================================================*/
-static void pid_environ(int slot)
+/*
+ * Dump the process's initial environment as it is contained in the process
+ * itself. Each entry is terminated with a null character.
+ */
+static void
+pid_environ(int slot)
{
- /* Dump the process's initial environment as it is contained in the
- * process itself. Each entry is terminated with a null character.
- */
vir_bytes base, size, ptr;
size_t nargs, off, len;
char **envp;
return;
off = sizeof(size_t) + sizeof(char *) * (nargs + 1);
- envp = (char **) &frame[off];
+ envp = (char **)&frame[off];
for (;;) {
/* Make sure there is no buffer overrun. */
ptr -= base;
/* Check for bad pointers. */
- if ((long) ptr < 0L || ptr >= size)
+ if ((long)ptr < 0L || ptr >= size)
break;
len = strlen(&frame[ptr]) + 1;
put_frame();
}
-/*===========================================================================*
- * dump_regions *
- *===========================================================================*/
-static int dump_regions(int slot)
+/*
+ * Print the virtual memory regions of a process.
+ */
+static void
+dump_regions(int slot)
{
- /* Print the virtual memory regions of a process.
- */
struct vm_region_info vri[MAX_VRI_COUNT];
vir_bytes next;
int i, r, count;
do {
r = vm_info_region(proc[slot].p_endpoint, vri, MAX_VRI_COUNT,
- &next);
+ &next);
- if (r < 0)
- return r;
-
- if (r == 0)
+ if (r <= 0)
break;
for (i = 0; i < r; i++) {
buf_printf("%08lx-%08lx %c%c%c\n",
- vri[i].vri_addr, vri[i].vri_addr + vri[i].vri_length,
- (vri[i].vri_prot & PROT_READ) ? 'r' : '-',
- (vri[i].vri_prot & PROT_WRITE) ? 'w' : '-',
- (vri[i].vri_prot & PROT_EXEC) ? 'x' : '-');
+ vri[i].vri_addr,
+ vri[i].vri_addr + vri[i].vri_length,
+ (vri[i].vri_prot & PROT_READ) ? 'r' : '-',
+ (vri[i].vri_prot & PROT_WRITE) ? 'w' : '-',
+ (vri[i].vri_prot & PROT_EXEC) ? 'x' : '-');
count++;
}
} while (r == MAX_VRI_COUNT);
-
- return count;
}
-/*===========================================================================*
- * pid_map *
- *===========================================================================*/
-static void pid_map(int slot)
+/*
+ * Print a memory map of the process. Obtain the information from VM.
+ */
+static void
+pid_map(int slot)
{
- /* Print a memory map of the process. Obtain the information from VM if
- * possible; otherwise fall back on segments from the kernel.
- */
/* Zombies have no memory. */
if (is_zombie(slot))
return;
/* Kernel tasks also have no memory. */
- if (proc[slot].p_nr >= 0) {
- if (dump_regions(slot) != 0)
- return;
- }
+ if (proc[slot].p_nr >= 0)
+ dump_regions(slot);
}
/* buf.c */
void buf_init(char *ptr, size_t len, off_t start);
-void buf_printf(char *fmt, ...);
+void buf_printf(char *fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
void buf_append(char *data, size_t len);
ssize_t buf_result(void);
+/* cpuinfo.c */
+void root_cpuinfo(void);
+
/* tree.c */
int init_tree(void);
int lookup_hook(struct inode *parent, char *name, cbdata_t cbdata);
-/* ProcFS - root.c - by Alen Stojanov and David van Moolenbroek */
+/* ProcFS - root.c - generators for static files in the root directory */
#include "inc.h"
#include <machine/pci.h>
#endif
#include <minix/dmap.h>
-#include "cpuinfo.h"
static void root_hz(void);
static void root_uptime(void);
{ NULL, 0, NULL }
};
-/*===========================================================================*
- * root_hz *
- *===========================================================================*/
-static void root_hz(void)
+/*
+ * Print the system clock frequency.
+ */
+static void
+root_hz(void)
{
- /* Print the system clock frequency.
- */
- buf_printf("%lu\n", (long) sys_hz());
+ buf_printf("%lu\n", (unsigned long)sys_hz());
}
-/*===========================================================================*
- * root_loadavg *
- *===========================================================================*/
-static void root_loadavg(void)
+/*
+ * Print load averages.
+ */
+static void
+root_loadavg(void)
{
- /* Print load averages.
- */
struct load loads[3];
ldiv_t avg[3];
avg[2] = ldiv(100L * loads[2].proc_load / loads[2].ticks, 100);
buf_printf("%ld.%02ld %ld.%02ld %ld.%02ld\n",
- avg[0].quot, avg[0].rem, avg[1].quot, avg[1].rem,
- avg[2].quot, avg[2].rem);
+ avg[0].quot, avg[0].rem, avg[1].quot, avg[1].rem,
+ avg[2].quot, avg[2].rem);
}
-/*===========================================================================*
- * root_uptime *
- *===========================================================================*/
-static void root_uptime(void)
+/*
+ * Print the current uptime.
+ */
+static void
+root_uptime(void)
{
- /* Print the current uptime.
- */
clock_t ticks;
ldiv_t division;
buf_printf("%ld.%0.2ld\n", division.quot, division.rem);
}
-/*===========================================================================*
- * root_kinfo *
- *===========================================================================*/
-static void root_kinfo(void)
+/*
+ * Print general kernel information.
+ */
+static void
+root_kinfo(void)
{
- /* Print general kernel information.
- */
struct kinfo kinfo;
if (sys_getkinfo(&kinfo) != OK)
buf_printf("%u %u\n", kinfo.nr_procs, kinfo.nr_tasks);
}
-/*===========================================================================*
- * root_meminfo *
- *===========================================================================*/
-static void root_meminfo(void)
+/*
+ * Print general memory information.
+ */
+static void
+root_meminfo(void)
{
- /* Print general memory information.
- */
struct vm_stats_info vsi;
if (vm_info_stats(&vsi) != OK)
return;
- buf_printf("%u %lu %lu %lu %lu\n", vsi.vsi_pagesize,
- vsi.vsi_total, vsi.vsi_free, vsi.vsi_largest, vsi.vsi_cached);
+ buf_printf("%u %lu %lu %lu %lu\n", vsi.vsi_pagesize, vsi.vsi_total,
+ vsi.vsi_free, vsi.vsi_largest, vsi.vsi_cached);
}
-/*===========================================================================*
- * root_pci *
- *===========================================================================*/
#if defined(__i386__)
-static void root_pci(void)
+/*
+ * Print information about PCI devices present in the system.
+ */
+static void
+root_pci(void)
{
- /* Print information about PCI devices present in the system.
- */
u16_t vid, did, subvid, subdid;
u8_t bcr, scr, pifr, rev;
char *slot_name, *dev_name;
subdid = pci_attr_r16(devind, PCI_SUBDID);
buf_printf("%s %x/%x/%x/%x %04X:%04X:%04X:%04X %s\n",
- slot_name ? slot_name : "-1.-1.-1.-1",
- bcr, scr, pifr, rev,
- vid, did, subvid, subdid,
- dev_name ? dev_name : "");
+ slot_name ? slot_name : "-1.-1.-1.-1",
+ bcr, scr, pifr, rev,
+ vid, did, subvid, subdid,
+ dev_name ? dev_name : "");
r = pci_next_dev(&devind, &vid, &did);
}
}
#endif /* defined(__i386__) */
-/*===========================================================================*
- * root_dmap *
- *===========================================================================*/
-static void root_dmap(void)
+/*
+ * Print a list of drivers that have been assigned major device numbers.
+ */
+static void
+root_dmap(void)
{
struct dmap dmap[NR_DEVICES];
int i;
continue;
buf_printf("%u %s %u\n", i, dmap[i].dmap_label,
- dmap[i].dmap_driver);
+ dmap[i].dmap_driver);
}
}
-/*===========================================================================*
- * root_ipcvecs *
- *===========================================================================*/
-static void root_ipcvecs(void)
+/*
+ * Print a list of IPC vectors with their addresses.
+ */
+static void
+root_ipcvecs(void)
{
extern struct minix_kerninfo *_minix_kerninfo;
extern struct minix_ipcvecs _minix_ipcvecs;
- /* only print this if the kernel provides the info; otherwise binaries
- * will be using their own in-libc vectors that are normal symbols in the
- * binary.
+ /*
+ * Only print this if the kernel provides the info; otherwise binaries
+ * will be using their own in-libc vectors that are normal symbols in
+ * the binary.
*/
- if(!_minix_kerninfo || !(_minix_kerninfo->ki_flags & MINIX_KIF_IPCVECS))
+ if (!_minix_kerninfo ||
+ !(_minix_kerninfo->ki_flags & MINIX_KIF_IPCVECS))
return;
- /* print the vectors with an descriptive name and the additional (k)
+ /*
+ * Print the vectors with an descriptive name and the additional (k)
* to distinguish them from regular symbols.
*/
#define PRINT_ENTRYPOINT(name) \
- buf_printf("%08lx T %s(k)\n", _minix_ipcvecs.name, #name)
+ buf_printf("%08lx T %s(k)\n", \
+ (unsigned long)_minix_ipcvecs.name, #name)
PRINT_ENTRYPOINT(sendrec);
PRINT_ENTRYPOINT(send);
PRINT_ENTRYPOINT(do_kernel_call);
}
-/*===========================================================================*
- * root_mounts *
- *===========================================================================*/
+/*
+ * Print the list of mounted file systems.
+ */
static void
root_mounts(void)
{
for (i = 0; i < count; i++) {
buf_printf("%s on %s type %s (%s)\n", buf[i].f_mntfromname,
- buf[i].f_mntonname, buf[i].f_fstypename,
- (buf[i].f_flag & ST_RDONLY) ? "ro" : "rw");
- }
+ buf[i].f_mntonname, buf[i].f_fstypename,
+ (buf[i].f_flag & ST_RDONLY) ? "ro" : "rw");
+ }
}
-/* ProcFS - tree.c - by Alen Stojanov and David van Moolenbroek */
+/* ProcFS - tree.c - dynamic PID tree management and hook implementations */
#include "inc.h"
static int nr_pid_entries;
-/*===========================================================================*
- * slot_in_use *
- *===========================================================================*/
-static int slot_in_use(int slot)
+/*
+ * Return whether the given slot is in use by a process.
+ */
+static int
+slot_in_use(int slot)
{
- /* Return whether the given slot is in use by a process.
- */
- /* For kernel tasks, check only the kernel slot. Tasks do not have a
+ /*
+ * For kernel tasks, check only the kernel slot. Tasks do not have a
* PM/VFS process slot.
*/
if (slot < NR_TASKS)
return (proc[slot].p_rts_flags != RTS_SLOT_FREE);
- /* For regular processes, check only the PM slot. Do not check the
- * kernel slot, because that would skip zombie processes. The PID check
- * should be redundant, but if it fails, procfs could crash.
+ /* For regular processes, check only the PM slot. Do not check the
+ * kernel slot, because that would skip zombie processes. The PID
+ * check should be redundant, but if it fails, procfs could crash.
*/
return ((mproc[slot - NR_TASKS].mp_flags & IN_USE) &&
- mproc[slot - NR_TASKS].mp_pid != 0);
+ mproc[slot - NR_TASKS].mp_pid != 0);
}
-/*===========================================================================*
- * check_owner *
- *===========================================================================*/
-static int check_owner(struct inode *node, int slot)
+/*
+ * Check if the owner user and group ID of the inode are still in sync with
+ * the current effective user and group ID of the given process.
+ */
+static int
+check_owner(struct inode * node, int slot)
{
- /* Check if the owner user and group ID of the inode are still in sync
- * the current effective user and group ID of the given process.
- */
struct inode_stat stat;
if (slot < NR_TASKS) return TRUE;
get_inode_stat(node, &stat);
return (stat.uid == mproc[slot - NR_TASKS].mp_effuid &&
- stat.gid == mproc[slot - NR_TASKS].mp_effgid);
+ stat.gid == mproc[slot - NR_TASKS].mp_effgid);
}
-/*===========================================================================*
- * make_stat *
- *===========================================================================*/
-static void make_stat(struct inode_stat *stat, int slot, int index)
+/*
+ * Fill in an inode_stat structure for the given process slot and per-PID file
+ * index (or NO_INDEX for the process subdirectory root).
+ */
+static void
+make_stat(struct inode_stat * stat, int slot, int index)
{
- /* Fill in an inode_stat structure for the given process slot and
- * per-pid file index (or NO_INDEX for the process subdirectory root).
- */
if (index == NO_INDEX)
stat->mode = DIR_ALL_MODE;
stat->dev = NO_DEV;
}
-/*===========================================================================*
- * dir_is_pid *
- *===========================================================================*/
-static int dir_is_pid(struct inode *node)
+/*
+ * Return whether the given node is a PID directory.
+ */
+static int
+dir_is_pid(struct inode *node)
{
- /* Return whether the given node is a PID directory.
- */
return (get_parent_inode(node) == get_root_inode() &&
- get_inode_index(node) != NO_INDEX);
+ get_inode_index(node) != NO_INDEX);
}
-/*===========================================================================*
- * update_proc_table *
- *===========================================================================*/
-static int update_proc_table(void)
+/*
+ * Get the process table from the kernel. Check the magic number in the table
+ * entries.
+ */
+static int
+update_proc_table(void)
{
- /* Get the process table from the kernel.
- * Check the magic number in the table entries.
- */
int r, slot;
if ((r = sys_getproctab(proc)) != OK) return r;
return OK;
}
-/*===========================================================================*
- * update_mproc_table *
- *===========================================================================*/
-static int update_mproc_table(void)
+/*
+ * Get the process table from PM. Check the magic number in the table entries.
+ */
+static int
+update_mproc_table(void)
{
- /* Get the process table from PM.
- * Check the magic number in the table entries.
- */
int r, slot;
r = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc, sizeof(mproc));
return OK;
}
-/*===========================================================================*
- * update_fproc_table *
- *===========================================================================*/
-static int update_fproc_table(void)
+/*
+ * Get the process table from VFS.
+ */
+static int
+update_fproc_table(void)
{
- /* Get the process table from VFS.
- */
return getsysinfo(VFS_PROC_NR, SI_PROC_TAB, fproc, sizeof(fproc));
}
-/*===========================================================================*
- * update_tables *
- *===========================================================================*/
-static int update_tables(void)
+/*
+ * Get the process tables from the kernel, PM, and VFS.
+ */
+static int
+update_tables(void)
{
- /* Get the process tables from the kernel, PM, and VFS.
- */
int r;
if ((r = update_proc_table()) != OK) return r;
return OK;
}
-/*===========================================================================*
- * init_tree *
- *===========================================================================*/
-int init_tree(void)
+/*
+ * Initialize this module, before VTreeFS is started. As part of the process,
+ * check if we're not compiled against a kernel different from the one that is
+ * running at the moment.
+ */
+int
+init_tree(void)
{
- /* Initialize this module, before VTreeFS is started. As part of the
- * process, check if we're not compiled against a kernel different from
- * the one that is running at the moment.
- */
int i, r;
if ((r = update_tables()) != OK)
return r;
- /* Get the maximum number of entries that we may add to each PID's
- * directory. We could just default to a large value, but why not get
+ /*
+ * Get the maximum number of entries that we may add to each PID's
+ * directory. We could just default to a large value, but why not get
* it right?
*/
for (i = 0; pid_files[i].name != NULL; i++);
return OK;
}
-/*===========================================================================*
- * out_of_inodes *
- *===========================================================================*/
-static void out_of_inodes(void)
+/*
+ * Out of inodes - the NR_INODES value is set too low. We can not do much, but
+ * we might be able to continue with degraded functionality, so do not panic.
+ * If the NR_INODES value is not below the *crucial* minimum, the symptom of
+ * this case will be an incomplete listing of the main proc directory.
+ */
+static void
+out_of_inodes(void)
{
- /* Out of inodes - the NR_INODES value is set too low. We can not do
- * much, but we might be able to continue with degraded functionality,
- * so do not panic. If the NR_INODES value is not below the *crucial*
- * minimum, the symptom of this case will be an incomplete listing of
- * the main proc directory.
- */
static int warned = FALSE;
if (warned == FALSE) {
}
}
-/*===========================================================================*
- * construct_pid_dirs *
- *===========================================================================*/
-static void construct_pid_dirs(void)
+/*
+ * Regenerate the set of PID directories in the root directory of the file
+ * system. Add new directories and delete old directories as appropriate;
+ * leave unchanged those that should remain the same.
+ */
+static void
+construct_pid_dirs(void)
{
- /* Regenerate the set of PID directories in the root directory of the
- * file system. Add new directories and delete old directories as
- * appropriate; leave unchanged those that should remain the same.
- *
- * We have to make two passes. Otherwise, we would trigger a vtreefs
+ /*
+ * We have to make two passes. Otherwise, we would trigger a vtreefs
* assert when we add an entry for a PID before deleting the previous
- * entry for that PID. While rare, such rapid PID reuse does occur in
+ * entry for that PID. While rare, such rapid PID reuse does occur in
* practice.
*/
struct inode *root, *node;
if (node == NULL)
continue;
- /* If the process slot is not in use, delete the associated
+ /*
+ * If the process slot is not in use, delete the associated
* inode.
*/
if (!slot_in_use(i)) {
/* Otherwise, get the process ID. */
if (i < NR_TASKS)
- pid = (pid_t) (i - NR_TASKS);
+ pid = (pid_t)(i - NR_TASKS);
else
pid = mproc[i - NR_TASKS].mp_pid;
- /* If there is an old entry, see if the pid matches the current
- * entry, and the owner is still the same. Otherwise, delete
- * the old entry first. We reconstruct the entire subtree even
+ /*
+ * If there is an old entry, see if the pid matches the current
+ * entry, and the owner is still the same. Otherwise, delete
+ * the old entry first. We reconstruct the entire subtree even
* if only the owner changed, for security reasons: if a
* process could keep open a file or directory across the owner
* change, it might be able to access information it shouldn't.
*/
- if (pid != (pid_t) get_inode_cbdata(node) ||
- !check_owner(node, i))
+ if (pid != (pid_t)get_inode_cbdata(node) ||
+ !check_owner(node, i))
delete_inode(node);
}
if (!slot_in_use(i))
continue;
- /* If we have an inode associated with this slot, we have
+ /*
+ * If we have an inode associated with this slot, we have
* already checked it to be up-to-date above.
*/
if (get_inode_by_index(root, i) != NULL)
/* Get the process ID. */
if (i < NR_TASKS)
- pid = (pid_t) (i - NR_TASKS);
+ pid = (pid_t)(i - NR_TASKS);
else
pid = mproc[i - NR_TASKS].mp_pid;
make_stat(&stat, i, NO_INDEX);
node = add_inode(root, name, i, &stat, nr_pid_entries,
- (cbdata_t) pid);
+ (cbdata_t)pid);
if (node == NULL)
out_of_inodes();
}
}
-/*===========================================================================*
- * make_one_pid_entry *
- *===========================================================================*/
-static void make_one_pid_entry(struct inode *parent, char *name, int slot)
+/*
+ * Construct one file in a PID directory, if a file with the given name should
+ * exist at all.
+ */
+static void
+make_one_pid_entry(struct inode * parent, char * name, int slot)
{
- /* Construct one file in a PID directory, if a file with the given name
- * should exist at all.
- */
struct inode *node;
struct inode_stat stat;
int i;
if (!strcmp(name, pid_files[i].name)) {
make_stat(&stat, slot, i);
- node = add_inode(parent, name, i, &stat,
- (index_t) 0, (cbdata_t) 0);
+ node = add_inode(parent, name, i, &stat, (index_t)0,
+ (cbdata_t)0);
if (node == NULL)
out_of_inodes();
}
}
-/*===========================================================================*
- * make_all_pid_entries *
- *===========================================================================*/
-static void make_all_pid_entries(struct inode *parent, int slot)
+/*
+ * Construct all files in a PID directory.
+ */
+static void
+make_all_pid_entries(struct inode * parent, int slot)
{
- /* Construct all files in a PID directory.
- */
struct inode *node;
struct inode_stat stat;
int i;
make_stat(&stat, slot, i);
node = add_inode(parent, pid_files[i].name, i, &stat,
- (index_t) 0, (cbdata_t) 0);
+ (index_t)0, (cbdata_t)0);
if (node == NULL)
out_of_inodes();
}
}
-/*===========================================================================*
- * construct_pid_entries *
- *===========================================================================*/
-static void construct_pid_entries(struct inode *parent, char *name)
+/*
+ * Construct one requested file entry, or all file entries, in a PID directory.
+ */
+static void
+construct_pid_entries(struct inode * parent, char * name)
{
- /* Construct one requested file entry, or all file entries, in a PID
- * directory.
- */
int slot;
slot = get_inode_index(parent);
return;
}
- /* If a specific file name is being looked up, see if we have to add
- * an inode for that file. If the directory contents are being
+ /*
+ * If a specific file name is being looked up, see if we have to add
+ * an inode for that file. If the directory contents are being
* retrieved, add all files that have not yet been added.
*/
if (name != NULL)
make_all_pid_entries(parent, slot);
}
-/*===========================================================================*
- * pid_read *
- *===========================================================================*/
-static void pid_read(struct inode *node)
+/*
+ * Data is requested from one of the files in a PID directory. Call the
+ * function that is responsible for generating the data for that file.
+ */
+static void
+pid_read(struct inode * node)
{
- /* Data is requested from one of the files in a PID directory. Call the
- * function that is responsible for generating the data for that file.
- */
struct inode *parent;
int slot, index;
- /* Get the slot number of the process. Note that this currently will
+ /*
+ * Get the slot number of the process. Note that this currently will
* not work for files not in the top-level pid subdirectory.
*/
parent = get_parent_inode(node);
index = get_inode_index(node);
/* Call the handler procedure for the file. */
- ((void (*) (int)) pid_files[index].data)(slot);
+ ((void (*)(int))pid_files[index].data)(slot);
}
-/*===========================================================================*
- * pid_link *
- *===========================================================================*/
-static int pid_link(struct inode *UNUSED(node), char *ptr, int max)
+/*
+ * The contents of a symbolic link in a PID directory are requested. This
+ * function is a placeholder for future use.
+ */
+static int
+pid_link(struct inode * __unused node, char * ptr, int max)
{
- /* The contents of a symbolic link in a PID directory are requested.
- * This function is a placeholder for future use.
- */
/* Nothing yet. */
strlcpy(ptr, "", max);
return OK;
}
-/*===========================================================================*
- * lookup_hook *
- *===========================================================================*/
-int lookup_hook(struct inode *parent, char *name,
- cbdata_t UNUSED(cbdata))
+/*
+ * Path name resolution hook, for a specific parent and name pair. If needed,
+ * update our own view of the system first; after that, determine whether we
+ * need to (re)generate certain files.
+ */
+int
+lookup_hook(struct inode * parent, char * name, cbdata_t __unused cbdata)
{
- /* Path name resolution hook, for a specific parent and name pair.
- * If needed, update our own view of the system first; after that,
- * determine whether we need to (re)generate certain files.
- */
static clock_t last_update = 0;
clock_t now;
int r;
- /* Update lazily for lookups, as this gets too expensive otherwise.
+ /*
+ * Update lazily for lookups, as this gets too expensive otherwise.
* Alternative: pull in only PM's table?
*/
if ((r = getticks(&now)) != OK)
last_update = now;
}
- /* If the parent is the root directory, we must now reconstruct all
+ /*
+ * If the parent is the root directory, we must now reconstruct all
* entries, because some of them might have been garbage collected.
* We must update the entire tree at once; if we update individual
* entries, we risk name collisions.
- */
- if (parent == get_root_inode()) {
- construct_pid_dirs();
- }
- /* If the parent is a process directory, we may need to (re)construct
+ *
+ * If the parent is a process directory, we may need to (re)construct
* the entry being looked up.
*/
- else if (dir_is_pid(parent)) {
- /* We might now have deleted our current containing directory;
+ if (parent == get_root_inode())
+ construct_pid_dirs();
+ else if (dir_is_pid(parent))
+ /*
+ * We might now have deleted our current containing directory;
* construct_pid_entries() will take care of this case.
*/
construct_pid_entries(parent, name);
- }
return OK;
}
-/*===========================================================================*
- * getdents_hook *
- *===========================================================================*/
-int getdents_hook(struct inode *node, cbdata_t UNUSED(cbdata))
+/*
+ * Directory entry retrieval hook, for potentially all files in a directory.
+ * Make sure that all files that are supposed to be returned, are actually part
+ * of the virtual tree.
+ */
+int
+getdents_hook(struct inode * node, cbdata_t __unused cbdata)
{
- /* Directory entry retrieval hook, for potentially all files in a
- * directory. Make sure that all files that are supposed to be
- * returned, are actually part of the virtual tree.
- */
if (node == get_root_inode()) {
update_tables();
construct_pid_dirs();
- } else if (dir_is_pid(node)) {
+ } else if (dir_is_pid(node))
construct_pid_entries(node, NULL /*name*/);
- }
return OK;
}
-/*===========================================================================*
- * read_hook *
- *===========================================================================*/
-ssize_t read_hook(struct inode *node, char *ptr, size_t len, off_t off,
+/*
+ * Regular file read hook. Call the appropriate callback function to generate
+ * and return the data.
+ */
+ssize_t
+read_hook(struct inode * node, char * ptr, size_t len, off_t off,
cbdata_t cbdata)
{
- /* Regular file read hook. Call the appropriate callback function to
- * generate and return the data.
- */
buf_init(ptr, len, off);
/* Populate the buffer with the proper content. */
- if (get_inode_index(node) != NO_INDEX) {
+ if (get_inode_index(node) != NO_INDEX)
pid_read(node);
- } else {
- ((void (*) (void)) cbdata)();
- }
+ else
+ ((void (*)(void))cbdata)();
return buf_result();
}
-/*===========================================================================*
- * rdlink_hook *
- *===========================================================================*/
-int rdlink_hook(struct inode *node, char *ptr, size_t max,
- cbdata_t UNUSED(cbdata))
+/*
+ * Symbolic link resolution hook. Not used yet.
+ */
+int
+rdlink_hook(struct inode * node, char * ptr, size_t max,
+ cbdata_t __unused cbdata)
{
- /* Symbolic link resolution hook. Not used yet.
- */
struct inode *parent;
/* Get the parent inode. */
parent = get_parent_inode(node);
- /* If the parent inode is a pid directory, call the pid handler.
- */
+ /* If the parent inode is a pid directory, call the pid handler. */
if (parent != NULL && dir_is_pid(parent))
pid_link(node, ptr, max);
long proc_load; /* .. the CPU had this load */
};
-/* ProcFS supports two groups of files: dynamic files, which are created within
- * process-specific (PID) directories, and static files, which are global. For
+/*
+ * ProcFS supports two groups of files: dynamic files, which are created within
+ * process-specific (PID) directories, and static files, which are global. For
* both, the following structure is used to construct the files.
*
* For dynamic files, the rules are simple: only regular files are supported
* The function will be called whenever a read request for the file is made;
* 'slot' contains the kernel slot number of the process being queried (so for
* the PM and VFS process tables, NR_TASKS has to be subtracted from the slot
- * number to find the right slot). The function is expected to produce
+ * number to find the right slot). The function is expected to produce
* appropriate output using the buf_printf() function.
*
- * For static files, regular files and directories are supported. For
+ * For static files, regular files and directories are supported. For
* directories, the 'data' field must be a pointer to another 'struct file'
* array that specifies the contents of the directory - this directory will
- * the be created recursively. For regular files, the 'data' field must point
+ * the be created recursively. For regular files, the 'data' field must point
* to a function of the type:
*
* void (*)(void)
*
* Here too, the function will be called upon a read request, and it is
- * supposed to "fill" the file using buf_printf(). Obviously, for static files,
- * there is no slot number.
+ * supposed to "fill" the file using buf_printf(). Obviously, for static
+ * files, there is no slot number.
*
* For both static and dynamic files, 'mode' must specify the file type as well
* as the access mode, and in both cases, each array is terminated with an
* entry that has its name set to NULL.
*/
-/* The internal link between static/dynamic files/directories and VTreeFS'
+/*
+ * The internal link between static/dynamic files/directories and VTreeFS'
* indexes and cbdata values is as follows:
* - Dynamic directories are always PID directories in the root directory.
* They are generated automatically, and are not specified using a "struct
- * file" structure. Their index is their slot number, so that getdents()
- * calls always return any PID at most once. Their cbdata value is the PID of
- * the process associated with that dynamic directory, for the purpose of
+ * file" structure. Their index is their slot number, so that getdents()
+ * calls always return any PID at most once. Their cbdata value is the PID
+ * of the process associated with that dynamic directory, for the purpose of
* comparing old and new PIDs after updating process tables (without having
* to atoi() the directory's name).
- * - Dynamic files are always in such a dynamic directory. Their index is the
- * array index into the "struct file" array of pid files (pid_files[]). They
- * are indexed at all, because they may be deleted at any time due to inode
- * shortages, independently of other dynamic files in the same directory, and
- * recreating them without index would again risk possibly inconsistent
+ * - Dynamic files are always in such a dynamic directory. Their index is the
+ * array index into the "struct file" array of pid files (pid_files[]). They
+ * are indexed at all because they may be deleted at any time due to inode
+ * shortages, independently of other dynamic files in the same directory.
+ * Recreating them without index would again risk possibly inconsistent
* getdents() results, where for example the same file shows up twice.
- * VTreeFS currently does not distinguish between indexed and delatable files
+ * VTreeFS currently does not distinguish between indexed and deletable files
* and hence, all dynamic files must be indexed so as to be deletable anyway.
* - Static directories have no index (they are not and must not be deletable),
* and although their cbdata is their associated 'data' field from their
* "struct file" entries, their cbdata value is currently not relied on
- * anywhere. Then again, as of writing, there are no static directories at
+ * anywhere. Then again, as of writing, there are no static directories at
* all.
- * - Static files have no index either (for the same reason). Their cbdata is
+ * - Static files have no index either (for the same reason). Their cbdata is
* also their 'data' field from the "struct file" entry creating the file,
* and this is used to actually call the callback function directly.
*/
-/* ProcFS - util.c - by Alen Stojanov and David van Moolenbroek */
+/* ProcFS - util.c - utility functions */
#include "inc.h"
-/*===========================================================================*
- * procfs_getloadavg *
- *===========================================================================*/
-int procfs_getloadavg(struct load *loadavg, int nelem)
+/*
+ * Retrieve system load average information.
+ */
+int
+procfs_getloadavg(struct load * loadavg, int nelem)
{
- /* Retrieve system load average information.
- */
struct loadinfo loadinfo;
u32_t system_hz, ticks_per_slot;
int p, unfilled_ticks;
+ int h, slots, latest, slot;
int minutes[3] = { 1, 5, 15 };
ssize_t l;
- if(nelem < 1) {
+ if (nelem < 1) {
errno = ENOSPC;
return -1;
}
system_hz = sys_hz();
- if((l=sys_getloadinfo(&loadinfo)) != OK)
+ if ((l = sys_getloadinfo(&loadinfo)) != OK)
return -1;
- if(nelem > 3)
+ if (nelem > 3)
nelem = 3;
/* How many ticks are missing from the newest-filled slot? */
ticks_per_slot = _LOAD_UNIT_SECS * system_hz;
unfilled_ticks =
- ticks_per_slot - (loadinfo.last_clock % ticks_per_slot);
+ ticks_per_slot - (loadinfo.last_clock % ticks_per_slot);
- for(p = 0; p < nelem; p++) {
- int h, slots;
- int latest = loadinfo.proc_last_slot;
+ for (p = 0; p < nelem; p++) {
+ latest = loadinfo.proc_last_slot;
slots = minutes[p] * 60 / _LOAD_UNIT_SECS;
loadavg[p].proc_load = 0;
- /* Add up the total number of process ticks for this number
- * of minutes (minutes[p]). Start with the newest slot, which
+ /*
+ * Add up the total number of process ticks for this number
+ * of minutes (minutes[p]). Start with the newest slot, which
* is latest, and count back for the number of slots that
- * correspond to the right number of minutes. Take wraparound
+ * correspond to the right number of minutes. Take wraparound
* into account by calculating the index modulo _LOAD_HISTORY,
* which is the number of slots of history kept.
*/
- for(h = 0; h < slots; h++) {
- int slot;
+ for (h = 0; h < slots; h++) {
slot = (latest - h + _LOAD_HISTORY) % _LOAD_HISTORY;
loadavg[p].proc_load +=
- loadinfo.proc_load_history[slot];
+ loadinfo.proc_load_history[slot];
l += (ssize_t) loadinfo.proc_load_history[slot];
}
- /* The load average over this number of minutes is the number
+ /*
+ * The load average over this number of minutes is the number
* of process-ticks divided by the number of ticks, not
* counting the number of ticks the last slot hasn't been
* around yet.