summaryrefslogtreecommitdiff
path: root/corebinutils/ps/ps.h
blob: fd18e6ef8f618f4fbcde7ee734be7fe2c0f4aaee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*-
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright (c) 1990, 1993
 *	The Regents of the University of California.  All rights reserved.
 * Copyright (c) 2026 Project Tick. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Linux-native port: replaces BSD kinfo_proc with a Linux-compatible equivalent
 * that can be filled from /proc.
 */

#ifndef _PS_H_
#define _PS_H_

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdbool.h>

/* Minimal STAILQ for musl-gcc compatibility */
#define STAILQ_HEAD(name, type) \
struct name { struct type *stqh_first; struct type **stqh_last; }
#define STAILQ_HEAD_INITIALIZER(head) { NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { struct type *stqe_next; }
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_INIT(head) do { (head)->stqh_first = NULL; (head)->stqh_last = &(head)->stqh_first; } while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
	(elm)->field.stqe_next = NULL; \
	*(head)->stqh_last = (elm); \
	(head)->stqh_last = &(elm)->field.stqe_next; \
} while (0)
#define STAILQ_FOREACH(var, head, field) \
	for ((var) = STAILQ_FIRST(head); (var); (var) = STAILQ_NEXT(var, field))
#define STAILQ_CONCAT(head1, head2) do { \
	if (!STAILQ_EMPTY(head2)) { \
		*(head1)->stqh_last = (head2)->stqh_first; \
		(head1)->stqh_last = (head2)->stqh_last; \
		STAILQ_INIT(head2); \
	} \
} while (0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
		(head)->stqh_last = &(head)->stqh_first; \
} while (0)

#define UNLIMITED 0

#ifndef __unused
#define __unused __attribute__((__unused__))
#endif

#define COMMLEN 256
#define WMESGLEN 64
#define KI_NGROUPS 16

/* Linux-port version of kinfo_proc to store data from /proc */
struct kinfo_proc {
	pid_t    ki_pid;
	pid_t    ki_ppid;
	pid_t    ki_pgid;
	pid_t    ki_sid;
	dev_t    ki_tdev;
	pid_t    ki_tpgid;
	uid_t    ki_uid;
	uid_t    ki_ruid;
	uid_t    ki_svuid;
	gid_t    ki_groups[KI_NGROUPS];
	gid_t    ki_rgid;
	gid_t    ki_svgid;
	char     ki_comm[COMMLEN];
	char     ki_tdname[64];
	char     ki_moretdname[64];
	struct timeval ki_start;
	uint64_t ki_runtime; // in microseconds
	uint64_t ki_size;    // VSZ in bytes
	uint64_t ki_rssize;  // RSS in pages
	uint64_t ki_tsize;   // Text size in pages (hard to get precise on Linux)
	uint64_t ki_dsize;   // Data size in pages
	uint64_t ki_ssize;   // Stack size in pages
	int      ki_nice;
	int      ki_pri_level;
	int      ki_pri_class;
	char     ki_stat;    // BSD-like state character (S, R, T, Z, D)
	long     ki_flag;    // Linux task flags
	char     ki_wmesg[WMESGLEN];
	int      ki_numthreads;
	long     ki_slptime; // time since last running (approximate)
	int      ki_oncpu;
	int      ki_lastcpu;
	int      ki_jid;     // Always 0 on Linux
	char     ki_login[64]; // placeholder for logname
	struct rusage ki_rusage; // approximate from /proc/pid/stat
	struct timeval ki_childtime; // placeholder for sumrusage
	struct timeval ki_childstime; 
	struct timeval ki_childutime;
};

/* Compatibility aliases for FreeBSD KVM-based fields used in print.c */
#define ki_pri ki_pri_level

typedef long fixpt_t;
typedef uint64_t segsz_t;

enum type { UNSPEC, CHAR, UCHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, KPTR, PGTOK };

typedef struct kinfo_str {
	STAILQ_ENTRY(kinfo_str) ks_next;
	char *ks_str;	/* formatted string */
} KINFO_STR;

typedef struct kinfo {
	struct kinfo_proc *ki_p;	/* kinfo_proc structure */
	char *ki_args;		/* exec args (heap) */
	char *ki_env;		/* environment (heap) */
	int ki_valid;		/* 1 => data valid */
	double ki_pcpu;		/* calculated in main() */
	segsz_t ki_memsize;	/* calculated in main() */
	union {
		int level;	/* used in descendant_sort() */
		char *prefix;	/* prefix string for tree-view */
	} ki_d;
	STAILQ_HEAD(, kinfo_str) ki_ks;
} KINFO;

struct var;
typedef struct var VAR;

typedef struct varent {
	STAILQ_ENTRY(varent) next_ve;
	const char *header;
	const struct var *var;
	u_int width;
#define VE_KEEP (1 << 0)
	uint16_t flags;
} VARENT;

STAILQ_HEAD(velisthead, varent);

struct var {
	const char *name;
	union {
		const char *aliased;
		const VAR *final_kw;
	};
	const char *header;
	const char *field;
#define COMM 0x01
#define LJUST 0x02
#define USER 0x04
#define INF127 0x10
#define NOINHERIT 0x1000
#define RESOLVING_ALIAS 0x10000
#define RESOLVED_ALIAS 0x20000
	u_int flag;
	char *(*oproc)(struct kinfo *, struct varent *);
	size_t off;
	enum type type;
	const char *fmt;
};

#define KERN_PROC_PROC      0
#define KERN_PROC_THREAD    1
#define KERN_PROC_INC_THREAD 2
#define KERN_PROC_ALL       3

/* Don't define these if they conflict with system headers */
#ifndef NZERO
#define NZERO 20
#endif

/* Linux PRI mapping */
#define PUSER 0

#include "extern.h"

#endif /* _PS_H_ */