124139SjoergInstructions for porting top to other architectures.
224139Sjoerg
324139SjoergThis is still a preliminary document.  Suggestions for improvement are
424139Sjoergmost welcome.
524139Sjoerg
689750SdwmaloneMy address is now "wnl@groupsys.com".
724139Sjoerg
824139SjoergBefore you embark on a port, please send me a mail message telling me
924139Sjoergwhat platform you are porting top to.  There are three reasons for
1024139Sjoergthis: (1) I may already have a port, (2) module naming needs to be
1124139Sjoergcentralized, (3) I want to loosely track the various porting efforts.
1224139SjoergYou do not need to wait for an "okay", but I do want to know that you
1324139Sjoergare working on it.  And of course, once it is finished, please send me
1424139Sjoergthe module files so that I can add them to the main distribution!
1524139Sjoerg
1624139Sjoerg----------
1724139Sjoerg
1824139SjoergThere is one set of functions which extract all the information that
1924139Sjoergtop needs for display.  These functions are collected in to one file.
2024139SjoergTo make top work on a different architecture simply requires a
2124139Sjoergdifferent implementation of these functions.  The functions for a
2224139Sjoerggiven architecture "foo" are stored in a file called "m_foo.c".  The
2324139SjoergConfigure script looks for these files and lets the configurer choose
2424139Sjoergone of them.  This file is called a "module".  The idea is that making
2524139Sjoergtop work on a different machine only requires one additional file and
2624139Sjoergdoes not require changes to any existing files.
2724139Sjoerg
2824139SjoergA module template is included in the distribution, called "m-template".
2924139SjoergTo write your own module, it is a good idea to start with this template.
3024139SjoergIf you architecture is similar to one for which a module already
3124139Sjoergexists, then you can start with that module instead.  If you do so,
3224139Sjoergremember to change the "AUTHOR" section at the top!
3324139Sjoerg
3424139SjoergThe first comment in a module contains information which is extracted
3524139Sjoergand used by Configure.  This information is marked with words in all
3624139Sjoergcapitals (such as "SYNOPSIS:" and "LIBS:").  Go look at m-template: it
3724139Sjoergis fairly self-explanatory.  The text after "LIBS:" (on the same line)
3824139Sjoergis extracted and included in the LIBS definition of the Makefile so
3924139Sjoergthat extra libraries which may be necessary on some machines (such as
4024139Sjoerg"-lkvm") can be specified in the module.  The text after "CFLAGS:"
4124139Sjoerg(on the same line) is extracted and included as flags in the "CFLAGS"
4224139Sjoergdefinition of the Makefile (thus in every compilation step).  This is
4324139Sjoergused for rare circumstances only:  please don't abuse this hook.
4424139Sjoerg
4524139SjoergSome operating systems have idiosyncrasies which will affect the form
4624139Sjoergand/or content of the information top displays.  You may wish to
4724139Sjoergdocument such anomalies in the top man page.  This can be done by adding
4824139Sjoerga file called m_{modulename}.man (where {modulename} is replaced with
4924139Sjoergthe name of the module).  Configure will automatically add this file to
5024139Sjoergthe end of the man page.  See m_sunos4.man for an example.
5124139Sjoerg
5224139SjoergA module is concerned with two structures:
5324139Sjoerg
5424139SjoergThe statics struct is filled in by machine_init.  Each item is a
5524139Sjoergpointer to a list of character pointers.  The list is terminated 
5624139Sjoergwith a null pointer.
5724139Sjoerg
5824139Sjoergstruct statics
5924139Sjoerg{
6024139Sjoerg    char **procstate_names;	/* process state names */
6124139Sjoerg    char **cpustate_names;	/* cpu state names */
6224139Sjoerg    char **memory_names;	/* memory information names */
6324139Sjoerg};
6424139Sjoerg
6524139SjoergThe system_info struct is filled in by get_system_info and
6624139Sjoergget_process_info.
6724139Sjoerg
6824139Sjoergstruct system_info
6924139Sjoerg{
7024139Sjoerg    int    last_pid;     /* last pid assigned (0 means non-sequential assignment) */
7124139Sjoerg    double load_avg[NUM_AVERAGES];     /* see below */
7224139Sjoerg    int    p_total;      /* total number of processes */
7324139Sjoerg    int    p_active;     /* number of procs considered "active" */
7424139Sjoerg    int    *procstates;  /* array of process state counters */
7524139Sjoerg    int    *cpustates;   /* array of cpustate counters */
7624139Sjoerg    int    *memory;      /* memory information */
7724139Sjoerg};
7824139Sjoerg
7924139SjoergThe last three pointers each point to an array of integers.  The
8024139Sjoerglength of the array is determined by the length of the corresponding
8124139Sjoerg_names array in the statics structure.  Furthermore, if an entry in a
8224139Sjoerg_names array is the empty string ("") then the corresponding value in
8324139Sjoergthe value array will be skipped over.  The display routine displays,
8424139Sjoergfor example, the string procstate_names[0] then the number
8524139Sjoergprocstates[0], then procstate_names[1], procstates[1], etc. until
8624139Sjoergprocstate_names[N] == NULL.  This allows for a tremendous amount of
8724139Sjoergflexibility in labeling the displayed values.
8824139Sjoerg
8924139Sjoerg"procstates" and "memory" are displayed as straight integer values.
9024139SjoergValues in "cpustates" are displayed as a percentage * 10.  For
9124139Sjoergexample, the (integer) value 105 is displayed as 10.5%.
9224139Sjoerg
9324139SjoergThese routines must be defined by the machine dependent module.
9424139Sjoerg
9524139Sjoergint machine_init(struct statics *)
9624139Sjoerg
9724139Sjoerg	returns 0 on success and -1 on failure,
9824139Sjoerg	prints error messages
9924139Sjoerg
10024139Sjoergchar *format_header(char *)
10124139Sjoerg
10224139Sjoerg	Returns a string which should be used as the header for the
10324139Sjoerg	process display area.  The argument is a string used to label
10424139Sjoerg	the username column (either "USERNAME" or "UID") and is always
10524139Sjoerg	8 characters in length.
10624139Sjoerg
10724139Sjoergvoid get_system_info(struct system_info *)
10824139Sjoerg
10924139Sjoergcaddr_t get_process_info(struct system_info *, int, int, int (*func)())
11024139Sjoerg
11124139Sjoerg	returns a handle to use with format_next_process
11224139Sjoerg
11324139Sjoergchar *format_next_process(caddr_t, char *(*func)())
11424139Sjoerg
11524139Sjoerg	returns string which describes next process
11624139Sjoerg
11724139Sjoergint proc_compare(caddr_t, caddr_t)
11824139Sjoerg
11924139Sjoerg	qsort comparison function
12024139Sjoerg
12124139Sjoerguid_t proc_owner(pid_t)
12224139Sjoerg
12324139Sjoerg	Returns the uid owner of the process specified by the pid argument.
12424139Sjoerg	This function is VERY IMPORTANT.  If it fails to do its job, then
12524139Sjoerg	top may pose a security risk.
12624139Sjoerg
12724139Sjoerg
12824139Sjoergget_process_info is called immediately after get_system_info.  In
12924139Sjoergfact, the two functions could be rolled in to one.  The reason they
13024139Sjoergare not is mostly historical.
13124139Sjoerg
13224139SjoergTop relies on the existence of a function called "setpriority" to
13324139Sjoergchange a process's priority.  This exists as a kernel call on most 4.3
13424139SjoergBSD derived Unixes.  If neither your operating system nor your C
13524139Sjoerglibrary supplies such a function, then you will need to add one to the
13624139Sjoergmodule.  It is defined as follows:
13724139Sjoerg
13824139Sjoerg	int setpriority (int dummy, int who, int niceval)
13924139Sjoerg
14024139Sjoerg	For the purposes of top, the first argument is meaningless.
14124139Sjoerg	The second is the pid and the third is the new nice value.
14224139Sjoerg	This function should behave just like a kernel call, setting
14324139Sjoerg	errno and returning -1 in case of an error.  This function MUST
14424139Sjoerg	check to make sure that a non-root user does not specify a nice
14524139Sjoerg	value less than the process's current value.  If it detects such
14624139Sjoerg	a condition, it should set errno to EACCES and return -1.
14724139Sjoerg	Other possible ERRNO values:  ESRCH when pid "who" does not exist,
14824139Sjoerg	EPERM when the invoker is not root and not the same as the
14924139Sjoerg	process owner.
15024139Sjoerg
15124139SjoergNote that top checks process ownership and should never call setpriority
15224139Sjoergwhen the invoker's uid is not root and not the same as the process's owner
15324139Sjoerguid.
15424139Sjoerg
15524139Sjoerg
15624139SjoergThe file "machine.h" contains definitions which are useful to modules
15724139Sjoergand to top.c (such as the structure definitions).  You SHOULD NOT need
15824139Sjoergto change it when porting to a new platform.
15924139Sjoerg
16024139SjoergPorting to a new platform should NOT require any changes to existing
16124139Sjoergfiles.  You should only need to add m_ files.  If you feel you need a
16224139Sjoergchange in one of the existing files, please contact me so that we can
16324139Sjoergdiscuss the details.  I want to keep such changes as general as
16424139Sjoergpossible.
16524139Sjoerg
166