diff options
Diffstat (limited to 'contrib/top/Porting')
-rw-r--r-- | contrib/top/Porting | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/contrib/top/Porting b/contrib/top/Porting new file mode 100644 index 0000000..7fd3ff4 --- /dev/null +++ b/contrib/top/Porting @@ -0,0 +1,165 @@ +Instructions for porting top to other architectures. + +This is still a preliminary document. Suggestions for improvement are +most welcome. + +My address is now "lefebvre@dis.anl.gov". + +Before you embark on a port, please send me a mail message telling me +what platform you are porting top to. There are three reasons for +this: (1) I may already have a port, (2) module naming needs to be +centralized, (3) I want to loosely track the various porting efforts. +You do not need to wait for an "okay", but I do want to know that you +are working on it. And of course, once it is finished, please send me +the module files so that I can add them to the main distribution! + +---------- + +There is one set of functions which extract all the information that +top needs for display. These functions are collected in to one file. +To make top work on a different architecture simply requires a +different implementation of these functions. The functions for a +given architecture "foo" are stored in a file called "m_foo.c". The +Configure script looks for these files and lets the configurer choose +one of them. This file is called a "module". The idea is that making +top work on a different machine only requires one additional file and +does not require changes to any existing files. + +A module template is included in the distribution, called "m-template". +To write your own module, it is a good idea to start with this template. +If you architecture is similar to one for which a module already +exists, then you can start with that module instead. If you do so, +remember to change the "AUTHOR" section at the top! + +The first comment in a module contains information which is extracted +and used by Configure. This information is marked with words in all +capitals (such as "SYNOPSIS:" and "LIBS:"). Go look at m-template: it +is fairly self-explanatory. The text after "LIBS:" (on the same line) +is extracted and included in the LIBS definition of the Makefile so +that extra libraries which may be necessary on some machines (such as +"-lkvm") can be specified in the module. The text after "CFLAGS:" +(on the same line) is extracted and included as flags in the "CFLAGS" +definition of the Makefile (thus in every compilation step). This is +used for rare circumstances only: please don't abuse this hook. + +Some operating systems have idiosyncrasies which will affect the form +and/or content of the information top displays. You may wish to +document such anomalies in the top man page. This can be done by adding +a file called m_{modulename}.man (where {modulename} is replaced with +the name of the module). Configure will automatically add this file to +the end of the man page. See m_sunos4.man for an example. + +A module is concerned with two structures: + +The statics struct is filled in by machine_init. Each item is a +pointer to a list of character pointers. The list is terminated +with a null pointer. + +struct statics +{ + char **procstate_names; /* process state names */ + char **cpustate_names; /* cpu state names */ + char **memory_names; /* memory information names */ +}; + +The system_info struct is filled in by get_system_info and +get_process_info. + +struct system_info +{ + int last_pid; /* last pid assigned (0 means non-sequential assignment) */ + double load_avg[NUM_AVERAGES]; /* see below */ + int p_total; /* total number of processes */ + int p_active; /* number of procs considered "active" */ + int *procstates; /* array of process state counters */ + int *cpustates; /* array of cpustate counters */ + int *memory; /* memory information */ +}; + +The last three pointers each point to an array of integers. The +length of the array is determined by the length of the corresponding +_names array in the statics structure. Furthermore, if an entry in a +_names array is the empty string ("") then the corresponding value in +the value array will be skipped over. The display routine displays, +for example, the string procstate_names[0] then the number +procstates[0], then procstate_names[1], procstates[1], etc. until +procstate_names[N] == NULL. This allows for a tremendous amount of +flexibility in labeling the displayed values. + +"procstates" and "memory" are displayed as straight integer values. +Values in "cpustates" are displayed as a percentage * 10. For +example, the (integer) value 105 is displayed as 10.5%. + +These routines must be defined by the machine dependent module. + +int machine_init(struct statics *) + + returns 0 on success and -1 on failure, + prints error messages + +char *format_header(char *) + + Returns a string which should be used as the header for the + process display area. The argument is a string used to label + the username column (either "USERNAME" or "UID") and is always + 8 characters in length. + +void get_system_info(struct system_info *) + +caddr_t get_process_info(struct system_info *, int, int, int (*func)()) + + returns a handle to use with format_next_process + +char *format_next_process(caddr_t, char *(*func)()) + + returns string which describes next process + +int proc_compare(caddr_t, caddr_t) + + qsort comparison function + +uid_t proc_owner(pid_t) + + Returns the uid owner of the process specified by the pid argument. + This function is VERY IMPORTANT. If it fails to do its job, then + top may pose a security risk. + + +get_process_info is called immediately after get_system_info. In +fact, the two functions could be rolled in to one. The reason they +are not is mostly historical. + +Top relies on the existence of a function called "setpriority" to +change a process's priority. This exists as a kernel call on most 4.3 +BSD derived Unixes. If neither your operating system nor your C +library supplies such a function, then you will need to add one to the +module. It is defined as follows: + + int setpriority (int dummy, int who, int niceval) + + For the purposes of top, the first argument is meaningless. + The second is the pid and the third is the new nice value. + This function should behave just like a kernel call, setting + errno and returning -1 in case of an error. This function MUST + check to make sure that a non-root user does not specify a nice + value less than the process's current value. If it detects such + a condition, it should set errno to EACCES and return -1. + Other possible ERRNO values: ESRCH when pid "who" does not exist, + EPERM when the invoker is not root and not the same as the + process owner. + +Note that top checks process ownership and should never call setpriority +when the invoker's uid is not root and not the same as the process's owner +uid. + + +The file "machine.h" contains definitions which are useful to modules +and to top.c (such as the structure definitions). You SHOULD NOT need +to change it when porting to a new platform. + +Porting to a new platform should NOT require any changes to existing +files. You should only need to add m_ files. If you feel you need a +change in one of the existing files, please contact me so that we can +discuss the details. I want to keep such changes as general as +possible. + |