Add manpage for stge(4)
[dragonfly.git] / contrib / top / Porting
1 Instructions for porting top to other architectures.
2
3 This is still a preliminary document.  Suggestions for improvement are
4 most welcome.
5
6 My address is now "wnl@groupsys.com".
7
8 Before you embark on a port, please send me a mail message telling me
9 what platform you are porting top to.  There are three reasons for
10 this: (1) I may already have a port, (2) module naming needs to be
11 centralized, (3) I want to loosely track the various porting efforts.
12 You do not need to wait for an "okay", but I do want to know that you
13 are working on it.  And of course, once it is finished, please send me
14 the module files so that I can add them to the main distribution!
15
16 ----------
17
18 There is one set of functions which extract all the information that
19 top needs for display.  These functions are collected in to one file.
20 To make top work on a different architecture simply requires a
21 different implementation of these functions.  The functions for a
22 given architecture "foo" are stored in a file called "m_foo.c".  The
23 Configure script looks for these files and lets the configurer choose
24 one of them.  This file is called a "module".  The idea is that making
25 top work on a different machine only requires one additional file and
26 does not require changes to any existing files.
27
28 A module template is included in the distribution, called "m-template".
29 To write your own module, it is a good idea to start with this template.
30 If you architecture is similar to one for which a module already
31 exists, then you can start with that module instead.  If you do so,
32 remember to change the "AUTHOR" section at the top!
33
34 The first comment in a module contains information which is extracted
35 and used by Configure.  This information is marked with words in all
36 capitals (such as "SYNOPSIS:" and "LIBS:").  Go look at m-template: it
37 is fairly self-explanatory.  The text after "LIBS:" (on the same line)
38 is extracted and included in the LIBS definition of the Makefile so
39 that extra libraries which may be necessary on some machines (such as
40 "-lkvm") can be specified in the module.  The text after "CFLAGS:"
41 (on the same line) is extracted and included as flags in the "CFLAGS"
42 definition of the Makefile (thus in every compilation step).  This is
43 used for rare circumstances only:  please don't abuse this hook.
44
45 Some operating systems have idiosyncrasies which will affect the form
46 and/or content of the information top displays.  You may wish to
47 document such anomalies in the top man page.  This can be done by adding
48 a file called m_{modulename}.man (where {modulename} is replaced with
49 the name of the module).  Configure will automatically add this file to
50 the end of the man page.  See m_sunos4.man for an example.
51
52 A module is concerned with two structures:
53
54 The statics struct is filled in by machine_init.  Each item is a
55 pointer to a list of character pointers.  The list is terminated 
56 with a null pointer.
57
58 struct statics
59 {
60     char **procstate_names;     /* process state names */
61     char **cpustate_names;      /* cpu state names */
62     char **memory_names;        /* memory information names */
63 };
64
65 The system_info struct is filled in by get_system_info and
66 get_process_info.
67
68 struct system_info
69 {
70     int    last_pid;     /* last pid assigned (0 means non-sequential assignment) */
71     double load_avg[NUM_AVERAGES];     /* see below */
72     int    p_total;      /* total number of processes */
73     int    p_active;     /* number of procs considered "active" */
74     int    *procstates;  /* array of process state counters */
75     int    *cpustates;   /* array of cpustate counters */
76     int    *memory;      /* memory information */
77 };
78
79 The last three pointers each point to an array of integers.  The
80 length of the array is determined by the length of the corresponding
81 _names array in the statics structure.  Furthermore, if an entry in a
82 _names array is the empty string ("") then the corresponding value in
83 the value array will be skipped over.  The display routine displays,
84 for example, the string procstate_names[0] then the number
85 procstates[0], then procstate_names[1], procstates[1], etc. until
86 procstate_names[N] == NULL.  This allows for a tremendous amount of
87 flexibility in labeling the displayed values.
88
89 "procstates" and "memory" are displayed as straight integer values.
90 Values in "cpustates" are displayed as a percentage * 10.  For
91 example, the (integer) value 105 is displayed as 10.5%.
92
93 These routines must be defined by the machine dependent module.
94
95 int machine_init(struct statics *)
96
97         returns 0 on success and -1 on failure,
98         prints error messages
99
100 char *format_header(char *)
101
102         Returns a string which should be used as the header for the
103         process display area.  The argument is a string used to label
104         the username column (either "USERNAME" or "UID") and is always
105         8 characters in length.
106
107 void get_system_info(struct system_info *)
108
109 caddr_t get_process_info(struct system_info *, int, int, int (*func)())
110
111         returns a handle to use with format_next_process
112
113 char *format_next_process(caddr_t, char *(*func)())
114
115         returns string which describes next process
116
117 int proc_compare(caddr_t, caddr_t)
118
119         qsort comparison function
120
121 uid_t proc_owner(pid_t)
122
123         Returns the uid owner of the process specified by the pid argument.
124         This function is VERY IMPORTANT.  If it fails to do its job, then
125         top may pose a security risk.
126
127
128 get_process_info is called immediately after get_system_info.  In
129 fact, the two functions could be rolled in to one.  The reason they
130 are not is mostly historical.
131
132 Top relies on the existence of a function called "setpriority" to
133 change a process's priority.  This exists as a kernel call on most 4.3
134 BSD derived Unixes.  If neither your operating system nor your C
135 library supplies such a function, then you will need to add one to the
136 module.  It is defined as follows:
137
138         int setpriority (int dummy, int who, int niceval)
139
140         For the purposes of top, the first argument is meaningless.
141         The second is the pid and the third is the new nice value.
142         This function should behave just like a kernel call, setting
143         errno and returning -1 in case of an error.  This function MUST
144         check to make sure that a non-root user does not specify a nice
145         value less than the process's current value.  If it detects such
146         a condition, it should set errno to EACCES and return -1.
147         Other possible ERRNO values:  ESRCH when pid "who" does not exist,
148         EPERM when the invoker is not root and not the same as the
149         process owner.
150
151 Note that top checks process ownership and should never call setpriority
152 when the invoker's uid is not root and not the same as the process's owner
153 uid.
154
155
156 The file "machine.h" contains definitions which are useful to modules
157 and to top.c (such as the structure definitions).  You SHOULD NOT need
158 to change it when porting to a new platform.
159
160 Porting to a new platform should NOT require any changes to existing
161 files.  You should only need to add m_ files.  If you feel you need a
162 change in one of the existing files, please contact me so that we can
163 discuss the details.  I want to keep such changes as general as
164 possible.
165