build-sys: Relocate library to library/

All the dependent programs needed to have their includes moved too

Signed-off-by: Craig Small <csmall@dropbear.xyz>
This commit is contained in:
Craig Small
2022-08-29 19:02:44 +10:00
parent 406b6d311c
commit 3d0871728b
55 changed files with 137 additions and 137 deletions

6
library/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
test_Itemtables
test_namespace
test_pids
test_sysinfo
test_uptime
test_version

481
library/COPYING Normal file
View File

@@ -0,0 +1,481 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

361
library/devname.c Normal file
View File

@@ -0,0 +1,361 @@
/*
* devname - device name functions
* Copyright 1998-2002 by Albert Cahalan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "misc.h"
#include "devname.h"
// This is the buffer size for a tty name. Any path is legal,
// which makes PAGE_SIZE appropriate (see kernel source), but
// that is only 99% portable and utmp only holds 32 anyway.
// We need at least 20 for guess_name().
#define TTY_NAME_SIZE 128
/* Who uses what:
*
* dev_to_tty top, ps
*/
#ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#elif defined MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#else
#define major(d) ( ((unsigned)(d)>>8u) & 0xfffu )
#define minor(d) ( ((unsigned)(d)&0xffu) | (((unsigned)(d)&0xfff00000u)>>12u) )
#endif
typedef struct tty_map_node {
struct tty_map_node *next;
unsigned short devfs_type; // bool
unsigned short major_number;
unsigned minor_first;
unsigned minor_last;
char name[16];
} tty_map_node;
static __thread tty_map_node *tty_map = NULL;
/* Load /proc/tty/drivers for device name mapping use. */
static void load_drivers(void){
char buf[10000];
char *p;
int fd;
int bytes;
fd = open("/proc/tty/drivers",O_RDONLY);
if(fd == -1) goto fail;
bytes = read(fd, buf, sizeof(buf) - 1);
if(bytes == -1) goto fail;
buf[bytes] = '\0';
p = buf;
while(( p = strstr(p, " /dev/") )){ // " /dev/" is the second column
tty_map_node *tmn;
size_t len;
char *end;
p += 6;
end = strchr(p, ' ');
if(!end) continue;
len = end - p;
if (!(tmn = calloc(1, sizeof(tty_map_node))))
goto fail;
tmn->next = tty_map;
tty_map = tmn;
/* if we have a devfs type name such as /dev/tts/%d then strip the %d but
keep a flag. */
if(len >= 3 && !strncmp(end - 2, "%d", 2)){
len -= 2;
tmn->devfs_type = 1;
}
if(len >= sizeof tmn->name)
len = sizeof tmn->name - 1; // mangle it to avoid overflow
memcpy(tmn->name, p, len);
p = end; /* set p to point past the %d as well if there is one */
while(*p == ' ') p++;
tmn->major_number = atoi(p);
p += strspn(p, "0123456789");
while(*p == ' ') p++;
switch(sscanf(p, "%u-%u", &tmn->minor_first, &tmn->minor_last)){
default:
/* Can't finish parsing this line so we remove it from the list */
tty_map = tty_map->next;
free(tmn);
break;
case 1:
tmn->minor_last = tmn->minor_first;
break;
case 2:
break;
}
}
fail:
if(fd != -1) close(fd);
if(!tty_map) tty_map = (tty_map_node *)-1;
}
/* Try to guess the device name from /proc/tty/drivers info. */
static int driver_name(char *restrict const buf, unsigned maj, unsigned min){
struct stat sbuf;
tty_map_node *tmn;
if(!tty_map) load_drivers();
if(tty_map == (tty_map_node *)-1) return 0;
tmn = tty_map;
for(;;){
if(!tmn) return 0;
if(tmn->major_number == maj && tmn->minor_first <= min && tmn->minor_last >= min) break;
tmn = tmn->next;
}
sprintf(buf, "/dev/%s%d", tmn->name, min); /* like "/dev/ttyZZ255" */
if(stat(buf, &sbuf) < 0){
sprintf(buf, "/dev/%s/%d", tmn->name, min); /* like "/dev/pts/255" */
if(stat(buf, &sbuf) < 0){
if(tmn->devfs_type) return 0;
sprintf(buf, "/dev/%s", tmn->name); /* like "/dev/ttyZZ255" */
if(stat(buf, &sbuf) < 0) return 0;
}
}
if(min != minor(sbuf.st_rdev)) return 0;
if(maj != major(sbuf.st_rdev)) return 0;
return 1;
}
// major 204 is a mess -- "Low-density serial ports"
static const char low_density_names[][6] = {
"LU0", "LU1", "LU2", "LU3",
"FB0",
"SA0", "SA1", "SA2",
"SC0", "SC1", "SC2", "SC3",
"FW0", "FW1", "FW2", "FW3",
"AM0", "AM1", "AM2", "AM3", "AM4", "AM5", "AM6", "AM7",
"AM8", "AM9", "AM10", "AM11", "AM12", "AM13", "AM14", "AM15",
"DB0", "DB1", "DB2", "DB3", "DB4", "DB5", "DB6", "DB7",
"SG0",
"SMX0", "SMX1", "SMX2",
"MM0", "MM1",
"CPM0", "CPM1", "CPM2", "CPM3", /* "CPM4", "CPM5", */ // bad allocation?
"IOC0", "IOC1", "IOC2", "IOC3", "IOC4", "IOC5", "IOC6", "IOC7",
"IOC8", "IOC9", "IOC10", "IOC11", "IOC12", "IOC13", "IOC14", "IOC15",
"IOC16", "IOC17", "IOC18", "IOC19", "IOC20", "IOC21", "IOC22", "IOC23",
"IOC24", "IOC25", "IOC26", "IOC27", "IOC28", "IOC29", "IOC30", "IOC31",
"VR0", "VR1",
"IOC84", "IOC85", "IOC86", "IOC87", "IOC88", "IOC89", "IOC90", "IOC91",
"IOC92", "IOC93", "IOC94", "IOC95", "IOC96", "IOC97", "IOC98", "IOC99",
"IOC100", "IOC101", "IOC102", "IOC103", "IOC104", "IOC105", "IOC106", "IOC107",
"IOC108", "IOC109", "IOC110", "IOC111", "IOC112", "IOC113", "IOC114", "IOC115",
"SIOC0", "SIOC1", "SIOC2", "SIOC3", "SIOC4", "SIOC5", "SIOC6", "SIOC7",
"SIOC8", "SIOC9", "SIOC10", "SIOC11", "SIOC12", "SIOC13", "SIOC14", "SIOC15",
"SIOC16", "SIOC17", "SIOC18", "SIOC19", "SIOC20", "SIOC21", "SIOC22", "SIOC23",
"SIOC24", "SIOC25", "SIOC26", "SIOC27", "SIOC28", "SIOC29", "SIOC30", "SIOC31",
"PSC0", "PSC1", "PSC2", "PSC3", "PSC4", "PSC5",
"AT0", "AT1", "AT2", "AT3", "AT4", "AT5", "AT6", "AT7",
"AT8", "AT9", "AT10", "AT11", "AT12", "AT13", "AT14", "AT15",
"NX0", "NX1", "NX2", "NX3", "NX4", "NX5", "NX6", "NX7",
"NX8", "NX9", "NX10", "NX11", "NX12", "NX13", "NX14", "NX15",
"J0", // minor is 186
"UL0","UL1","UL2","UL3",
"xvc0", // FAIL -- "/dev/xvc0" lacks "tty" prefix
"PZ0","PZ1","PZ2","PZ3",
"TX0","TX1","TX2","TX3","TX4","TX5","TX6","TX7",
"SC0","SC1","SC2","SC3",
"MAX0","MAX1","MAX2","MAX3",
};
#if 0
// test code
#include <stdio.h>
#define AS(x) (sizeof(x)/sizeof((x)[0]))
int main(int argc, char *argv[]){
int i = 0;
while(i<AS(low_density_names)){
printf("%3d = /dev/tty%.*s\n",i,sizeof low_density_names[i],low_density_names[i]);
i++;
}
return 0;
}
#endif
/* Try to guess the device name (useful until /proc/PID/tty is added) */
static int guess_name(char *restrict const buf, unsigned maj, unsigned min){
struct stat sbuf;
#ifndef __CYGWIN__
int t0, t1;
#endif
unsigned tmpmin = min;
switch(maj){
case 3: /* /dev/[pt]ty[p-za-o][0-9a-z] is 936 */
if(tmpmin > 255) return 0; // should never happen; array index protection
#ifdef __CYGWIN__
sprintf(buf, "cons%d", tmpmin);
/* Skip stat call. The reason is that cons devices are local to
* the processes running in that console. Calling stat from another
* console or pty will return -1. */
return 1;
#else
t0 = "pqrstuvwxyzabcde"[tmpmin>>4];
t1 = "0123456789abcdef"[tmpmin&0x0f];
sprintf(buf, "/dev/tty%c%c", t0, t1);
#endif
break;
case 4:
if(min<64){
sprintf(buf, "/dev/tty%d", min);
break;
}
sprintf(buf, "/dev/ttyS%d", min-64);
break;
case 11: sprintf(buf, "/dev/ttyB%d", min); break;
case 17: sprintf(buf, "/dev/ttyH%d", min); break;
case 19: sprintf(buf, "/dev/ttyC%d", min); break;
case 22: sprintf(buf, "/dev/ttyD%d", min); break; /* devices.txt */
case 23: sprintf(buf, "/dev/ttyD%d", min); break; /* driver code */
case 24: sprintf(buf, "/dev/ttyE%d", min); break;
case 32: sprintf(buf, "/dev/ttyX%d", min); break;
case 43: sprintf(buf, "/dev/ttyI%d", min); break;
case 46: sprintf(buf, "/dev/ttyR%d", min); break;
case 48: sprintf(buf, "/dev/ttyL%d", min); break;
case 57: sprintf(buf, "/dev/ttyP%d", min); break;
case 71: sprintf(buf, "/dev/ttyF%d", min); break;
case 75: sprintf(buf, "/dev/ttyW%d", min); break;
case 78: sprintf(buf, "/dev/ttyM%d", min); break; /* conflict */
case 105: sprintf(buf, "/dev/ttyV%d", min); break;
case 112: sprintf(buf, "/dev/ttyM%d", min); break; /* conflict */
#ifdef __CYGWIN__
case 136: sprintf(buf, "/dev/pty%d", min); break;
#else
/* 136 ... 143 are /dev/pts/0, /dev/pts/1, /dev/pts/2 ... */
case 136 ... 143: sprintf(buf, "/dev/pts/%d", min+(maj-136)*256); break;
#endif
case 148: sprintf(buf, "/dev/ttyT%d", min); break;
case 154: sprintf(buf, "/dev/ttySR%d", min); break;
case 156: sprintf(buf, "/dev/ttySR%d", min+256); break;
case 164: sprintf(buf, "/dev/ttyCH%d", min); break;
case 166: sprintf(buf, "/dev/ttyACM%d", min); break; /* bummer, 9-char */
case 172: sprintf(buf, "/dev/ttyMX%d", min); break;
case 174: sprintf(buf, "/dev/ttySI%d", min); break;
case 188: sprintf(buf, "/dev/ttyUSB%d", min); break; /* bummer, 9-char */
case 204:
if(min >= sizeof low_density_names / sizeof low_density_names[0]) return 0;
memcpy(buf,"/dev/tty",8);
memcpy(buf+8, low_density_names[min], sizeof low_density_names[0]);
buf[8 + sizeof low_density_names[0]] = '\0';
// snprintf(buf, 9 + sizeof low_density_names[0], "/dev/tty%.*s", sizeof low_density_names[0], low_density_names[min]);
break;
case 208: sprintf(buf, "/dev/ttyU%d", min); break;
case 216: sprintf(buf, "/dev/ttyUB%d", min); break; // "/dev/rfcomm%d" now?
case 224: sprintf(buf, "/dev/ttyY%d", min); break;
case 227: sprintf(buf, "/dev/3270/tty%d", min); break; /* bummer, HUGE */
case 229: sprintf(buf, "/dev/iseries/vtty%d", min); break; /* bummer, HUGE */
case 256: sprintf(buf, "/dev/ttyEQ%d", min); break;
default: return 0;
}
if(stat(buf, &sbuf) < 0) return 0;
if(min != minor(sbuf.st_rdev)) return 0;
if(maj != major(sbuf.st_rdev)) return 0;
return 1;
}
/* Linux 2.2 can give us filenames that might be correct.
* Useful names could be in /proc/PID/fd/2 (stderr, seldom redirected)
* and in /proc/PID/fd/255 (used by bash to remember the tty).
*/
static int link_name(char *restrict const buf, unsigned maj, unsigned min, int pid, const char *restrict name){
struct stat sbuf;
char path[32];
ssize_t count;
const int len = snprintf(path, sizeof path, "/proc/%d/%s", pid, name); /* often permission denied */
if(len <= 0 || (size_t)len >= sizeof path) return 0;
count = readlink(path,buf,TTY_NAME_SIZE-1);
if(count <= 0 || count >= TTY_NAME_SIZE-1) return 0;
buf[count] = '\0';
if(stat(buf, &sbuf) < 0) return 0;
if(min != minor(sbuf.st_rdev)) return 0;
if(maj != major(sbuf.st_rdev)) return 0;
return 1;
}
#ifdef USE_PROC_CTTY
/* Cygwin keeps the name to the controlling tty in a virtual file called
/proc/PID/ctty, including a trailing LF (sigh). */
static int ctty_name(char *restrict const buf, int pid) {
char path[32];
FILE *fp;
char *lf;
sprintf (path, "/proc/%d/ctty", pid); /* often permission denied */
fp = fopen (path, "r");
if (!fp)
return 0;
if (!fgets (buf,TTY_NAME_SIZE,fp))
{
fclose (fp);
return 0;
}
fclose (fp);
lf = strchr (buf, '\n');
if (lf)
*lf = (lf == buf ? '?' : '\0');
return 1;
}
#endif
/* number --> name */
unsigned dev_to_tty(char *restrict ret, unsigned chop, dev_t dev_t_dev, int pid, unsigned int flags) {
static __thread char buf[TTY_NAME_SIZE];
char *restrict tmp = buf;
unsigned dev = dev_t_dev;
unsigned i = 0;
int c;
#ifdef USE_PROC_CTTY
if( ctty_name(tmp, pid )) goto abbrev;
#endif
if(dev == 0u) goto no_tty;
if(driver_name(tmp, major(dev), minor(dev) )) goto abbrev;
if( link_name(tmp, major(dev), minor(dev), pid, "fd/2" )) goto abbrev;
if( guess_name(tmp, major(dev), minor(dev) )) goto abbrev;
if( link_name(tmp, major(dev), minor(dev), pid, "fd/255")) goto abbrev;
// fall through if unable to find a device file
no_tty:
strcpy(ret, chop >= 1 ? "?" : "");
return 1;
abbrev:
if((flags&ABBREV_DEV) && !strncmp(tmp,"/dev/",5) && tmp[5]) tmp += 5;
if((flags&ABBREV_TTY) && !strncmp(tmp,"tty", 3) && tmp[3]) tmp += 3;
if((flags&ABBREV_PTS) && !strncmp(tmp,"pts/", 4) && tmp[4]) tmp += 4;
/* gotta check before we chop or we may chop someone else's memory */
if(chop + (unsigned long)(tmp-buf) < sizeof buf)
tmp[chop] = '\0';
/* replace non-ASCII characters with '?' and return the number of chars */
while(i < chop){
c = *tmp;
tmp++;
if(!c) break;
i++;
if(c<=' ') c = '?';
if(c>126) c = '?';
*ret = c;
ret++;
}
*ret = '\0';
return i;
}

1027
library/diskstats.c Normal file

File diff suppressed because it is too large Load Diff

142
library/escape.c Normal file
View File

@@ -0,0 +1,142 @@
/*
* escape.c - printing handling
* Copyright 1998-2002 by Albert Cahalan
* Copyright 2020-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "escape.h"
#include "readproc.h"
#include "nls.h"
#define SECURE_ESCAPE_ARGS(dst, bytes) do { \
if ((bytes) <= 0) return 0; \
*(dst) = '\0'; \
if ((bytes) >= INT_MAX) return 0; \
} while (0)
static const char UTF_tab[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 0x0F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 0x1F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 0x2F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 0x3F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 0x4F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 0x5F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6F
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 0x7F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 0x80 - 0x8F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 0x90 - 0x9F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 0xA0 - 0xAF
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 0xB0 - 0xBF
-1,-1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xC0 - 0xCF
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xD0 - 0xDF
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xE0 - 0xEF
4, 4, 4, 4, 4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 0xF0 - 0xFF
};
static const unsigned char ESC_tab[] = {
"@..............................." // 0x00 - 0x1F
"||||||||||||||||||||||||||||||||" // 0x20 - 0x3F
"||||||||||||||||||||||||||||||||" // 0x40 - 0x5f
"|||||||||||||||||||||||||||||||." // 0x60 - 0x7F
"????????????????????????????????" // 0x80 - 0x9F
"????????????????????????????????" // 0xA0 - 0xBF
"????????????????????????????????" // 0xC0 - 0xDF
"????????????????????????????????" // 0xE0 - 0xFF
};
static inline void esc_all (unsigned char *str) {
unsigned char c;
// if bad locale/corrupt str, replace non-printing stuff
while (*str) {
if ((c = ESC_tab[*str]) != '|')
*str = c;
++str;
}
}
static inline void esc_ctl (unsigned char *str, int len) {
int i, n;
for (i = 0; i < len; ) {
// even with a proper locale, strings might be corrupt
if ((n = UTF_tab[*str]) < 0 || i + n > len) {
esc_all(str);
return;
}
// and eliminate those non-printing control characters
if (*str < 0x20 || *str == 0x7f)
*str = '?';
str += n;
i += n;
}
}
int escape_str (char *dst, const char *src, int bufsize) {
static __thread int utf_sw = 0;
int n;
if (utf_sw == 0) {
char *enc = nl_langinfo(CODESET);
utf_sw = enc && strcasecmp(enc, "UTF-8") == 0 ? 1 : -1;
}
SECURE_ESCAPE_ARGS(dst, bufsize);
n = snprintf(dst, bufsize, "%s", src);
if (n < 0) {
*dst = '\0';
return 0;
}
if (n >= bufsize) n = bufsize-1;
if (utf_sw < 0)
esc_all((unsigned char *)dst);
else
esc_ctl((unsigned char *)dst, n);
return n;
}
int escape_command (char *outbuf, const proc_t *pp, int bytes, unsigned flags) {
int overhead = 0;
int end = 0;
if (flags & ESC_BRACKETS)
overhead += 2;
if (flags & ESC_DEFUNCT) {
if (pp->state == 'Z') overhead += 10; // chars in " <defunct>"
else flags &= ~ESC_DEFUNCT;
}
if (overhead + 1 >= bytes) {
// if no room for even one byte of the command name
outbuf[0] = '\0';
return 0;
}
if (flags & ESC_BRACKETS)
outbuf[end++] = '[';
end += escape_str(outbuf+end, pp->cmd, bytes-overhead);
// we want "[foo] <defunct>", not "[foo <defunct>]"
if (flags & ESC_BRACKETS)
outbuf[end++] = ']';
if (flags & ESC_DEFUNCT) {
memcpy(outbuf+end, " <defunct>", 10);
end += 10;
}
outbuf[end] = '\0';
return end; // bytes, not including the NUL
}

10
library/include/devname.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef PROC_DEVNAME_H
#define PROC_DEVNAME_H
#define ABBREV_DEV 1 /* remove /dev/ */
#define ABBREV_TTY 2 /* remove tty */
#define ABBREV_PTS 4 /* remove pts/ */
unsigned dev_to_tty(char *__restrict ret, unsigned chop, dev_t dev_t_dev, int pid, unsigned int flags);
#endif

137
library/include/diskstats.h Normal file
View File

@@ -0,0 +1,137 @@
/*
* diskstat.c - disk I/O related declarations for libprocps
*
* Copyright (c) 2003 Fabian Frederick
* Copyright (C) 2003 Albert Cahalan
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
* Copyright (C) 2016-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_DISKSTATS_H
#define PROCPS_DISKSTATS_H
#ifdef __cplusplus
extern "C" {
#endif
enum diskstats_item {
DISKSTATS_noop, // ( never altered )
DISKSTATS_extra, // ( reset to zero )
// returns origin, see proc(5)
// ------- -------------------
DISKSTATS_NAME, // str /proc/diskstats
DISKSTATS_TYPE, // s_int "
DISKSTATS_MAJOR, // s_int "
DISKSTATS_MINOR, // s_int "
DISKSTATS_READS, // ul_int "
DISKSTATS_READS_MERGED, // ul_int "
DISKSTATS_READ_SECTORS, // ul_int "
DISKSTATS_READ_TIME, // ul_int "
DISKSTATS_WRITES, // ul_int "
DISKSTATS_WRITES_MERGED, // ul_int "
DISKSTATS_WRITE_SECTORS, // ul_int "
DISKSTATS_WRITE_TIME, // ul_int "
DISKSTATS_IO_TIME, // ul_int "
DISKSTATS_WEIGHTED_TIME, // ul_int "
DISKSTATS_IO_INPROGRESS, // s_int "
DISKSTATS_DELTA_READS, // s_int derived from above
DISKSTATS_DELTA_READS_MERGED, // s_int "
DISKSTATS_DELTA_READ_SECTORS, // s_int "
DISKSTATS_DELTA_READ_TIME, // s_int "
DISKSTATS_DELTA_WRITES, // s_int "
DISKSTATS_DELTA_WRITES_MERGED, // s_int "
DISKSTATS_DELTA_WRITE_SECTORS, // s_int "
DISKSTATS_DELTA_WRITE_TIME, // s_int "
DISKSTATS_DELTA_IO_TIME, // s_int "
DISKSTATS_DELTA_WEIGHTED_TIME // s_int "
};
enum diskstats_sort_order {
DISKSTATS_SORT_ASCEND = +1,
DISKSTATS_SORT_DESCEND = -1
};
struct diskstats_result {
enum diskstats_item item;
union {
signed int s_int;
unsigned long ul_int;
char *str;
} result;
};
struct diskstats_stack {
struct diskstats_result *head;
};
struct diskstats_reaped {
int total;
struct diskstats_stack **stacks;
};
struct diskstats_info;
#define DISKSTATS_TYPE_DISK -11111
#define DISKSTATS_TYPE_PARTITION -22222
#define DISKSTATS_GET( info, name, actual_enum, type ) ( { \
struct diskstats_result *r = procps_diskstats_get( info, name, actual_enum ); \
r ? r->result . type : 0; } )
#define DISKSTATS_VAL( relative_enum, type, stack, info ) \
stack -> head [ relative_enum ] . result . type
int procps_diskstats_new (struct diskstats_info **info);
int procps_diskstats_ref (struct diskstats_info *info);
int procps_diskstats_unref (struct diskstats_info **info);
struct diskstats_result *procps_diskstats_get (
struct diskstats_info *info,
const char *name,
enum diskstats_item item);
struct diskstats_reaped *procps_diskstats_reap (
struct diskstats_info *info,
enum diskstats_item *items,
int numitems);
struct diskstats_stack *procps_diskstats_select (
struct diskstats_info *info,
const char *name,
enum diskstats_item *items,
int numitems);
struct diskstats_stack **procps_diskstats_sort (
struct diskstats_info *info,
struct diskstats_stack *stacks[],
int numstacked,
enum diskstats_item sortitem,
enum diskstats_sort_order order);
#ifdef XTRA_PROCPS_DEBUG
# include "xtra-procps-debug.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

33
library/include/escape.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* escape.h - printing handling
* Copyright 1998-2002 by Albert Cahalan
* Copyright 2020-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_PROC_ESCAPE_H
#define PROCPS_PROC_ESCAPE_H
#include "readproc.h"
#define ESC_BRACKETS 0x2 // if using cmd, put '[' and ']' around it
#define ESC_DEFUNCT 0x4 // mark zombies with " <defunct>"
int escape_command (char *outbuf, const proc_t *pp, int bytes, unsigned flags);
int escape_str (char *dst, const char *src, int bufsize);
#endif

216
library/include/meminfo.h Normal file
View File

@@ -0,0 +1,216 @@
/*
* meminfo.h - memory related declarations for libprocps
*
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
* Copyright (C) 2016-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_MEMINFO_H
#define PROCPS_MEMINFO_H
#ifdef __cplusplus
extern "C" {
#endif
enum meminfo_item {
MEMINFO_noop, // ( never altered )
MEMINFO_extra, // ( reset to zero )
/*
note: all of the following values are expressed as KiB
*/
// returns origin, see proc(5)
// ------- -------------------
MEMINFO_MEM_ACTIVE, // ul_int /proc/meminfo
MEMINFO_MEM_ACTIVE_ANON, // ul_int "
MEMINFO_MEM_ACTIVE_FILE, // ul_int "
MEMINFO_MEM_ANON, // ul_int "
MEMINFO_MEM_AVAILABLE, // ul_int "
MEMINFO_MEM_BOUNCE, // ul_int "
MEMINFO_MEM_BUFFERS, // ul_int "
MEMINFO_MEM_CACHED, // ul_int "
MEMINFO_MEM_CACHED_ALL, // ul_int derived from MEM_CACHED + MEM_SLAB_RECLAIM
MEMINFO_MEM_CMA_FREE, // ul_int /proc/meminfo
MEMINFO_MEM_CMA_TOTAL, // ul_int "
MEMINFO_MEM_COMMITTED_AS, // ul_int "
MEMINFO_MEM_COMMIT_LIMIT, // ul_int "
MEMINFO_MEM_DIRECTMAP_1G, // ul_int "
MEMINFO_MEM_DIRECTMAP_2M, // ul_int "
MEMINFO_MEM_DIRECTMAP_4K, // ul_int "
MEMINFO_MEM_DIRECTMAP_4M, // ul_int "
MEMINFO_MEM_DIRTY, // ul_int "
MEMINFO_MEM_FILE_HUGEPAGES, // ul_int "
MEMINFO_MEM_FILE_PMDMAPPED, // ul_int "
MEMINFO_MEM_FREE, // ul_int "
MEMINFO_MEM_HARD_CORRUPTED, // ul_int "
MEMINFO_MEM_HIGH_FREE, // ul_int "
MEMINFO_MEM_HIGH_TOTAL, // ul_int "
MEMINFO_MEM_HIGH_USED, // ul_int derived from MEM_HIGH_TOTAL - MEM_HIGH_FREE
MEMINFO_MEM_HUGETBL, // ul_int /proc/meminfo
MEMINFO_MEM_HUGE_ANON, // ul_int "
MEMINFO_MEM_HUGE_FREE, // ul_int "
MEMINFO_MEM_HUGE_RSVD, // ul_int "
MEMINFO_MEM_HUGE_SIZE, // ul_int "
MEMINFO_MEM_HUGE_SURPLUS, // ul_int "
MEMINFO_MEM_HUGE_TOTAL, // ul_int "
MEMINFO_MEM_INACTIVE, // ul_int "
MEMINFO_MEM_INACTIVE_ANON, // ul_int "
MEMINFO_MEM_INACTIVE_FILE, // ul_int "
MEMINFO_MEM_KERNEL_RECLAIM, // ul_int "
MEMINFO_MEM_KERNEL_STACK, // ul_int "
MEMINFO_MEM_LOCKED, // ul_int "
MEMINFO_MEM_LOW_FREE, // ul_int "
MEMINFO_MEM_LOW_TOTAL, // ul_int "
MEMINFO_MEM_LOW_USED, // ul_int derived from MEM_LOW_TOTAL - MEM_LOW_FREE
MEMINFO_MEM_MAPPED, // ul_int /proc/meminfo
MEMINFO_MEM_MAP_COPY, // ul_int "
MEMINFO_MEM_NFS_UNSTABLE, // ul_int "
MEMINFO_MEM_PAGE_TABLES, // ul_int "
MEMINFO_MEM_PER_CPU, // ul_int "
MEMINFO_MEM_SHADOWCALLSTACK, // ul_int "
MEMINFO_MEM_SHARED, // ul_int "
MEMINFO_MEM_SHMEM_HUGE, // ul_int "
MEMINFO_MEM_SHMEM_HUGE_MAP, // ul_int "
MEMINFO_MEM_SLAB, // ul_int "
MEMINFO_MEM_SLAB_RECLAIM, // ul_int "
MEMINFO_MEM_SLAB_UNRECLAIM, // ul_int "
MEMINFO_MEM_TOTAL, // ul_int "
MEMINFO_MEM_UNEVICTABLE, // ul_int "
MEMINFO_MEM_USED, // ul_int derived from MEM_TOTAL - MEM_AVAILABLE
MEMINFO_MEM_VM_ALLOC_CHUNK, // ul_int /proc/meminfo
MEMINFO_MEM_VM_ALLOC_TOTAL, // ul_int "
MEMINFO_MEM_VM_ALLOC_USED, // ul_int "
MEMINFO_MEM_WRITEBACK, // ul_int "
MEMINFO_MEM_WRITEBACK_TMP, // ul_int "
MEMINFO_DELTA_ACTIVE, // s_int derived from above
MEMINFO_DELTA_ACTIVE_ANON, // s_int "
MEMINFO_DELTA_ACTIVE_FILE, // s_int "
MEMINFO_DELTA_ANON, // s_int "
MEMINFO_DELTA_AVAILABLE, // s_int "
MEMINFO_DELTA_BOUNCE, // s_int "
MEMINFO_DELTA_BUFFERS, // s_int "
MEMINFO_DELTA_CACHED, // s_int "
MEMINFO_DELTA_CACHED_ALL, // s_int "
MEMINFO_DELTA_CMA_FREE, // s_int "
MEMINFO_DELTA_CMA_TOTAL, // s_int "
MEMINFO_DELTA_COMMITTED_AS, // s_int "
MEMINFO_DELTA_COMMIT_LIMIT, // s_int "
MEMINFO_DELTA_DIRECTMAP_1G, // s_int "
MEMINFO_DELTA_DIRECTMAP_2M, // s_int "
MEMINFO_DELTA_DIRECTMAP_4K, // s_int "
MEMINFO_DELTA_DIRECTMAP_4M, // s_int "
MEMINFO_DELTA_DIRTY, // s_int "
MEMINFO_DELTA_FILE_HUGEPAGES, // s_int "
MEMINFO_DELTA_FILE_PMDMAPPED, // s_int "
MEMINFO_DELTA_FREE, // s_int "
MEMINFO_DELTA_HARD_CORRUPTED, // s_int "
MEMINFO_DELTA_HIGH_FREE, // s_int "
MEMINFO_DELTA_HIGH_TOTAL, // s_int "
MEMINFO_DELTA_HIGH_USED, // s_int "
MEMINFO_DELTA_HUGETBL, // s_int "
MEMINFO_DELTA_HUGE_ANON, // s_int "
MEMINFO_DELTA_HUGE_FREE, // s_int "
MEMINFO_DELTA_HUGE_RSVD, // s_int "
MEMINFO_DELTA_HUGE_SIZE, // s_int "
MEMINFO_DELTA_HUGE_SURPLUS, // s_int "
MEMINFO_DELTA_HUGE_TOTAL, // s_int "
MEMINFO_DELTA_INACTIVE, // s_int "
MEMINFO_DELTA_INACTIVE_ANON, // s_int "
MEMINFO_DELTA_INACTIVE_FILE, // s_int "
MEMINFO_DELTA_KERNEL_RECLAIM, // s_int "
MEMINFO_DELTA_KERNEL_STACK, // s_int "
MEMINFO_DELTA_LOCKED, // s_int "
MEMINFO_DELTA_LOW_FREE, // s_int "
MEMINFO_DELTA_LOW_TOTAL, // s_int "
MEMINFO_DELTA_LOW_USED, // s_int "
MEMINFO_DELTA_MAPPED, // s_int "
MEMINFO_DELTA_MAP_COPY, // s_int "
MEMINFO_DELTA_NFS_UNSTABLE, // s_int "
MEMINFO_DELTA_PAGE_TABLES, // s_int "
MEMINFO_DELTA_PER_CPU, // s_int "
MEMINFO_DELTA_SHADOWCALLSTACK, // s_int "
MEMINFO_DELTA_SHARED, // s_int "
MEMINFO_DELTA_SHMEM_HUGE, // s_int "
MEMINFO_DELTA_SHMEM_HUGE_MAP, // s_int "
MEMINFO_DELTA_SLAB, // s_int "
MEMINFO_DELTA_SLAB_RECLAIM, // s_int "
MEMINFO_DELTA_SLAB_UNRECLAIM, // s_int "
MEMINFO_DELTA_TOTAL, // s_int "
MEMINFO_DELTA_UNEVICTABLE, // s_int "
MEMINFO_DELTA_USED, // s_int "
MEMINFO_DELTA_VM_ALLOC_CHUNK, // s_int "
MEMINFO_DELTA_VM_ALLOC_TOTAL, // s_int "
MEMINFO_DELTA_VM_ALLOC_USED, // s_int "
MEMINFO_DELTA_WRITEBACK, // s_int "
MEMINFO_DELTA_WRITEBACK_TMP, // s_int "
MEMINFO_SWAP_CACHED, // ul_int /proc/meminfo
MEMINFO_SWAP_FREE, // ul_int "
MEMINFO_SWAP_TOTAL, // ul_int "
MEMINFO_SWAP_USED, // ul_int derived from SWAP_TOTAL - SWAP_FREE
MEMINFO_SWAP_DELTA_CACHED, // s_int derived from above
MEMINFO_SWAP_DELTA_FREE, // s_int "
MEMINFO_SWAP_DELTA_TOTAL, // s_int "
MEMINFO_SWAP_DELTA_USED // s_int "
};
struct meminfo_result {
enum meminfo_item item;
union {
signed int s_int;
unsigned long ul_int;
} result;
};
struct meminfo_stack {
struct meminfo_result *head;
};
struct meminfo_info;
#define MEMINFO_GET( info, actual_enum, type ) ( { \
struct meminfo_result *r = procps_meminfo_get( info, actual_enum ); \
r ? r->result . type : 0; } )
#define MEMINFO_VAL( relative_enum, type, stack, info ) \
stack -> head [ relative_enum ] . result . type
int procps_meminfo_new (struct meminfo_info **info);
int procps_meminfo_ref (struct meminfo_info *info);
int procps_meminfo_unref (struct meminfo_info **info);
struct meminfo_result *procps_meminfo_get (
struct meminfo_info *info,
enum meminfo_item item);
struct meminfo_stack *procps_meminfo_select (
struct meminfo_info *info,
enum meminfo_item *items,
int numitems);
#ifdef XTRA_PROCPS_DEBUG
# include "xtra-procps-debug.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

90
library/include/misc.h Normal file
View File

@@ -0,0 +1,90 @@
/*
* libprocps - Library to read proc filesystem
*
* Copyright 1992-1998 Michael K. Johnson <johnsonm@redhat.com>
* Copyright ???? Larry Greenfield <greenfie@gauss.rutgers.edu>
* Copyright 1993 J. Cowley
* Copyright 1995 Martin Schulze <joey@infodrom.north.de>
* Copyright 1996 Charles Blake <cblake@bbn.com>
* Copyright 1998-2003 Albert Cahalan
* Copyright 2015 Craig Small <csmall@dropbear.xyz>
* Copyright 2021-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROC_MISC_H
#define PROC_MISC_H
#include <sys/types.h>
#include <dirent.h>
#ifdef __cplusplus
extern "C" {
#endif
// //////////////////////////////////////////////////////////////////
// Platform Particulars /////////////////////////////////////////////
long procps_cpu_count (void);
long procps_hertz_get (void);
unsigned int procps_pid_length (void);
// Convenience macros for composing/decomposing version codes
#define LINUX_VERSION(x,y,z) (0x10000*((x)&0x7fff) + 0x100*((y)&0xff) + ((z)&0xff))
#define LINUX_VERSION_MAJOR(x) (((x)>>16) & 0xFF)
#define LINUX_VERSION_MINOR(x) (((x)>> 8) & 0xFF)
#define LINUX_VERSION_PATCH(x) ( (x) & 0xFF)
int procps_linux_version(void);
// //////////////////////////////////////////////////////////////////
// Runtime Particulars //////////////////////////////////////////////
int procps_loadavg (double *av1, double *av5, double *av15);
int procps_uptime (double *uptime_secs, double *idle_secs);
char *procps_uptime_sprint (void);
char *procps_uptime_sprint_short (void);
// //////////////////////////////////////////////////////////////////
// Namespace Particulars ////////////////////////////////////////////
enum namespace_type {
PROCPS_NS_CGROUP,
PROCPS_NS_IPC,
PROCPS_NS_MNT,
PROCPS_NS_NET,
PROCPS_NS_PID,
PROCPS_NS_TIME,
PROCPS_NS_USER,
PROCPS_NS_UTS,
PROCPS_NS_COUNT // total namespaces (fencepost)
};
struct procps_ns {
unsigned long ns[PROCPS_NS_COUNT];
};
const char *procps_ns_get_name (const int id);
int procps_ns_get_id (const char *name);
int procps_ns_read_pid (const int pid, struct procps_ns *nsp);
#ifdef __cplusplus
}
#endif
#endif

29
library/include/numa.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* NUMA node support for <PIDS> & <STAT> interfaces
* Copyright 2017-2022 by James C. Warmer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_NUMA_H
#define PROCPS_NUMA_H
void numa_init (void);
void numa_uninit (void);
extern int (*numa_max_node) (void);
extern int (*numa_node_of_cpu) (int);
#endif

288
library/include/pids.h Normal file
View File

@@ -0,0 +1,288 @@
/*
* pids.h - process related declarations for libprocps
*
* Copyright (C) 1998-2005 Albert Cahalan
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
* Copyright (C) 2015-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_PIDS_H
#define PROCPS_PIDS_H
#ifdef __cplusplus
extern "C" {
#endif
enum pids_item {
PIDS_noop, // ( never altered )
PIDS_extra, // ( reset to zero )
// returns origin, see proc(5)
// ------- -------------------
PIDS_ADDR_CODE_END, // ul_int stat: end_code
PIDS_ADDR_CODE_START, // ul_int stat: start_code
PIDS_ADDR_CURR_EIP, // ul_int stat: eip
PIDS_ADDR_CURR_ESP, // ul_int stat: esp
PIDS_ADDR_STACK_START, // ul_int stat: start_stack
PIDS_AUTOGRP_ID, // s_int autogroup
PIDS_AUTOGRP_NICE, // s_int autogroup
PIDS_CGNAME, // str derived from CGROUP ':name='
PIDS_CGROUP, // str cgroup
PIDS_CGROUP_V, // strv cgroup, as *str[]
PIDS_CMD, // str stat: comm or status: Name
PIDS_CMDLINE, // str cmdline
PIDS_CMDLINE_V, // strv cmdline, as *str[]
PIDS_ENVIRON, // str environ
PIDS_ENVIRON_V, // strv environ, as *str[]
PIDS_EXE, // str exe
PIDS_EXIT_SIGNAL, // s_int stat: exit_signal
PIDS_FLAGS, // ul_int stat: flags
PIDS_FLT_MAJ, // ul_int stat: maj_flt
PIDS_FLT_MAJ_C, // ul_int derived from stat: maj_flt + cmaj_flt
PIDS_FLT_MAJ_DELTA, // s_int derived from FLT_MAJ
PIDS_FLT_MIN, // ul_int stat: min_flt
PIDS_FLT_MIN_C, // ul_int derived from stat: min_flt + cmin_flt
PIDS_FLT_MIN_DELTA, // s_int derived from FLT_MIN
PIDS_ID_EGID, // u_int status: Gid
PIDS_ID_EGROUP, // str derived from EGID, see getgrgid(3)
PIDS_ID_EUID, // u_int status: Uid
PIDS_ID_EUSER, // str derived from EUID, see getpwuid(3)
PIDS_ID_FGID, // u_int status: Gid
PIDS_ID_FGROUP, // str derived from FGID, see getgrgid(3)
PIDS_ID_FUID, // u_int status: Uid
PIDS_ID_FUSER, // str derived from FUID, see getpwuid(3)
PIDS_ID_LOGIN, // s_int loginuid
PIDS_ID_PGRP, // s_int stat: pgrp
PIDS_ID_PID, // s_int from /proc/<pid>
PIDS_ID_PPID, // s_int stat: ppid or status: PPid
PIDS_ID_RGID, // u_int status: Gid
PIDS_ID_RGROUP, // str derived from RGID, see getgrgid(3)
PIDS_ID_RUID, // u_int status: Uid
PIDS_ID_RUSER, // str derived from RUID, see getpwuid(3)
PIDS_ID_SESSION, // s_int stat: sid
PIDS_ID_SGID, // u_int status: Gid
PIDS_ID_SGROUP, // str derived from SGID, see getgrgid(3)
PIDS_ID_SUID, // u_int status: Uid
PIDS_ID_SUSER, // str derived from SUID, see getpwuid(3)
PIDS_ID_TGID, // s_int status: Tgid
PIDS_ID_TID, // s_int from /proc/<pid>/task/<tid>
PIDS_ID_TPGID, // s_int stat: tty_pgrp
PIDS_IO_READ_BYTES, // ul_int io: read_bytes
PIDS_IO_READ_CHARS, // ul_int io: rchar
PIDS_IO_READ_OPS, // ul_int io: syscr
PIDS_IO_WRITE_BYTES, // ul_int io: write_bytes
PIDS_IO_WRITE_CBYTES, // ul_int io: cancelled_write_bytes
PIDS_IO_WRITE_CHARS, // ul_int io: wchar
PIDS_IO_WRITE_OPS, // ul_int io: syscw
PIDS_LXCNAME, // str derived from CGROUP 'lxc.payload'
PIDS_MEM_CODE, // ul_int derived from MEM_CODE_PGS, as KiB
PIDS_MEM_CODE_PGS, // ul_int statm: trs
PIDS_MEM_DATA, // ul_int derived from MEM_DATA_PGS, as KiB
PIDS_MEM_DATA_PGS, // ul_int statm: drs
PIDS_MEM_RES, // ul_int derived from MEM_RES_PGS, as KiB
PIDS_MEM_RES_PGS, // ul_int statm: resident
PIDS_MEM_SHR, // ul_int derived from MEM_SHR_PGS, as KiB
PIDS_MEM_SHR_PGS, // ul_int statm: shared
PIDS_MEM_VIRT, // ul_int derived from MEM_VIRT_PGS, as KiB
PIDS_MEM_VIRT_PGS, // ul_int statm: size
PIDS_NICE, // s_int stat: nice
PIDS_NLWP, // s_int stat: num_threads or status: Threads
PIDS_NS_CGROUP, // ul_int ns/
PIDS_NS_IPC, // ul_int "
PIDS_NS_MNT, // ul_int "
PIDS_NS_NET, // ul_int "
PIDS_NS_PID, // ul_int "
PIDS_NS_TIME, // ul_int "
PIDS_NS_USER, // ul_int "
PIDS_NS_UTS, // ul_int "
PIDS_OOM_ADJ, // s_int oom_score_adj
PIDS_OOM_SCORE, // s_int oom_score
PIDS_PRIORITY, // s_int stat: priority
PIDS_PRIORITY_RT, // s_int stat: rt_priority
PIDS_PROCESSOR, // s_int stat: task_cpu
PIDS_PROCESSOR_NODE, // s_int derived from PROCESSOR, see numa(3)
PIDS_RSS, // ul_int stat: rss
PIDS_RSS_RLIM, // ul_int stat: rsslim
PIDS_SCHED_CLASS, // s_int stat: policy
PIDS_SD_MACH, // str derived from PID/TID, see sd-login(3)
PIDS_SD_OUID, // str "
PIDS_SD_SEAT, // str "
PIDS_SD_SESS, // str "
PIDS_SD_SLICE, // str "
PIDS_SD_UNIT, // str "
PIDS_SD_UUNIT, // str "
PIDS_SIGBLOCKED, // str status: SigBlk
PIDS_SIGCATCH, // str status: SigCgt
PIDS_SIGIGNORE, // str status: SigIgn
PIDS_SIGNALS, // str status: ShdPnd
PIDS_SIGPENDING, // str status: SigPnd
PIDS_SMAP_ANONYMOUS, // ul_int smaps_rollup: Anonymous
PIDS_SMAP_HUGE_ANON, // ul_int smaps_rollup: AnonHugePages
PIDS_SMAP_HUGE_FILE, // ul_int smaps_rollup: FilePmdMapped
PIDS_SMAP_HUGE_SHMEM, // ul_int smaps_rollup: ShmemPmdMapped
PIDS_SMAP_HUGE_TLBPRV, // ul_int smaps_rollup: Private_Hugetlb
PIDS_SMAP_HUGE_TLBSHR, // ul_int smaps_rollup: Shared_Hugetlb
PIDS_SMAP_LAZY_FREE, // ul_int smaps_rollup: LazyFree
PIDS_SMAP_LOCKED, // ul_int smaps_rollup: Locked
PIDS_SMAP_PRV_CLEAN, // ul_int smaps_rollup: Private_Clean
PIDS_SMAP_PRV_DIRTY, // ul_int smaps_rollup: Private_Dirty
PIDS_SMAP_PRV_TOTAL, // ul_int derived from SMAP_PRV_CLEAN + SMAP_PRV_DIRTY
PIDS_SMAP_PSS, // ul_int smaps_rollup: Pss
PIDS_SMAP_PSS_ANON, // ul_int smaps_rollup: Pss_Anon
PIDS_SMAP_PSS_FILE, // ul_int smaps_rollup: Pss_File
PIDS_SMAP_PSS_SHMEM, // ul_int smaps_rollup: Pss_Shmem
PIDS_SMAP_REFERENCED, // ul_int smaps_rollup: Referenced
PIDS_SMAP_RSS, // ul_int smaps_rollup: Rss
PIDS_SMAP_SHR_CLEAN, // ul_int smaps_rollup: Shared_Clean
PIDS_SMAP_SHR_DIRTY, // ul_int smaps_rollup: Shared_Dirty
PIDS_SMAP_SWAP, // ul_int smaps_rollup: Swap
PIDS_SMAP_SWAP_PSS, // ul_int smaps_rollup: SwapPss
PIDS_STATE, // s_ch stat: state or status: State
PIDS_SUPGIDS, // str status: Groups
PIDS_SUPGROUPS, // str derived from SUPGIDS, see getgrgid(3)
PIDS_TICS_ALL, // ull_int derived from stat: stime + utime
PIDS_TICS_ALL_C, // ull_int derived from stat: stime + utime + cstime + cutime
PIDS_TICS_ALL_DELTA, // u_int derived from TICS_ALL
PIDS_TICS_BEGAN, // ull_int stat: start_time
PIDS_TICS_BLKIO, // ull_int stat: blkio_ticks
PIDS_TICS_GUEST, // ull_int stat: gtime
PIDS_TICS_GUEST_C, // ull_int derived from stat: gtime + cgtime
PIDS_TICS_SYSTEM, // ull_int stat: stime
PIDS_TICS_SYSTEM_C, // ull_int derived from stat: stime + cstime
PIDS_TICS_USER, // ull_int stat: utime
PIDS_TICS_USER_C, // ull_int derived from stat: utime + cutime
PIDS_TIME_ALL, // real * derived from stat: (utime + stime) / hertz
PIDS_TIME_ALL_C, // real * derived from stat: (utime + stime + cutime + cstime) / hertz
PIDS_TIME_ELAPSED, // real * derived from stat: (/proc/uptime - start_time) / hertz
PIDS_TIME_START, // real * derived from stat: start_time / hertz
PIDS_TTY, // s_int stat: tty_nr
PIDS_TTY_NAME, // str derived from TTY
PIDS_TTY_NUMBER, // str derived from TTY as str
PIDS_UTILIZATION, // real derived from TIME_ALL / TIME_ELAPSED, as percentage
PIDS_UTILIZATION_C, // real derived from TIME_ALL_C / TIME_ELAPSED, as percentage
PIDS_VM_DATA, // ul_int status: VmData
PIDS_VM_EXE, // ul_int status: VmExe
PIDS_VM_LIB, // ul_int status: VmLib
PIDS_VM_RSS, // ul_int status: VmRSS
PIDS_VM_RSS_ANON, // ul_int status: RssAnon
PIDS_VM_RSS_FILE, // ul_int status: RssFile
PIDS_VM_RSS_LOCKED, // ul_int status: VmLck
PIDS_VM_RSS_SHARED, // ul_int status: RssShmem
PIDS_VM_SIZE, // ul_int status: VmSize
PIDS_VM_STACK, // ul_int status: VmStk
PIDS_VM_SWAP, // ul_int status: VmSwap
PIDS_VM_USED, // ul_int derived from status: VmRSS + VmSwap
PIDS_VSIZE_BYTES, // ul_int stat: vsize
PIDS_WCHAN_NAME // str wchan
};
// * while these are all expressed as seconds, each can be
// converted into tics/jiffies with no loss of precision
// when multiplied by hertz obtained via procps_misc(3).
enum pids_fetch_type {
PIDS_FETCH_TASKS_ONLY,
PIDS_FETCH_THREADS_TOO
};
enum pids_select_type {
PIDS_SELECT_PID = 0x10000,
PIDS_SELECT_PID_THREADS = 0x10001,
PIDS_SELECT_UID = 0x20000,
PIDS_SELECT_UID_THREADS = 0x20001
};
enum pids_sort_order {
PIDS_SORT_ASCEND = +1,
PIDS_SORT_DESCEND = -1
};
struct pids_result {
enum pids_item item;
union {
signed char s_ch;
signed int s_int;
unsigned int u_int;
unsigned long ul_int;
unsigned long long ull_int;
char *str;
char **strv;
double real;
} result;
};
struct pids_stack {
struct pids_result *head;
};
struct pids_counts {
int total;
int running, sleeping, stopped, zombied, other;
};
struct pids_fetch {
struct pids_counts *counts;
struct pids_stack **stacks;
};
struct pids_info;
#define PIDS_VAL( relative_enum, type, stack, info ) \
stack -> head [ relative_enum ] . result . type
int procps_pids_new (struct pids_info **info, enum pids_item *items, int numitems);
int procps_pids_ref (struct pids_info *info);
int procps_pids_unref (struct pids_info **info);
struct pids_stack *fatal_proc_unmounted (
struct pids_info *info,
int return_self);
struct pids_stack *procps_pids_get (
struct pids_info *info,
enum pids_fetch_type which);
struct pids_fetch *procps_pids_reap (
struct pids_info *info,
enum pids_fetch_type which);
int procps_pids_reset (
struct pids_info *info,
enum pids_item *newitems,
int newnumitems);
struct pids_fetch *procps_pids_select (
struct pids_info *info,
unsigned *these,
int numthese,
enum pids_select_type which);
struct pids_stack **procps_pids_sort (
struct pids_info *info,
struct pids_stack *stacks[],
int numstacked,
enum pids_item sortitem,
enum pids_sort_order order);
#ifdef XTRA_PROCPS_DEBUG
# include "xtra-procps-debug.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,28 @@
/*
* libprocps - Library to read proc filesystem
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_PRIVATE_H
#define PROCPS_PRIVATE_H
#define PROCPS_EXPORT __attribute__ ((visibility("default")))
#define STRINGIFY_ARG(a) #a
#define STRINGIFY(a) STRINGIFY_ARG(a)
#define MAXTABLE(t) (int)(sizeof(t) / sizeof(t[0]))
#endif

12
library/include/pwcache.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef PROCPS_PROC_PWCACHE_H
#define PROCPS_PROC_PWCACHE_H
#include <sys/types.h>
// used in pwcache and in readproc to set size of username or groupname
#define P_G_SZ 33
char *pwcache_get_user(uid_t uid);
char *pwcache_get_group(gid_t gid);
#endif

288
library/include/readproc.h Normal file
View File

@@ -0,0 +1,288 @@
#ifndef PROCPS_PROC_READPROC_H
#define PROCPS_PROC_READPROC_H
// New Interface to Process Table -- PROCTAB Stream (a la Directory streams)
// Copyright 1996 Charles L. Blake.
// Copyright 1998 Michael K. Johnson
// Copyright 1998-2003 Albert Cahalan
// May be distributed under the terms of the
// GNU Library General Public License, a copy of which is provided
// in the file COPYING
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include "misc.h"
// the following is development only, forcing display of "[ duplicate ENUM ]" strings
// #define FALSE_THREADS /* set most child string fields to NULL */
// This is to help document a transition from pid to tgid/tid caused
// by the introduction of thread support. It is used in cases where
// neither tgid nor tid seemed correct. (in other words, FIXME)
#define XXXID tid
// Basic data structure which holds all information we can get about a process.
// (unless otherwise specified, fields are read from /proc/#/stat)
//
// Most of it comes from task_struct in linux/sched.h
//
typedef struct proc_t {
int
tid, // (special) task id, the POSIX thread ID (see also: tgid)
ppid; // stat,status pid of parent process
char
state, // stat,status single-char code for process state (S=sleeping)
pad_1, // n/a padding
pad_2, // n/a padding
pad_3; // n/a padding
unsigned long long
utime, // stat user-mode CPU time accumulated by process
stime, // stat kernel-mode CPU time accumulated by process
cutime, // stat cumulative utime of process and reaped children
cstime, // stat cumulative stime of process and reaped children
start_time, // stat start time of process -- seconds since system boot
blkio_tics, // stat time spent waiting for block IO
gtime, // stat guest time of the task in jiffies
cgtime; // stat guest time of the task children in jiffies
int // next 3 fields are NOT filled in by readproc
pcpu, // stat (special) elapsed tics for %CPU usage calculation
maj_delta, // stat (special) major page faults since last update
min_delta; // stat (special) minor page faults since last update
char
// Linux 2.1.7x and up have 64 signals. Allow 64, plus '\0' and padding.
signal[18], // status mask of pending signals
blocked[18], // status mask of blocked signals
sigignore[18], // status mask of ignored signals
sigcatch[18], // status mask of caught signals
_sigpnd[18]; // status mask of PER TASK pending signals
unsigned long
start_code, // stat address of beginning of code segment
end_code, // stat address of end of code segment
start_stack, // stat address of the bottom of stack for the process
kstk_esp, // stat kernel stack pointer
kstk_eip, // stat kernel instruction pointer
wchan, // stat (special) address of kernel wait channel proc is sleeping in
rss, // stat identical to 'resident'
alarm; // stat ?
int
priority, // stat kernel scheduling priority
nice; // stat standard unix nice level of process
unsigned long
// the next 7 members come from /proc/#/statm
size, // statm total virtual memory (as # pages)
resident, // statm resident non-swapped memory (as # pages)
share, // statm shared (mmap'd) memory (as # pages)
trs, // statm text (exe) resident set (as # pages)
lrs, // statm library resident set (always 0 w/ 2.6)
drs, // statm data+stack resident set (as # pages)
dt; // statm dirty pages (always 0 w/ 2.6)
unsigned long
vm_size, // status equals 'size' (as kb)
vm_lock, // status locked pages (as kb)
vm_rss, // status equals 'rss' and/or 'resident' (as kb)
vm_rss_anon, // status the 'anonymous' portion of vm_rss (as kb)
vm_rss_file, // status the 'file-backed' portion of vm_rss (as kb)
vm_rss_shared, // status the 'shared' portion of vm_rss (as kb)
vm_data, // status data only size (as kb)
vm_stack, // status stack only size (as kb)
vm_swap, // status based on linux-2.6.34 "swap ents" (as kb)
vm_exe, // status equals 'trs' (as kb)
vm_lib, // status total, not just used, library pages (as kb)
vsize, // stat number of pages of virtual memory ...
rss_rlim, // stat resident set size limit?
flags, // stat kernel flags for the process
min_flt, // stat number of minor page faults since process start
maj_flt, // stat number of major page faults since process start
cmin_flt, // stat cumulative min_flt of process and child processes
cmaj_flt, // stat cumulative maj_flt of process and child processes
rchar, // io characters read
wchar, // io characters written
syscr, // io number of read I/O operations
syscw, // io number of write I/O operations
read_bytes, // io number of bytes fetched from the storage layer
write_bytes, // io number of bytes sent to the storage layer
cancelled_write_bytes, // io number of bytes truncating pagecache
smap_Rss, // smaps_rollup mapping currently resident in RAM
smap_Pss, // " Rss divided by total processes sharing it
smap_Pss_Anon, // " proportional share of 'anonymous' memory
smap_Pss_File, // " proportional share of 'file' memory
smap_Pss_Shmem, // " proportional share of 'shmem' memory
smap_Shared_Clean, // " unmodified shared memory
smap_Shared_Dirty, // " altered shared memory
smap_Private_Clean, // " unmodified private memory
smap_Private_Dirty, // " altered private memory
smap_Referenced, // " memory marked as referenced/accessed
smap_Anonymous, // " memory not belonging to any file
smap_LazyFree, // " memory marked by madvise(MADV_FREE)
smap_AnonHugePages, // " memory backed by transparent huge pages
smap_ShmemPmdMapped, // " shmem/tmpfs memory backed by huge pages
smap_FilePmdMapped, // " file memory backed by huge pages
smap_Shared_Hugetlb, // " hugetlbfs backed memory *not* counted in Rss/Pss
smap_Private_Hugetlb, // " hugetlbfs backed memory *not* counted in Rss/Pss
smap_Swap, // " swapped would-be-anonymous memory (includes swapped out shmem)
smap_SwapPss, // " the proportional share of 'Swap' (excludes swapped out shmem)
smap_Locked; // " memory amount locked to RAM
char
*environ, // (special) environment as string (/proc/#/environ)
*cmdline, // (special) command line as string (/proc/#/cmdline)
*cgroup, // (special) cgroup as string (/proc/#/cgroup)
*cgname, // (special) name portion of above (if possible)
*supgid, // status supplementary gids as comma delimited str
*supgrp, // supp grp names as comma delimited str, derived from supgid
**environ_v, // (special) environment string vectors (/proc/#/environ)
**cmdline_v, // (special) command line string vectors (/proc/#/cmdline)
**cgroup_v; // (special) cgroup string vectors (/proc/#/cgroup)
char
*euser, // stat(),status effective user name
*ruser, // status real user name
*suser, // status saved user name
*fuser, // status filesystem user name
*rgroup, // status real group name
*egroup, // status effective group name
*sgroup, // status saved group name
*fgroup, // status filesystem group name
*cmd; // stat,status basename of executable file in call to exec(2)
int
rtprio, // stat real-time priority
sched, // stat scheduling class
pgrp, // stat process group id
session, // stat session id
nlwp, // stat,status number of threads, or 0 if no clue
tgid, // (special) thread group ID, the POSIX PID (see also: tid)
tty; // stat full device number of controlling terminal
/* FIXME: int uids & gids should be uid_t or gid_t from pwd.h */
uid_t euid; gid_t egid; // stat(),status effective
uid_t ruid; gid_t rgid; // status real
uid_t suid; gid_t sgid; // status saved
uid_t fuid; gid_t fgid; // status fs (used for file access only)
int
tpgid, // stat terminal process group id
exit_signal, // stat might not be SIGCHLD
processor; // stat current (or most recent?) CPU
int
oom_score, // oom_score (badness for OOM killer)
oom_adj; // oom_adj (adjustment to OOM score)
struct procps_ns ns; // (ns subdir) inode number of namespaces
char
*sd_mach, // n/a systemd vm/container name
*sd_ouid, // n/a systemd session owner uid
*sd_seat, // n/a systemd login session seat
*sd_sess, // n/a systemd login session id
*sd_slice, // n/a systemd slice unit
*sd_unit, // n/a systemd system unit id
*sd_uunit; // n/a systemd user unit id
char
*lxcname, // n/a lxc container name
*exe; // exe executable path + name
int
luid, // loginuid user id at login
autogrp_id, // autogroup autogroup number (id)
autogrp_nice; // autogroup autogroup nice value
} proc_t;
// PROCTAB: data structure holding the persistent information readproc needs
// from openproc(). The setup is intentionally similar to the dirent interface
// and other system table interfaces (utmp+wtmp come to mind).
#define PROCPATHLEN 64 // must hold /proc/2000222000/task/2000222000/cmdline
typedef struct PROCTAB {
DIR *procfs;
// char deBug0[64];
DIR *taskdir; // for threads
// char deBug1[64];
pid_t taskdir_user; // for threads
int(*finder)(struct PROCTAB *__restrict const, proc_t *__restrict const);
proc_t*(*reader)(struct PROCTAB *__restrict const, proc_t *__restrict const);
int(*taskfinder)(struct PROCTAB *__restrict const, const proc_t *__restrict const, proc_t *__restrict const, char *__restrict const);
proc_t*(*taskreader)(struct PROCTAB *__restrict const, proc_t *__restrict const, char *__restrict const);
pid_t *pids; // pids of the procs
uid_t *uids; // uids of procs
int nuid; // cannot really sentinel-terminate unsigned short[]
int i; // generic
int hide_kernel; // getenv LIBPROC_HIDE_KERNEL was set
unsigned flags;
unsigned u; // generic
void * vp; // generic
char path[PROCPATHLEN]; // must hold /proc/2000222000/task/2000222000/cmdline
unsigned pathlen; // length of string in the above (w/o '\0')
} PROCTAB;
// openproc/readproctab:
//
// Return PROCTAB* / *proc_t[] or NULL on error ((probably) "/proc" cannot be
// opened.) By default readproc will consider all processes as valid to parse
// and return, but not actually fill in the cmdline, environ, and /proc/#/statm
// derived memory fields.
//
// `flags' (a bitwise-or of PROC_* below) modifies the default behavior. The
// "fill" options will cause more of the proc_t to be filled in. The "filter"
// options all use the second argument as the pointer to a list of objects:
// process status', process id's, user id's. The third
// argument is the length of the list (currently only used for lists of user
// id's since uid_t supports no convenient termination sentinel.)
#define PROC_FILLMEM 0x00000001 // read statm
#define PROC_FILLARG 0x00000002 // alloc and fill in `cmdline' vectors
#define PROC_FILLENV 0x00000004 // alloc and fill in `environ' vectors
#define PROC_FILLUSR 0x00000008 // resolve user id number -> user name
#define PROC_FILLGRP 0x00000010 // resolve group id number -> group name
#define PROC_FILLSTATUS 0x00000020 // read status
#define PROC_FILLSTAT 0x00000040 // read stat
#define PROC_FILLCGROUP 0x00000080 // alloc and fill in `cgroup` vectors
#define PROC_FILLOOM 0x00000100 // fill in proc_t oom_score and oom_adj
#define PROC_FILLNS 0x00000200 // fill in proc_t namespace information
#define PROC_FILLSYSTEMD 0x00000400 // fill in proc_t systemd information
#define PROC_FILL_LXC 0x00000800 // fill in proc_t lxcname, if possible
#define PROC_FILL_LUID 0x00001000 // fill in proc_t luid (login user id)
#define PROC_FILL_EXE 0x00002000 // fill in proc_t exe path + pgm name
#define PROC_FILLIO 0x00004000 // fill in proc_t io information
#define PROC_FILLSMAPS 0x00008000 // fill in proc_t smaps_rollup stuff
// consider only processes with one of the passed:
#define PROC_PID 0x00010000 // process id numbers ( 0 terminated )
#define PROC_UID 0x00020000 // user id numbers ( length needed )
// Note: the above 2 values must NOT change without also changing pids.h !!!
#define PROC_EDITCGRPCVT 0x00040000 // edit `cgroup' as regular string
#define PROC_EDITCMDLCVT 0x00080000 // edit `cmdline' as regular string
#define PROC_EDITENVRCVT 0x00100000 // edit `environ' as regular string
// these three also require the PROC_FILLSTATUS flage
#define PROC_FILL_OUSERS ( 0x00200000 | PROC_FILLSTATUS ) // obtain other user names
#define PROC_FILL_OGROUPS ( 0x00400000 | PROC_FILLSTATUS ) // obtain other group names
#define PROC_FILL_SUPGRP ( 0x00800000 | PROC_FILLSTATUS ) // obtain supplementary group names
// and let's put new flags here ...
#define PROC_FILLAUTOGRP 0x01000000 // fill in proc_t autogroup stuff
// it helps to give app code a few spare bits
#define PROC_SPARE_1 0x10000000
#define PROC_SPARE_2 0x20000000
#define PROC_SPARE_3 0x40000000
#define PROC_SPARE_4 0x80000000
// Function definitions
// Initialize a PROCTAB structure holding needed call-to-call persistent data
PROCTAB *openproc(unsigned flags, ... /* pid_t *| uid_t *| dev_t *| char *[, int n] */ );
// Retrieve the next process or task matching the criteria set by the openproc().
//
// Note: When NULL is used as the readproc 'p' or readeither 'x'
// parameter, the library will allocate the necessary proc_t storage.
//
// Alternatively, you may provide your own reuseable buffer address
// in which case that buffer *MUST* be initialized to zero one time
// only before first use. Thereafter, the library will manage such
// a passed proc_t, freeing any additional acquired memory associated
// with the previous process or thread.
proc_t *readproc(PROCTAB *__restrict const PT, proc_t *__restrict p);
proc_t *readeither(PROCTAB *__restrict const PT, proc_t *__restrict x);
int look_up_our_self(proc_t *p);
void closeproc(PROCTAB *PT);
char **vectorize_this_str(const char *src);
#endif

141
library/include/slabinfo.h Normal file
View File

@@ -0,0 +1,141 @@
/*
* slabinfo.h - slab pools related declarations for libprocps
*
* Copyright (C) 1998-2005 Albert Cahalan
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
* Copyright (C) 2016-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_SLABINFO_H
#define PROCPS_SLABINFO_H
#ifdef __cplusplus
extern "C "{
#endif
enum slabinfo_item {
SLABINFO_noop, // ( never altered )
SLABINFO_extra, // ( reset to zero )
// returns origin, see proc(5)
// ------- -------------------
SLAB_NAME, // str /proc/slabinfo
SLAB_NUM_OBJS, // u_int "
SLAB_ACTIVE_OBJS, // u_int "
SLAB_OBJ_SIZE, // u_int "
SLAB_OBJ_PER_SLAB, // u_int "
SLAB_NUMS_SLABS, // u_int "
SLAB_ACTIVE_SLABS, // u_int "
SLAB_PAGES_PER_SLAB, // u_int "
SLAB_PERCENT_USED, // u_int derived from ACTIVE_OBJS / NUM_OBJS
SLAB_SIZE_TOTAL, // ul_int derived from page size * NUM_OBJS * PAGES_PER_SLAB
SLABS_CACHES_TOTAL, // u_int derived from all caches
SLABS_CACHES_ACTIVE, // u_int "
SLABS_NUM_OBJS, // u_int "
SLABS_ACTIVE_OBJS, // u_int "
SLABS_OBJ_SIZE_AVG, // u_int "
SLABS_OBJ_SIZE_MIN, // u_int "
SLABS_OBJ_SIZE_MAX, // u_int "
SLABS_NUMS_SLABS, // u_int "
SLABS_ACTIVE_SLABS, // u_int "
SLABS_PAGES_TOTAL, // u_int "
SLABS_SIZE_ACTIVE, // ul_int "
SLABS_SIZE_TOTAL, // ul_int "
SLABS_DELTA_CACHES_TOTAL, // s_int derived from above
SLABS_DELTA_CACHES_ACTIVE, // s_int "
SLABS_DELTA_NUM_OBJS, // s_int "
SLABS_DELTA_ACTIVE_OBJS, // s_int "
SLABS_DELTA_OBJ_SIZE_AVG, // s_int "
SLABS_DELTA_OBJ_SIZE_MIN, // s_int "
SLABS_DELTA_OBJ_SIZE_MAX, // s_int "
SLABS_DELTA_NUMS_SLABS, // s_int "
SLABS_DELTA_ACTIVE_SLABS, // s_int "
SLABS_DELTA_PAGES_TOTAL, // s_int "
SLABS_DELTA_SIZE_ACTIVE, // s_int "
SLABS_DELTA_SIZE_TOTAL // s_int "
};
enum slabinfo_sort_order {
SLABINFO_SORT_ASCEND = +1,
SLABINFO_SORT_DESCEND = -1
};
struct slabinfo_result {
enum slabinfo_item item;
union {
signed int s_int;
unsigned int u_int;
unsigned long ul_int;
char *str;
} result;
};
struct slabinfo_stack {
struct slabinfo_result *head;
};
struct slabinfo_reaped {
int total;
struct slabinfo_stack **stacks;
};
struct slabinfo_info;
#define SLABINFO_GET( info, actual_enum, type ) ( { \
struct slabinfo_result *r = procps_slabinfo_get( info, actual_enum ); \
r ? r->result . type : 0; } )
#define SLABINFO_VAL( relative_enum, type, stack, info ) \
stack -> head [ relative_enum ] . result . type
int procps_slabinfo_new (struct slabinfo_info **info);
int procps_slabinfo_ref (struct slabinfo_info *info);
int procps_slabinfo_unref (struct slabinfo_info **info);
struct slabinfo_result *procps_slabinfo_get (
struct slabinfo_info *info,
enum slabinfo_item item);
struct slabinfo_reaped *procps_slabinfo_reap (
struct slabinfo_info *info,
enum slabinfo_item *items,
int numitems);
struct slabinfo_stack *procps_slabinfo_select (
struct slabinfo_info *info,
enum slabinfo_item *items,
int numitems);
struct slabinfo_stack **procps_slabinfo_sort (
struct slabinfo_info *info,
struct slabinfo_stack *stacks[],
int numstacked,
enum slabinfo_item sortitem,
enum slabinfo_sort_order order);
#ifdef XTRA_PROCPS_DEBUG
# include "xtra-procps-debug.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

173
library/include/stat.h Normal file
View File

@@ -0,0 +1,173 @@
/*
* stat.h - cpu/numa related declarations for libprocps
*
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
* Copyright (C) 2015-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_STAT_H
#define PROCPS_STAT_H
#ifdef __cplusplus
extern "C" {
#endif
enum stat_item {
STAT_noop, // ( never altered )
STAT_extra, // ( reset to zero )
// returns origin, see proc(5)
// ------- -------------------
STAT_TIC_ID, // s_int /proc/stat, cpu or numa node id
STAT_TIC_NUMA_NODE, // s_int [ CPU ID based, see: numa(3) ]
STAT_TIC_NUM_CONTRIBUTORS, // s_int [ total CPUs contributing to TIC counts ]
STAT_TIC_USER, // ull_int /proc/stat
STAT_TIC_NICE, // ull_int "
STAT_TIC_SYSTEM, // ull_int "
STAT_TIC_IDLE, // ull_int "
STAT_TIC_IOWAIT, // ull_int "
STAT_TIC_IRQ, // ull_int "
STAT_TIC_SOFTIRQ, // ull_int "
STAT_TIC_STOLEN, // ull_int "
STAT_TIC_GUEST, // ull_int "
STAT_TIC_GUEST_NICE, // ull_int "
STAT_TIC_DELTA_USER, // sl_int derived from above
STAT_TIC_DELTA_NICE, // sl_int "
STAT_TIC_DELTA_SYSTEM, // sl_int "
STAT_TIC_DELTA_IDLE, // sl_int "
STAT_TIC_DELTA_IOWAIT, // sl_int "
STAT_TIC_DELTA_IRQ, // sl_int "
STAT_TIC_DELTA_SOFTIRQ, // sl_int "
STAT_TIC_DELTA_STOLEN, // sl_int "
STAT_TIC_DELTA_GUEST, // sl_int "
STAT_TIC_DELTA_GUEST_NICE, // sl_int "
STAT_TIC_SUM_USER, // ull_int derived from USER + NICE tics
STAT_TIC_SUM_SYSTEM, // ull_int derived from SYSTEM + IRQ + SOFTIRQ tics
STAT_TIC_SUM_IDLE, // ull_int derived from IDLE + IOWAIT tics
STAT_TIC_SUM_BUSY, // ull_int derived from SUM_TOTAL - SUM_IDLE tics
STAT_TIC_SUM_TOTAL, // ull_int derived from sum of all 10 tics
STAT_TIC_SUM_DELTA_USER, // sl_int derived from above
STAT_TIC_SUM_DELTA_SYSTEM, // sl_int "
STAT_TIC_SUM_DELTA_IDLE, // sl_int "
STAT_TIC_SUM_DELTA_BUSY, // sl_int "
STAT_TIC_SUM_DELTA_TOTAL, // sl_int "
STAT_SYS_CTX_SWITCHES, // ul_int /proc/stat
STAT_SYS_INTERRUPTS, // ul_int "
STAT_SYS_PROC_BLOCKED, // ul_int "
STAT_SYS_PROC_CREATED, // ul_int "
STAT_SYS_PROC_RUNNING, // ul_int "
STAT_SYS_TIME_OF_BOOT, // ul_int "
STAT_SYS_DELTA_CTX_SWITCHES, // s_int derived from above
STAT_SYS_DELTA_INTERRUPTS, // s_int "
STAT_SYS_DELTA_PROC_BLOCKED, // s_int "
STAT_SYS_DELTA_PROC_CREATED, // s_int "
STAT_SYS_DELTA_PROC_RUNNING // s_int "
};
enum stat_reap_type {
STAT_REAP_CPUS_ONLY,
STAT_REAP_NUMA_NODES_TOO
};
enum stat_sort_order {
STAT_SORT_ASCEND = +1,
STAT_SORT_DESCEND = -1
};
struct stat_result {
enum stat_item item;
union {
signed int s_int;
signed long sl_int;
unsigned long ul_int;
unsigned long long ull_int;
} result;
};
struct stat_stack {
struct stat_result *head;
};
struct stat_reap {
int total;
struct stat_stack **stacks;
};
struct stat_reaped {
struct stat_stack *summary;
struct stat_reap *cpus;
struct stat_reap *numa;
};
struct stat_info;
// STAT_TIC_ID value for /proc/stat cpu summary
#define STAT_SUMMARY_ID -11111
// STAT_TIC_NUMA_NODE value for STAT_REAP_CPUS_ONLY or
// for STAT_REAP_NUMA_NODES_TOO when node was inactive
#define STAT_NODE_INVALID -22222
#define STAT_GET( info, actual_enum, type ) ( { \
struct stat_result *r = procps_stat_get( info, actual_enum ); \
r ? r->result . type : 0; } )
#define STAT_VAL( relative_enum, type, stack, info ) \
stack -> head [ relative_enum ] . result . type
int procps_stat_new (struct stat_info **info);
int procps_stat_ref (struct stat_info *info);
int procps_stat_unref (struct stat_info **info);
struct stat_result *procps_stat_get (
struct stat_info *info,
enum stat_item item);
struct stat_reaped *procps_stat_reap (
struct stat_info *info,
enum stat_reap_type what,
enum stat_item *items,
int numitems);
struct stat_stack *procps_stat_select (
struct stat_info *info,
enum stat_item *items,
int numitems);
struct stat_stack **procps_stat_sort (
struct stat_info *info,
struct stat_stack *stacks[],
int numstacked,
enum stat_item sortitem,
enum stat_sort_order order);
#ifdef XTRA_PROCPS_DEBUG
# include "xtra-procps-debug.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

385
library/include/vmstat.h Normal file
View File

@@ -0,0 +1,385 @@
/*
* vmstat,c - virtual memory related declarations for libprocps
*
* Copyright (C) 1995 Martin Schulze <joey@infodrom.north.de>
* Copyright (C) 1996 Charles Blake <cblake@bbn.com>
* Copyright (C) 2003 Albert Cahalan
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
* Copyright (C) 2016-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROCPS_VMSTAT_H
#define PROCPS_VMSTAT_H
#ifdef __cplusplus
extern "C" {
#endif
enum vmstat_item {
VMSTAT_noop, // ( never altered )
VMSTAT_extra, // ( reset to zero )
// returns origin, see proc(5)
// ------- -------------------
VMSTAT_ALLOCSTALL_DMA, // ul_int /proc/vmstat
VMSTAT_ALLOCSTALL_DMA32, // ul_int "
VMSTAT_ALLOCSTALL_HIGH, // ul_int "
VMSTAT_ALLOCSTALL_MOVABLE, // ul_int "
VMSTAT_ALLOCSTALL_NORMAL, // ul_int "
VMSTAT_BALLOON_DEFLATE, // ul_int "
VMSTAT_BALLOON_INFLATE, // ul_int "
VMSTAT_BALLOON_MIGRATE, // ul_int "
VMSTAT_COMPACT_DAEMON_FREE_SCANNED, // ul_int "
VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED, // ul_int "
VMSTAT_COMPACT_DAEMON_WAKE, // ul_int "
VMSTAT_COMPACT_FAIL, // ul_int "
VMSTAT_COMPACT_FREE_SCANNED, // ul_int "
VMSTAT_COMPACT_ISOLATED, // ul_int "
VMSTAT_COMPACT_MIGRATE_SCANNED, // ul_int "
VMSTAT_COMPACT_STALL, // ul_int "
VMSTAT_COMPACT_SUCCESS, // ul_int "
VMSTAT_DROP_PAGECACHE, // ul_int "
VMSTAT_DROP_SLAB, // ul_int "
VMSTAT_HTLB_BUDDY_ALLOC_FAIL, // ul_int "
VMSTAT_HTLB_BUDDY_ALLOC_SUCCESS, // ul_int "
VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY, // ul_int "
VMSTAT_KSWAPD_INODESTEAL, // ul_int "
VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY, // ul_int "
VMSTAT_NR_ACTIVE_ANON, // ul_int "
VMSTAT_NR_ACTIVE_FILE, // ul_int "
VMSTAT_NR_ANON_PAGES, // ul_int "
VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES, // ul_int "
VMSTAT_NR_BOUNCE, // ul_int "
VMSTAT_NR_DIRTIED, // ul_int "
VMSTAT_NR_DIRTY, // ul_int "
VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD, // ul_int "
VMSTAT_NR_DIRTY_THRESHOLD, // ul_int "
VMSTAT_NR_FILE_HUGEPAGES, // ul_int "
VMSTAT_NR_FILE_PAGES, // ul_int "
VMSTAT_NR_FILE_PMDMAPPED, // ul_int "
VMSTAT_NR_FOLL_PIN_ACQUIRED, // ul_int "
VMSTAT_NR_FOLL_PIN_RELEASED, // ul_int "
VMSTAT_NR_FREE_CMA, // ul_int "
VMSTAT_NR_FREE_PAGES, // ul_int "
VMSTAT_NR_INACTIVE_ANON, // ul_int "
VMSTAT_NR_INACTIVE_FILE, // ul_int "
VMSTAT_NR_ISOLATED_ANON, // ul_int "
VMSTAT_NR_ISOLATED_FILE, // ul_int "
VMSTAT_NR_KERNEL_MISC_RECLAIMABLE, // ul_int "
VMSTAT_NR_KERNEL_STACK, // ul_int "
VMSTAT_NR_MAPPED, // ul_int "
VMSTAT_NR_MLOCK, // ul_int "
VMSTAT_NR_PAGE_TABLE_PAGES, // ul_int "
VMSTAT_NR_SHADOW_CALL_STACK, // ul_int "
VMSTAT_NR_SHMEM, // ul_int "
VMSTAT_NR_SHMEM_HUGEPAGES, // ul_int "
VMSTAT_NR_SHMEM_PMDMAPPED, // ul_int "
VMSTAT_NR_SLAB_RECLAIMABLE, // ul_int "
VMSTAT_NR_SLAB_UNRECLAIMABLE, // ul_int "
VMSTAT_NR_UNEVICTABLE, // ul_int "
VMSTAT_NR_UNSTABLE, // ul_int "
VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM, // ul_int "
VMSTAT_NR_VMSCAN_WRITE, // ul_int "
VMSTAT_NR_WRITEBACK, // ul_int "
VMSTAT_NR_WRITEBACK_TEMP, // ul_int "
VMSTAT_NR_WRITTEN, // ul_int "
VMSTAT_NR_ZONE_ACTIVE_ANON, // ul_int "
VMSTAT_NR_ZONE_ACTIVE_FILE, // ul_int "
VMSTAT_NR_ZONE_INACTIVE_ANON, // ul_int "
VMSTAT_NR_ZONE_INACTIVE_FILE, // ul_int "
VMSTAT_NR_ZONE_UNEVICTABLE, // ul_int "
VMSTAT_NR_ZONE_WRITE_PENDING, // ul_int "
VMSTAT_NR_ZSPAGES, // ul_int "
VMSTAT_NUMA_FOREIGN, // ul_int "
VMSTAT_NUMA_HINT_FAULTS, // ul_int "
VMSTAT_NUMA_HINT_FAULTS_LOCAL, // ul_int "
VMSTAT_NUMA_HIT, // ul_int "
VMSTAT_NUMA_HUGE_PTE_UPDATES, // ul_int "
VMSTAT_NUMA_INTERLEAVE, // ul_int "
VMSTAT_NUMA_LOCAL, // ul_int "
VMSTAT_NUMA_MISS, // ul_int "
VMSTAT_NUMA_OTHER, // ul_int "
VMSTAT_NUMA_PAGES_MIGRATED, // ul_int "
VMSTAT_NUMA_PTE_UPDATES, // ul_int "
VMSTAT_OOM_KILL, // ul_int "
VMSTAT_PAGEOUTRUN, // ul_int "
VMSTAT_PGACTIVATE, // ul_int "
VMSTAT_PGALLOC_DMA, // ul_int "
VMSTAT_PGALLOC_DMA32, // ul_int "
VMSTAT_PGALLOC_HIGH, // ul_int "
VMSTAT_PGALLOC_MOVABLE, // ul_int "
VMSTAT_PGALLOC_NORMAL, // ul_int "
VMSTAT_PGDEACTIVATE, // ul_int "
VMSTAT_PGFAULT, // ul_int "
VMSTAT_PGFREE, // ul_int "
VMSTAT_PGINODESTEAL, // ul_int "
VMSTAT_PGLAZYFREE, // ul_int "
VMSTAT_PGLAZYFREED, // ul_int "
VMSTAT_PGMAJFAULT, // ul_int "
VMSTAT_PGMIGRATE_FAIL, // ul_int "
VMSTAT_PGMIGRATE_SUCCESS, // ul_int "
VMSTAT_PGPGIN, // ul_int "
VMSTAT_PGPGOUT, // ul_int "
VMSTAT_PGREFILL, // ul_int "
VMSTAT_PGROTATED, // ul_int "
VMSTAT_PGSCAN_ANON, // ul_int "
VMSTAT_PGSCAN_DIRECT, // ul_int "
VMSTAT_PGSCAN_DIRECT_THROTTLE, // ul_int "
VMSTAT_PGSCAN_FILE, // ul_int "
VMSTAT_PGSCAN_KSWAPD, // ul_int "
VMSTAT_PGSKIP_DMA, // ul_int "
VMSTAT_PGSKIP_DMA32, // ul_int "
VMSTAT_PGSKIP_HIGH, // ul_int "
VMSTAT_PGSKIP_MOVABLE, // ul_int "
VMSTAT_PGSKIP_NORMAL, // ul_int "
VMSTAT_PGSTEAL_ANON, // ul_int "
VMSTAT_PGSTEAL_DIRECT, // ul_int "
VMSTAT_PGSTEAL_FILE, // ul_int "
VMSTAT_PGSTEAL_KSWAPD, // ul_int "
VMSTAT_PSWPIN, // ul_int "
VMSTAT_PSWPOUT, // ul_int "
VMSTAT_SLABS_SCANNED, // ul_int "
VMSTAT_SWAP_RA, // ul_int "
VMSTAT_SWAP_RA_HIT, // ul_int "
VMSTAT_THP_COLLAPSE_ALLOC, // ul_int "
VMSTAT_THP_COLLAPSE_ALLOC_FAILED, // ul_int "
VMSTAT_THP_DEFERRED_SPLIT_PAGE, // ul_int "
VMSTAT_THP_FAULT_ALLOC, // ul_int "
VMSTAT_THP_FAULT_FALLBACK, // ul_int "
VMSTAT_THP_FAULT_FALLBACK_CHARGE, // ul_int "
VMSTAT_THP_FILE_ALLOC, // ul_int "
VMSTAT_THP_FILE_FALLBACK, // ul_int "
VMSTAT_THP_FILE_FALLBACK_CHARGE, // ul_int "
VMSTAT_THP_FILE_MAPPED, // ul_int "
VMSTAT_THP_SPLIT_PAGE, // ul_int "
VMSTAT_THP_SPLIT_PAGE_FAILED, // ul_int "
VMSTAT_THP_SPLIT_PMD, // ul_int "
VMSTAT_THP_SPLIT_PUD, // ul_int "
VMSTAT_THP_SWPOUT, // ul_int "
VMSTAT_THP_SWPOUT_FALLBACK, // ul_int "
VMSTAT_THP_ZERO_PAGE_ALLOC, // ul_int "
VMSTAT_THP_ZERO_PAGE_ALLOC_FAILED, // ul_int "
VMSTAT_UNEVICTABLE_PGS_CLEARED, // ul_int "
VMSTAT_UNEVICTABLE_PGS_CULLED, // ul_int "
VMSTAT_UNEVICTABLE_PGS_MLOCKED, // ul_int "
VMSTAT_UNEVICTABLE_PGS_MUNLOCKED, // ul_int "
VMSTAT_UNEVICTABLE_PGS_RESCUED, // ul_int "
VMSTAT_UNEVICTABLE_PGS_SCANNED, // ul_int "
VMSTAT_UNEVICTABLE_PGS_STRANDED, // ul_int "
VMSTAT_WORKINGSET_ACTIVATE, // ul_int "
VMSTAT_WORKINGSET_NODERECLAIM, // ul_int "
VMSTAT_WORKINGSET_NODES, // ul_int "
VMSTAT_WORKINGSET_REFAULT, // ul_int "
VMSTAT_WORKINGSET_RESTORE, // ul_int "
VMSTAT_ZONE_RECLAIM_FAILED, // ul_int "
VMSTAT_DELTA_ALLOCSTALL_DMA, // sl_int derived from above
VMSTAT_DELTA_ALLOCSTALL_DMA32, // sl_int "
VMSTAT_DELTA_ALLOCSTALL_HIGH, // sl_int "
VMSTAT_DELTA_ALLOCSTALL_MOVABLE, // sl_int "
VMSTAT_DELTA_ALLOCSTALL_NORMAL, // sl_int "
VMSTAT_DELTA_BALLOON_DEFLATE, // sl_int "
VMSTAT_DELTA_BALLOON_INFLATE, // sl_int "
VMSTAT_DELTA_BALLOON_MIGRATE, // sl_int "
VMSTAT_DELTA_COMPACT_DAEMON_FREE_SCANNED, // sl_int "
VMSTAT_DELTA_COMPACT_DAEMON_MIGRATE_SCANNED, // sl_int "
VMSTAT_DELTA_COMPACT_DAEMON_WAKE, // sl_int "
VMSTAT_DELTA_COMPACT_FAIL, // sl_int "
VMSTAT_DELTA_COMPACT_FREE_SCANNED, // sl_int "
VMSTAT_DELTA_COMPACT_ISOLATED, // sl_int "
VMSTAT_DELTA_COMPACT_MIGRATE_SCANNED, // sl_int "
VMSTAT_DELTA_COMPACT_STALL, // sl_int "
VMSTAT_DELTA_COMPACT_SUCCESS, // sl_int "
VMSTAT_DELTA_DROP_PAGECACHE, // sl_int "
VMSTAT_DELTA_DROP_SLAB, // sl_int "
VMSTAT_DELTA_HTLB_BUDDY_ALLOC_FAIL, // sl_int "
VMSTAT_DELTA_HTLB_BUDDY_ALLOC_SUCCESS, // sl_int "
VMSTAT_DELTA_KSWAPD_HIGH_WMARK_HIT_QUICKLY, // sl_int "
VMSTAT_DELTA_KSWAPD_INODESTEAL, // sl_int "
VMSTAT_DELTA_KSWAPD_LOW_WMARK_HIT_QUICKLY, // sl_int "
VMSTAT_DELTA_NR_ACTIVE_ANON, // sl_int "
VMSTAT_DELTA_NR_ACTIVE_FILE, // sl_int "
VMSTAT_DELTA_NR_ANON_PAGES, // sl_int "
VMSTAT_DELTA_NR_ANON_TRANSPARENT_HUGEPAGES, // sl_int "
VMSTAT_DELTA_NR_BOUNCE, // sl_int "
VMSTAT_DELTA_NR_DIRTIED, // sl_int "
VMSTAT_DELTA_NR_DIRTY, // sl_int "
VMSTAT_DELTA_NR_DIRTY_BACKGROUND_THRESHOLD, // sl_int "
VMSTAT_DELTA_NR_DIRTY_THRESHOLD, // sl_int "
VMSTAT_DELTA_NR_FILE_HUGEPAGES, // sl_int "
VMSTAT_DELTA_NR_FILE_PAGES, // sl_int "
VMSTAT_DELTA_NR_FILE_PMDMAPPED, // sl_int "
VMSTAT_DELTA_NR_FOLL_PIN_ACQUIRED, // sl_int "
VMSTAT_DELTA_NR_FOLL_PIN_RELEASED, // sl_int "
VMSTAT_DELTA_NR_FREE_CMA, // sl_int "
VMSTAT_DELTA_NR_FREE_PAGES, // sl_int "
VMSTAT_DELTA_NR_INACTIVE_ANON, // sl_int "
VMSTAT_DELTA_NR_INACTIVE_FILE, // sl_int "
VMSTAT_DELTA_NR_ISOLATED_ANON, // sl_int "
VMSTAT_DELTA_NR_ISOLATED_FILE, // sl_int "
VMSTAT_DELTA_NR_KERNEL_MISC_RECLAIMABLE, // sl_int "
VMSTAT_DELTA_NR_KERNEL_STACK, // sl_int "
VMSTAT_DELTA_NR_MAPPED, // sl_int "
VMSTAT_DELTA_NR_MLOCK, // sl_int "
VMSTAT_DELTA_NR_PAGE_TABLE_PAGES, // sl_int "
VMSTAT_DELTA_NR_SHADOW_CALL_STACK, // sl_int "
VMSTAT_DELTA_NR_SHMEM, // sl_int "
VMSTAT_DELTA_NR_SHMEM_HUGEPAGES, // sl_int "
VMSTAT_DELTA_NR_SHMEM_PMDMAPPED, // sl_int "
VMSTAT_DELTA_NR_SLAB_RECLAIMABLE, // sl_int "
VMSTAT_DELTA_NR_SLAB_UNRECLAIMABLE, // sl_int "
VMSTAT_DELTA_NR_UNEVICTABLE, // sl_int "
VMSTAT_DELTA_NR_UNSTABLE, // sl_int "
VMSTAT_DELTA_NR_VMSCAN_IMMEDIATE_RECLAIM, // sl_int "
VMSTAT_DELTA_NR_VMSCAN_WRITE, // sl_int "
VMSTAT_DELTA_NR_WRITEBACK, // sl_int "
VMSTAT_DELTA_NR_WRITEBACK_TEMP, // sl_int "
VMSTAT_DELTA_NR_WRITTEN, // sl_int "
VMSTAT_DELTA_NR_ZONE_ACTIVE_ANON, // sl_int "
VMSTAT_DELTA_NR_ZONE_ACTIVE_FILE, // sl_int "
VMSTAT_DELTA_NR_ZONE_INACTIVE_ANON, // sl_int "
VMSTAT_DELTA_NR_ZONE_INACTIVE_FILE, // sl_int "
VMSTAT_DELTA_NR_ZONE_UNEVICTABLE, // sl_int "
VMSTAT_DELTA_NR_ZONE_WRITE_PENDING, // sl_int "
VMSTAT_DELTA_NR_ZSPAGES, // sl_int "
VMSTAT_DELTA_NUMA_FOREIGN, // sl_int "
VMSTAT_DELTA_NUMA_HINT_FAULTS, // sl_int "
VMSTAT_DELTA_NUMA_HINT_FAULTS_LOCAL, // sl_int "
VMSTAT_DELTA_NUMA_HIT, // sl_int "
VMSTAT_DELTA_NUMA_HUGE_PTE_UPDATES, // sl_int "
VMSTAT_DELTA_NUMA_INTERLEAVE, // sl_int "
VMSTAT_DELTA_NUMA_LOCAL, // sl_int "
VMSTAT_DELTA_NUMA_MISS, // sl_int "
VMSTAT_DELTA_NUMA_OTHER, // sl_int "
VMSTAT_DELTA_NUMA_PAGES_MIGRATED, // sl_int "
VMSTAT_DELTA_NUMA_PTE_UPDATES, // sl_int "
VMSTAT_DELTA_OOM_KILL, // sl_int "
VMSTAT_DELTA_PAGEOUTRUN, // sl_int "
VMSTAT_DELTA_PGACTIVATE, // sl_int "
VMSTAT_DELTA_PGALLOC_DMA, // sl_int "
VMSTAT_DELTA_PGALLOC_DMA32, // sl_int "
VMSTAT_DELTA_PGALLOC_HIGH, // sl_int "
VMSTAT_DELTA_PGALLOC_MOVABLE, // sl_int "
VMSTAT_DELTA_PGALLOC_NORMAL, // sl_int "
VMSTAT_DELTA_PGDEACTIVATE, // sl_int "
VMSTAT_DELTA_PGFAULT, // sl_int "
VMSTAT_DELTA_PGFREE, // sl_int "
VMSTAT_DELTA_PGINODESTEAL, // sl_int "
VMSTAT_DELTA_PGLAZYFREE, // sl_int "
VMSTAT_DELTA_PGLAZYFREED, // sl_int "
VMSTAT_DELTA_PGMAJFAULT, // sl_int "
VMSTAT_DELTA_PGMIGRATE_FAIL, // sl_int "
VMSTAT_DELTA_PGMIGRATE_SUCCESS, // sl_int "
VMSTAT_DELTA_PGPGIN, // sl_int "
VMSTAT_DELTA_PGPGOUT, // sl_int "
VMSTAT_DELTA_PGREFILL, // sl_int "
VMSTAT_DELTA_PGROTATED, // sl_int "
VMSTAT_DELTA_PGSCAN_ANON, // sl_int "
VMSTAT_DELTA_PGSCAN_DIRECT, // sl_int "
VMSTAT_DELTA_PGSCAN_DIRECT_THROTTLE, // sl_int "
VMSTAT_DELTA_PGSCAN_FILE, // sl_int "
VMSTAT_DELTA_PGSCAN_KSWAPD, // sl_int "
VMSTAT_DELTA_PGSKIP_DMA, // sl_int "
VMSTAT_DELTA_PGSKIP_DMA32, // sl_int "
VMSTAT_DELTA_PGSKIP_HIGH, // sl_int "
VMSTAT_DELTA_PGSKIP_MOVABLE, // sl_int "
VMSTAT_DELTA_PGSKIP_NORMAL, // sl_int "
VMSTAT_DELTA_PGSTEAL_ANON, // sl_int "
VMSTAT_DELTA_PGSTEAL_DIRECT, // sl_int "
VMSTAT_DELTA_PGSTEAL_FILE, // sl_int "
VMSTAT_DELTA_PGSTEAL_KSWAPD, // sl_int "
VMSTAT_DELTA_PSWPIN, // sl_int "
VMSTAT_DELTA_PSWPOUT, // sl_int "
VMSTAT_DELTA_SLABS_SCANNED, // sl_int "
VMSTAT_DELTA_SWAP_RA, // sl_int "
VMSTAT_DELTA_SWAP_RA_HIT, // sl_int "
VMSTAT_DELTA_THP_COLLAPSE_ALLOC, // sl_int "
VMSTAT_DELTA_THP_COLLAPSE_ALLOC_FAILED, // sl_int "
VMSTAT_DELTA_THP_DEFERRED_SPLIT_PAGE, // sl_int "
VMSTAT_DELTA_THP_FAULT_ALLOC, // sl_int "
VMSTAT_DELTA_THP_FAULT_FALLBACK, // sl_int "
VMSTAT_DELTA_THP_FAULT_FALLBACK_CHARGE, // sl_int "
VMSTAT_DELTA_THP_FILE_ALLOC, // sl_int "
VMSTAT_DELTA_THP_FILE_FALLBACK, // sl_int "
VMSTAT_DELTA_THP_FILE_FALLBACK_CHARGE, // sl_int "
VMSTAT_DELTA_THP_FILE_MAPPED, // sl_int "
VMSTAT_DELTA_THP_SPLIT_PAGE, // sl_int "
VMSTAT_DELTA_THP_SPLIT_PAGE_FAILED, // sl_int "
VMSTAT_DELTA_THP_SPLIT_PMD, // sl_int "
VMSTAT_DELTA_THP_SPLIT_PUD, // sl_int "
VMSTAT_DELTA_THP_SWPOUT, // sl_int "
VMSTAT_DELTA_THP_SWPOUT_FALLBACK, // sl_int "
VMSTAT_DELTA_THP_ZERO_PAGE_ALLOC, // sl_int "
VMSTAT_DELTA_THP_ZERO_PAGE_ALLOC_FAILED, // sl_int "
VMSTAT_DELTA_UNEVICTABLE_PGS_CLEARED, // sl_int "
VMSTAT_DELTA_UNEVICTABLE_PGS_CULLED, // sl_int "
VMSTAT_DELTA_UNEVICTABLE_PGS_MLOCKED, // sl_int "
VMSTAT_DELTA_UNEVICTABLE_PGS_MUNLOCKED, // sl_int "
VMSTAT_DELTA_UNEVICTABLE_PGS_RESCUED, // sl_int "
VMSTAT_DELTA_UNEVICTABLE_PGS_SCANNED, // sl_int "
VMSTAT_DELTA_UNEVICTABLE_PGS_STRANDED, // sl_int "
VMSTAT_DELTA_WORKINGSET_ACTIVATE, // sl_int "
VMSTAT_DELTA_WORKINGSET_NODERECLAIM, // sl_int "
VMSTAT_DELTA_WORKINGSET_NODES, // sl_int "
VMSTAT_DELTA_WORKINGSET_REFAULT, // sl_int "
VMSTAT_DELTA_WORKINGSET_RESTORE, // sl_int "
VMSTAT_DELTA_ZONE_RECLAIM_FAILED // sl_int "
};
struct vmstat_result {
enum vmstat_item item;
union {
signed long sl_int;
unsigned long ul_int;
} result;
};
struct vmstat_stack {
struct vmstat_result *head;
};
struct vmstat_info;
#define VMSTAT_GET( info, actual_enum, type ) ( { \
struct vmstat_result *r = procps_vmstat_get( info, actual_enum ); \
r ? r->result . type : 0; } )
#define VMSTAT_VAL( relative_enum, type, stack, info ) \
stack -> head [ relative_enum ] . result . type
int procps_vmstat_new (struct vmstat_info **info);
int procps_vmstat_ref (struct vmstat_info *info);
int procps_vmstat_unref (struct vmstat_info **info);
struct vmstat_result *procps_vmstat_get (
struct vmstat_info *info,
enum vmstat_item item);
struct vmstat_stack *procps_vmstat_select (
struct vmstat_info *info,
enum vmstat_item *items,
int numitems);
#ifdef XTRA_PROCPS_DEBUG
# include "xtra-procps-debug.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

6
library/include/wchan.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef PROCPS_PROC_WCHAN_H
#define PROCPS_PROC_WCHAN_H
extern const char *lookup_wchan (int pid);
#endif

View File

@@ -0,0 +1,208 @@
/*
* libprocps - Library to read proc filesystem
*
* Copyright (C) 2016-2022 Jim Warner <james.warner@comcast.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define STRINGIFY_ARG(a) #a
#define STRINGIFY(a) STRINGIFY_ARG(a)
// --- DISKSTATS ------------------------------------------
#if defined(PROCPS_DISKSTATS_H) && !defined(PROCPS_DISKSTATS_H_DEBUG)
#define PROCPS_DISKSTATS_H_DEBUG
struct diskstats_result *xtra_diskstats_get (
struct diskstats_info *info,
const char *name,
enum diskstats_item actual_enum,
const char *typestr,
const char *file,
int lineno);
# undef DISKSTATS_GET
#define DISKSTATS_GET( info, name, actual_enum, type ) ( { \
struct diskstats_result *r; \
r = xtra_diskstats_get(info, name, actual_enum , STRINGIFY(type), __FILE__, __LINE__); \
r ? r->result . type : 0; } )
struct diskstats_result *xtra_diskstats_val (
int relative_enum,
const char *typestr,
const struct diskstats_stack *stack,
struct diskstats_info *info,
const char *file,
int lineno);
# undef DISKSTATS_VAL
#define DISKSTATS_VAL( relative_enum, type, stack, info ) ( { \
struct diskstats_result *r; \
r = xtra_diskstats_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \
r ? r->result . type : 0; } )
#endif // . . . . . . . . . .
// --- MEMINFO --------------------------------------------
#if defined(PROCPS_MEMINFO_H) && !defined(PROCPS_MEMINFO_H_DEBUG)
#define PROCPS_MEMINFO_H_DEBUG
struct meminfo_result *xtra_meminfo_get (
struct meminfo_info *info,
enum meminfo_item actual_enum,
const char *typestr,
const char *file,
int lineno);
# undef MEMINFO_GET
#define MEMINFO_GET( info, actual_enum, type ) ( { \
struct meminfo_result *r; \
r = xtra_meminfo_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__); \
r ? r->result . type : 0; } )
struct meminfo_result *xtra_meminfo_val (
int relative_enum,
const char *typestr,
const struct meminfo_stack *stack,
struct meminfo_info *info,
const char *file,
int lineno);
# undef MEMINFO_VAL
#define MEMINFO_VAL( relative_enum, type, stack, info ) ( { \
struct meminfo_result *r; \
r = xtra_meminfo_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \
r ? r->result . type : 0; } )
#endif // . . . . . . . . . .
// --- PIDS -----------------------------------------------
#if defined(PROCPS_PIDS_H) && !defined(PROCPS_PIDS_H_DEBUG)
#define PROCPS_PIDS_H_DEBUG
struct pids_result *xtra_pids_val (
int relative_enum,
const char *typestr,
const struct pids_stack *stack,
struct pids_info *info,
const char *file,
int lineno);
# undef PIDS_VAL
#define PIDS_VAL( relative_enum, type, stack, info ) ( { \
struct pids_result *r; \
r = xtra_pids_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \
r ? r->result . type : 0; } )
#endif // . . . . . . . . . .
// --- SLABINFO -------------------------------------------
#if defined(PROCPS_SLABINFO_H) && !defined(PROCPS_SLABINFO_H_DEBUG)
#define PROCPS_SLABINFO_H_DEBUG
struct slabinfo_result *xtra_slabinfo_get (
struct slabinfo_info *info,
enum slabinfo_item actual_enum,
const char *typestr,
const char *file,
int lineno);
# undef SLABINFO_GET
#define SLABINFO_GET( info, actual_enum, type ) ( { \
struct slabinfo_result *r; \
r = xtra_slabinfo_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__); \
r ? r->result . type : 0; } )
struct slabinfo_result *xtra_slabinfo_val (
int relative_enum,
const char *typestr,
const struct slabinfo_stack *stack,
struct slabinfo_info *info,
const char *file,
int lineno);
# undef SLABINFO_VAL
#define SLABINFO_VAL( relative_enum, type, stack, info ) ( { \
struct slabinfo_result *r; \
r = xtra_slabinfo_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \
r ? r->result . type : 0; } )
#endif // . . . . . . . . . .
// --- STAT -----------------------------------------------
#if defined(PROCPS_STAT_H) && !defined(PROCPS_STAT_H_DEBUG)
#define PROCPS_STAT_H_DEBUG
struct stat_result *xtra_stat_get (
struct stat_info *info,
enum stat_item actual_enum,
const char *typestr,
const char *file,
int lineno);
# undef STAT_GET
#define STAT_GET( info, actual_enum, type ) ( { \
struct stat_result *r; \
r = xtra_stat_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__); \
r ? r->result . type : 0; } )
struct stat_result *xtra_stat_val (
int relative_enum,
const char *typestr,
const struct stat_stack *stack,
struct stat_info *info,
const char *file,
int lineno);
# undef STAT_VAL
#define STAT_VAL( relative_enum, type, stack, info ) ( { \
struct stat_result *r; \
r = xtra_stat_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \
r ? r->result . type : 0; } )
#endif // . . . . . . . . . .
// --- VMSTAT ---------------------------------------------
#if defined(PROCPS_VMSTAT_H) && !defined(PROCPS_VMSTAT_H_DEBUG)
#define PROCPS_VMSTAT_H_DEBUG
struct vmstat_result *xtra_vmstat_get (
struct vmstat_info *info,
enum vmstat_item actual_enum,
const char *typestr,
const char *file,
int lineno);
# undef VMSTAT_GET
#define VMSTAT_GET( info, actual_enum, type ) ( { \
struct vmstat_result *r; \
r = xtra_vmstat_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__); \
r ? r->result . type : 0; } )
struct vmstat_result *xtra_vmstat_val (
int relative_enum,
const char *typestr,
const struct vmstat_stack *stack,
struct vmstat_info *info,
const char *file,
int lineno);
# undef VMSTAT_VAL
#define VMSTAT_VAL( relative_enum, type, stack, info ) ( { \
struct vmstat_result *r; \
r = xtra_vmstat_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \
r ? r->result . type : 0; } )
#endif // . . . . . . . . . .

11
library/libproc-2.pc.in Normal file
View File

@@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libproc-2
Description: Library to control and query process state
Version: @VERSION@
Libs: -L${libdir} -lproc-2
Libs.private:
Cflags: -I${includedir}

67
library/libproc-2.sym Normal file
View File

@@ -0,0 +1,67 @@
LIBPROC_2 {
global:
fatal_proc_unmounted;
procps_cpu_count;
procps_diskstats_new;
procps_diskstats_ref;
procps_diskstats_unref;
procps_diskstats_get;
procps_diskstats_reap;
procps_diskstats_select;
procps_diskstats_sort;
procps_hertz_get;
procps_linux_version;
procps_loadavg;
procps_meminfo_new;
procps_meminfo_ref;
procps_meminfo_unref;
procps_meminfo_get;
procps_meminfo_select;
procps_ns_get_name;
procps_ns_get_id;
procps_ns_read_pid;
procps_pid_length;
procps_pids_new;
procps_pids_ref;
procps_pids_unref;
procps_pids_get;
procps_pids_reap;
procps_pids_reset;
procps_pids_select;
procps_pids_sort;
procps_slabinfo_new;
procps_slabinfo_ref;
procps_slabinfo_unref;
procps_slabinfo_get;
procps_slabinfo_reap;
procps_slabinfo_select;
procps_slabinfo_sort;
procps_stat_new;
procps_stat_ref;
procps_stat_unref;
procps_stat_get;
procps_stat_reap;
procps_stat_select;
procps_stat_sort;
procps_uptime;
procps_uptime_sprint;
procps_uptime_sprint_short;
procps_vmstat_new;
procps_vmstat_ref;
procps_vmstat_unref;
procps_vmstat_get;
procps_vmstat_select;
xtra_diskstats_get;
xtra_diskstats_val;
xtra_meminfo_get;
xtra_meminfo_val;
xtra_pids_val;
xtra_slabinfo_get;
xtra_slabinfo_val;
xtra_stat_get;
xtra_stat_val;
xtra_vmstat_get;
xtra_vmstat_val;
local:
*;
};

1016
library/meminfo.c Normal file

File diff suppressed because it is too large Load Diff

113
library/namespace.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* libprocps - Library to read proc filesystem
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "misc.h"
#include "procps-private.h"
#define NSPATHLEN 64
static const char *ns_names[] = {
[PROCPS_NS_CGROUP] = "cgroup",
[PROCPS_NS_IPC] = "ipc",
[PROCPS_NS_MNT] = "mnt",
[PROCPS_NS_NET] = "net",
[PROCPS_NS_PID] = "pid",
[PROCPS_NS_TIME] = "time",
[PROCPS_NS_USER] = "user",
[PROCPS_NS_UTS] = "uts"
};
/*
* procps_ns_get_name:
*
* Find the name of the namespace with the given ID
*
* @id: The ID of the required namespace, see
* namespace_type
*
* Returns: static string of the namespace
*/
PROCPS_EXPORT const char *procps_ns_get_name(const int id)
{
if (id >= PROCPS_NS_COUNT || id < 0)
return NULL;
return ns_names[id];
}
/*
* procps_ns_get_id:
*
* Find the namespace ID that matches the given
* name.
*
* @name: the name of the required namespace
*
* Returns: ID of found name
* < 0 means error
*/
PROCPS_EXPORT int procps_ns_get_id(const char *name)
{
int i;
if (name == NULL)
return -EINVAL;
for (i=0; i < PROCPS_NS_COUNT; i++)
if (!strcmp(ns_names[i], name))
return i;
return -EINVAL;
}
/*
* procs_ns_read_pid:
*
* Find all namespaces for the given process.
* @pid: Process ID for required process
* @nsp: Pointer to the struct procps_ns
*
* Returns:
* 0 on success
* < 0 on error
*/
PROCPS_EXPORT int procps_ns_read_pid(
const int pid,
struct procps_ns *nsp)
{
char path[NSPATHLEN+1];
struct stat st;
int i;
if (nsp == NULL)
return -EINVAL;
if (pid < 1)
return -EINVAL;
for (i=0; i < PROCPS_NS_COUNT; i++) {
snprintf(path, NSPATHLEN, "/proc/%d/ns/%s", pid, ns_names[i]);
if (0 == stat(path, &st))
nsp->ns[i] = (unsigned long)st.st_ino;
else
nsp->ns[i] = 0;
}
return 0;
}

113
library/numa.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* NUMA node support for <PIDS> & <STAT> interfaces
* Copyright 2017-2022 by James C. Warmer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef NUMA_DISABLE
#include <dlfcn.h>
#endif
#include <stdlib.h>
#include "numa.h"
/*
* We're structured so that if numa_init() is NOT called or that ./configure |
* --disable-numa WAS specified, then calls to both of our primary functions |
* of numa_max_node() plus numa_node_of_cpu() would always return a negative |
* 1 which signifies that NUMA information isn't available. That ./configure |
* option might be required when libdl.so (necessary for dlopen) is missing. |
*/
/* ------------------------------------------------------------------------- +
a strictly development #define, existing specifically for the top program |
( and it has no affect if ./configure --disable-numa has been specified ) | */
//#define PRETEND_NUMA // pretend there are 3 'discontiguous' numa nodes |
// ------------------------------------------------------------------------- +
static int null_max_node (void) { return -1; }
static int null_node_of_cpu (int n) { (void)n; return -1; }
#ifndef NUMA_DISABLE
#ifdef PRETEND_NUMA
static int fake_max_node (void) { return 3; }
static int fake_node_of_cpu (int n) { return (1 == (n % 4)) ? 0 : (n % 4); }
#endif
#endif
#ifndef NUMA_DISABLE
static void *libnuma_handle;
#endif
int (*numa_max_node) (void) = null_max_node;
int (*numa_node_of_cpu) (int) = null_node_of_cpu;
void numa_init (void) {
static int initialized;
if (initialized)
return;
#ifndef NUMA_DISABLE
#ifndef PRETEND_NUMA
// we'll try for the most recent version, then a version we know works...
if ((libnuma_handle = dlopen("libnuma.so", RTLD_LAZY))
|| (libnuma_handle = dlopen("libnuma.so.1", RTLD_LAZY))) {
numa_max_node = dlsym(libnuma_handle, "numa_max_node");
numa_node_of_cpu = dlsym(libnuma_handle, "numa_node_of_cpu");
if (numa_max_node == NULL
|| (numa_node_of_cpu == NULL)) {
// this dlclose is safe - we've yet to call numa_node_of_cpu
// ( there's one other dlclose which has now been disabled )
dlclose(libnuma_handle);
libnuma_handle = NULL;
numa_max_node = null_max_node;
numa_node_of_cpu = null_node_of_cpu;
}
}
#else
libnuma_handle = (void *)-1;
numa_max_node = fake_max_node;
numa_node_of_cpu = fake_node_of_cpu;
#endif
#endif
initialized = 1;
} // end: numa_init
void numa_uninit (void) {
#ifndef PRETEND_NUMA
/* note: we'll skip a dlcose() to avoid the following libnuma memory
* leak which is triggered after a call to numa_node_of_cpu():
* ==1234== LEAK SUMMARY:
* ==1234== definitely lost: 512 bytes in 1 blocks
* ==1234== indirectly lost: 48 bytes in 2 blocks
* ==1234== ...
* [ thanks very much libnuma for all the pains you have caused us ]
*/
// if (libnuma_handle)
// dlclose(libnuma_handle);
#endif
} // end: numa_uninit
#if defined(PRETEND_NUMA) && defined(NUMA_DISABLE)
# warning 'PRETEND_NUMA' ignored, 'NUMA_DISABLE' is active
#endif

1682
library/pids.c Normal file

File diff suppressed because it is too large Load Diff

96
library/pwcache.c Normal file
View File

@@ -0,0 +1,96 @@
/*
* pwcache.c - memory cache passwd file handling
*
* Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com
* Note: most likely none of his code remains
*
* Copyright 2002, Albert Cahalan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include "pwcache.h"
#include "procps-private.h"
// might as well fill cache lines... else we waste memory anyway
#define HASHSIZE 64 /* power of 2 */
#define HASH(x) ((x) & (HASHSIZE - 1))
static char ERRname[] = "?";
static __thread struct pwbuf {
struct pwbuf *next;
uid_t uid;
char name[P_G_SZ];
} *pwhash[HASHSIZE];
char *pwcache_get_user(uid_t uid) {
struct pwbuf **p;
struct passwd *pw;
p = &pwhash[HASH(uid)];
while (*p) {
if ((*p)->uid == uid)
return((*p)->name);
p = &(*p)->next;
}
if (!(*p = (struct pwbuf *)malloc(sizeof(struct pwbuf))))
return ERRname;
(*p)->uid = uid;
pw = getpwuid(uid);
if(!pw || strlen(pw->pw_name) >= P_G_SZ)
sprintf((*p)->name, "%u", uid);
else
strcpy((*p)->name, pw->pw_name);
(*p)->next = NULL;
return((*p)->name);
}
static __thread struct grpbuf {
struct grpbuf *next;
gid_t gid;
char name[P_G_SZ];
} *grphash[HASHSIZE];
char *pwcache_get_group(gid_t gid) {
struct grpbuf **g;
struct group *gr;
g = &grphash[HASH(gid)];
while (*g) {
if ((*g)->gid == gid)
return((*g)->name);
g = &(*g)->next;
}
if (!(*g = (struct grpbuf *)malloc(sizeof(struct grpbuf))))
return ERRname;;
(*g)->gid = gid;
gr = getgrgid(gid);
if (!gr || strlen(gr->gr_name) >= P_G_SZ)
sprintf((*g)->name, "%u", gid);
else
strcpy((*g)->name, gr->gr_name);
(*g)->next = NULL;
return((*g)->name);
}

1619
library/readproc.c Normal file

File diff suppressed because it is too large Load Diff

1039
library/slabinfo.c Normal file

File diff suppressed because it is too large Load Diff

1240
library/stat.c Normal file

File diff suppressed because it is too large Load Diff

165
library/sysinfo.c Normal file
View File

@@ -0,0 +1,165 @@
/*
* File for parsing top-level /proc entities.
* Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com
* Copyright 1998-2003 Albert Cahalan
* June 2003, Fabian Frederick, slab info
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <locale.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef __CYGWIN__
#include <sys/param.h>
#endif
#include "misc.h"
#include "procps-private.h"
#define LOADAVG_FILE "/proc/loadavg"
/* evals 'x' twice */
#define SET_IF_DESIRED(x,y) do{ if(x) *(x) = (y); }while(0)
/* return minimum of two values */
#ifndef __CYGWIN__
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif
/*
* procps_hertz_get:
*
*
* Some values in /proc are expressed in units of 1/HZ seconds, where HZ
* is the kernel clock tick rate. One of these units is called a jiffy.
* The HZ value used in the kernel may vary according to hacker desire.
*
* On some architectures, the kernel provides an ELF note to indicate
* HZ.
*
* Returns:
* The discovered or assumed hertz value
*/
PROCPS_EXPORT long procps_hertz_get(void)
{
long hz;
#ifdef _SC_CLK_TCK
if ((hz = sysconf(_SC_CLK_TCK)) > 0)
return hz;
#endif
#ifdef HZ
return(HZ);
#endif
/* Last resort, assume 100 */
return 100;
}
/*
* procps_loadavg:
* @av1: location to store 1 minute load average
* @av5: location to store 5 minute load average
* @av15: location to store 15 minute load average
*
* Find the 1,5 and 15 minute load average of the system
*
* Returns: 0 on success <0 on error
*/
PROCPS_EXPORT int procps_loadavg(
double *restrict av1,
double *restrict av5,
double *restrict av15)
{
double avg_1=0, avg_5=0, avg_15=0;
locale_t tmplocale;
int retval=0;
FILE *fp;
if ((fp = fopen(LOADAVG_FILE, "r")) == NULL)
return -errno;
tmplocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
uselocale(tmplocale);
if (fscanf(fp, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3)
retval = -ERANGE;
fclose(fp);
uselocale(LC_GLOBAL_LOCALE);
freelocale(tmplocale);
SET_IF_DESIRED(av1, avg_1);
SET_IF_DESIRED(av5, avg_5);
SET_IF_DESIRED(av15, avg_15);
return retval;
}
/////////////////////////////////////////////////////////////////////////////
#define PROCFS_PID_MAX "/proc/sys/kernel/pid_max"
#define DEFAULT_PID_LENGTH 5
/*
* procps_pid_length
*
* Return the length of the maximum possible pid.
*
* Returns either the strlen of PROCFS_PID_MAX or the
* best-guess DEFAULT_PID_LENGTH
*/
PROCPS_EXPORT unsigned int procps_pid_length(void)
{
FILE *fp;
char pidbuf[24];
static __thread int pid_length=0;
if (pid_length)
return pid_length;
pid_length = DEFAULT_PID_LENGTH;
if ((fp = fopen(PROCFS_PID_MAX, "r")) != NULL) {
if (fgets(pidbuf, sizeof(pidbuf), fp) != NULL) {
pid_length = strlen(pidbuf);
if (pidbuf[pid_length-1] == '\n')
--pid_length;
}
fclose(fp);
}
return pid_length;
}
///////////////////////////////////////////////////////////////////////////
/* procps_cpu_count:
*
* Returns the number of CPUs that are currently online.
*
*/
long procps_cpu_count(void)
{
long cpus;
cpus = sysconf(_SC_NPROCESSORS_ONLN);
if (cpus < 1)
return 1;
return cpus;
}

View File

@@ -0,0 +1,91 @@
/*
* libprocps - Library to read proc filesystem
* Tests for Item_table/enumerator synchronization
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include "diskstats.h"
#include "meminfo.h"
#include "pids.h"
#include "slabinfo.h"
#include "stat.h"
#include "vmstat.h"
#include "tests.h"
static int check_diskstats (void *data) {
struct diskstats_info *ctx = NULL;
testname = "Itemtable check, diskstats";
if (0 == procps_diskstats_new(&ctx))
procps_diskstats_unref(&ctx);
return 1;
}
static int check_meminfo (void *data) {
struct meminfo_info *ctx = NULL;
testname = "Itemtable check, meminfo";
if (0 == procps_meminfo_new(&ctx))
procps_meminfo_unref(&ctx);
return 1;
}
static int check_pids (void *data) {
struct pids_info *ctx = NULL;
testname = "Itemtable check, pids";
if (0 == procps_pids_new(&ctx, NULL, 0))
procps_pids_unref(&ctx);
return 1;
}
static int check_slabinfo (void *data) {
struct slabinfo_info *ctx = NULL;
testname = "Itemtable check, slabinfo";
if (0 == procps_slabinfo_new(&ctx))
procps_slabinfo_unref(&ctx);
return 1;
}
static int check_stat (void *data) {
struct stat_info *ctx = NULL;
testname = "Itemtable check, stat";
if (0 == procps_stat_new(&ctx))
procps_stat_unref(&ctx);
return 1;
}
static int check_vmstat (void *data) {
struct vmstat_info *ctx = NULL;
testname = "Itemtable check, vmstat";
if (0 == procps_vmstat_new(&ctx))
procps_vmstat_unref(&ctx);
return 1;
}
static TestFunction test_funcs[] = {
check_diskstats,
check_meminfo,
check_pids,
check_slabinfo,
check_stat,
check_vmstat,
NULL
};
int main (void) {
return run_tests(test_funcs, NULL);
}

View File

@@ -0,0 +1,76 @@
/*
* libprocps - Library to read proc filesystem
* Tests for namespace library calls
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "misc.h"
#include "tests.h"
int check_name_minus(void *data)
{
testname = "procps_ns_get_name() negative id";
return (procps_ns_get_name(-1) == NULL);
}
int check_name_over(void *data)
{
testname = "procps_ns_get_name() id over limit";
return (procps_ns_get_name(999) == NULL);
}
int check_name_ipc(void *data)
{
testname = "procps_ns_get_name() ipc";
return (strcmp(procps_ns_get_name(PROCPS_NS_IPC),"ipc")==0);
}
int check_id_null(void *data)
{
testname = "procps_ns_get_id(NULL)";
return (procps_ns_get_id(NULL) < 0);
}
int check_id_unfound(void *data)
{
testname = "procps_ns_get_id(unknown)";
return (procps_ns_get_id("foobar") < 0);
}
int check_id_mnt(void *data)
{
testname = "procps_ns_get_id(mnt)";
return (procps_ns_get_id("mnt") == PROCPS_NS_MNT);
}
TestFunction test_funcs[] = {
check_name_minus,
check_name_over,
check_name_ipc,
check_id_null,
check_id_unfound,
check_id_mnt,
NULL
};
int main(int argc, char *argv[])
{
return run_tests(test_funcs, NULL);
}

75
library/tests/test_pids.c Normal file
View File

@@ -0,0 +1,75 @@
/*
* libprocps - Library to read proc filesystem
* Tests for pids library calls
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "pids.h"
#include "tests.h"
enum pids_item items[] = { PIDS_ID_PID, PIDS_ID_PID };
enum pids_item items2[] = { PIDS_ID_PID, PIDS_VM_RSS };
int check_pids_new_nullinfo(void *data)
{
testname = "procps_pids_new() info=NULL returns -EINVAL";
return (procps_pids_new(NULL, items, 0) == -EINVAL);
}
int check_pids_new_toomany(void *data)
{
struct pids_info *info;
testname = "procps_pids_new() too many items returns -EINVAL";
return (procps_pids_new(&info, items, 1) == -EINVAL);
}
int check_pids_new_and_unref(void *data)
{
struct pids_info *info = NULL;
testname = "procps_pids new then unref";
return ( (procps_pids_new(&info, items, 2) == 0) &&
(procps_pids_unref(&info) == 0) &&
info == NULL);
}
int check_fatal_proc_unmounted(void *data)
{
struct pids_info *info = NULL;
struct pids_stack *stack;
testname = "check_fatal_proc_unmounted";
return ( (procps_pids_new(&info, items2, 2) == 0) &&
( (stack = fatal_proc_unmounted(info, 1)) != NULL) &&
( PIDS_VAL(0, s_int, stack, info) > 0) &&
( PIDS_VAL(1, u_int, stack, info) > 0));
}
TestFunction test_funcs[] = {
check_pids_new_nullinfo,
// skipped, ask Jim check_pids_new_toomany,
check_pids_new_and_unref,
check_fatal_proc_unmounted,
NULL };
int main(int argc, char *argv[])
{
return run_tests(test_funcs, NULL);
}

View File

@@ -0,0 +1,64 @@
/*
* libprocps - Library to read proc filesystem
* Tests for sysinfo library calls
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include "misc.h"
#include "tests.h"
int check_hertz(void *data)
{
long hz;
testname = "procps_hertz_get()";
hz = procps_hertz_get();
return (hz > 0);
}
int check_loadavg(void *data)
{
double a,b,c;
testname = "procps_loadavg()";
if (procps_loadavg(&a, &b, &c) == 0)
return 1;
return (a>0 && b>0 && c>0);
}
int check_loadavg_null(void *data)
{
testname = "procps_loadavg() with NULLs";
if (procps_loadavg(NULL, NULL, NULL) == 0)
return 1;
return 0;
}
TestFunction test_funcs[] = {
check_hertz,
check_loadavg,
check_loadavg_null,
NULL,
};
int main(int argc, char *argv[])
{
return run_tests(test_funcs, NULL);
}

View File

@@ -0,0 +1,97 @@
/*
* libprocps - Library to read proc filesystem
* Tests for version library calls
*
* Copyright 2016 Craig Small <csmall@dropbear.xyz>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include "misc.h"
#include "tests.h"
int check_uptime(void *data)
{
testname = "procps_uptime()";
double up=0, idle=0;
int rc;
rc = procps_uptime(&up, &idle);
return (rc == 0 && up > 0 && idle > 0);
}
int check_uptime_nullup(void *data)
{
double idle=0;
int rc;
testname = "procps_uptime() (up=NULL)";
rc = procps_uptime(NULL, &idle);
return (rc == 0 && idle > 0);
}
int check_uptime_nullidle(void *data)
{
double up=0;
int rc;
testname = "procps_uptime() (idle=NULL)";
rc = procps_uptime(&up, NULL);
return (rc == 0 && up > 0);
}
int check_uptime_nullall(void *data)
{
int rc;
testname = "procps_uptime() (up,idle=NULL)";
rc = procps_uptime(NULL, NULL);
return (rc == 0);
}
int check_uptime_sprint(void *data)
{
char *str;
testname = "procps_uptime_sprint()";
str = procps_uptime_sprint();
return (str != NULL && str[0] != '\0');
}
int check_uptime_sprint_short(void *data)
{
char *str;
testname = "procps_uptime_sprint_short()";
str = procps_uptime_sprint_short();
return (str != NULL && str[0] != '\0');
}
TestFunction test_funcs[] = {
check_uptime,
check_uptime_nullup,
check_uptime_nullidle,
check_uptime_nullall,
check_uptime_sprint,
check_uptime_sprint_short,
NULL,
};
int main(int argc, char *argv[])
{
return run_tests(test_funcs, NULL);
}

View File

@@ -0,0 +1,72 @@
/*
* libprocps - Library to read proc filesystem
* Tests for version library calls
*
* Copyright 2016 Craig Small <csmall@dropbear.xyz>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include "misc.h"
#include "tests.h"
int check_linux_version(void *data)
{
testname = "procps_linux_version()";
return (procps_linux_version() > 0);
}
int check_conversion(void *data)
{
testname = "LINUX_VERSION macro";
struct testvals {
int retval;
int major, minor, patch;
};
struct testvals *tv;
struct testvals tvs[] = {
{ 132096, 2, 4, 0 },
{ 132635, 2, 6, 27 },
{ 199936, 3, 13, 0 },
{ 263426, 4, 5, 2 },
{ 0, 0, 0, 0}
};
for (tv=tvs; tv->major != 0; tv++)
{
if (LINUX_VERSION(tv->major, tv->minor, tv->patch) != tv->retval) {
fprintf(stderr, "Failed %d != %d\n", LINUX_VERSION(tv->major, tv->minor,
tv->patch), tv->retval);
return 0;
}
}
return 1;
}
TestFunction test_funcs[] = {
check_conversion,
check_linux_version,
NULL
};
int main(int argc, char *argv[])
{
return run_tests(test_funcs, NULL);
}

250
library/uptime.c Normal file
View File

@@ -0,0 +1,250 @@
/*
* uptime - uptime related functions - part of procps
*
* Copyright (C) 1992-1998 Michael K. Johnson <johnsonm@redhat.com>
* Copyright (C) ???? Larry Greenfield <greenfie@gauss.rutgers.edu>
* Copyright (C) 1993 J. Cowley
* Copyright (C) 1998-2003 Albert Cahalan
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <utmp.h>
#include "misc.h"
#include "procps-private.h"
#define UPTIME_FILE "/proc/uptime"
static __thread char upbuf[256];
static __thread char shortbuf[256];
static int count_users(void)
{
int numuser = 0;
struct utmp *ut;
setutent();
while ((ut = getutent())) {
if ((ut->ut_type == USER_PROCESS) && (ut->ut_name[0] != '\0'))
numuser++;
}
endutent();
return numuser;
}
/*
* uptime:
*
* Find the uptime and idle time of the system.
* These numbers are found in /proc/uptime
* Unlike other procps functions this closes the file each time
* Either uptime_secs or idle_secs can be null
*
* Returns: 0 on success and <0 on failure
*/
PROCPS_EXPORT int procps_uptime(
double *restrict uptime_secs,
double *restrict idle_secs)
{
double up=0, idle=0;
locale_t tmplocale;
FILE *fp;
int rc;
if ((fp = fopen(UPTIME_FILE, "r")) == NULL)
return -errno;
tmplocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
uselocale(tmplocale);
rc = fscanf(fp, "%lf %lf", &up, &idle);
fclose(fp);
uselocale(LC_GLOBAL_LOCALE);
freelocale(tmplocale);
if (uptime_secs)
*uptime_secs = up;
if (idle_secs)
*idle_secs = idle;
if (rc < 2)
return -ERANGE;
return 0;
}
/*
* procps_uptime_sprint:
*
* Print current time in nice format
*
* Returns a statically allocated upbuf or NULL on error
*/
PROCPS_EXPORT char *procps_uptime_sprint(void)
{
int upminutes, uphours, updays, users;
int pos;
time_t realseconds;
struct tm realtime;
double uptime_secs, idle_secs;
double av1, av5, av15;
upbuf[0] = '\0';
if (time(&realseconds) < 0)
return upbuf;
localtime_r(&realseconds, &realtime);
if (procps_uptime(&uptime_secs, &idle_secs) < 0)
return upbuf;
updays = ((int) uptime_secs / (60*60*24));
uphours = ((int) uptime_secs / (60*60)) % 24;
upminutes = ((int) uptime_secs / (60)) % 60;
pos = sprintf(upbuf, " %02d:%02d:%02d up ",
realtime.tm_hour, realtime.tm_min, realtime.tm_sec);
if (updays)
pos += sprintf(upbuf + pos, "%d %s, ", updays, (updays > 1) ? "days" : "day");
if (uphours)
pos += sprintf(upbuf + pos, "%2d:%02d, ", uphours, upminutes);
else
pos += sprintf(upbuf + pos, "%d min, ", upminutes);
users = count_users();
procps_loadavg(&av1, &av5, &av15);
pos += sprintf(upbuf + pos, "%2d %s, load average: %.2f, %.2f, %.2f",
users, users > 1 ? "users" : "user",
av1, av5, av15);
return upbuf;
}
/*
* procps_uptime_sprint_short:
*
* Print current time in nice format
*
* Returns a statically allocated buffer or NULL on error
*/
PROCPS_EXPORT char *procps_uptime_sprint_short(void)
{
int updecades, upyears, upweeks, updays, uphours = 0, upminutes = 0;
int pos = 3;
int comma = 0;
double uptime_secs, idle_secs;
shortbuf[0] = '\0';
if (procps_uptime(&uptime_secs, &idle_secs) < 0)
return shortbuf;
if (uptime_secs>60*60*24*365*10) {
updecades = (int) uptime_secs / (60*60*24*365*10);
uptime_secs -= updecades*60*60*24*365*10;
}
else {
updecades = 0;
}
if (uptime_secs>60*60*24*365) {
upyears = (int) uptime_secs / (60*60*24*365);
uptime_secs -= upyears*60*60*24*365;
}
else {
upyears = 0;
}
if (uptime_secs>60*60*24*7) {
upweeks = (int) uptime_secs / (60*60*24*7);
uptime_secs -= upweeks*60*60*24*7;
}
else {
upweeks = 0;
}
if (uptime_secs>60*60*24) {
updays = (int) uptime_secs / (60*60*24);
uptime_secs -= updays*60*60*24;
}
else {
updays = 0;
}
if (uptime_secs>60*60) {
uphours = (int) uptime_secs / (60*60);
uptime_secs -= uphours*60*60;
}
if (uptime_secs>60) {
upminutes = (int) uptime_secs / 60;
uptime_secs -= upminutes*60;
}
/*updecades = (int) uptime_secs / (60*60*24*365*10);
upyears = ((int) uptime_secs / (60*60*24*365)) % 10;
upweeks = ((int) uptime_secs / (60*60*24*7)) % 52;
updays = ((int) uptime_secs / (60*60*24)) % 7;
uphours = ((int) uptime_secs / (60*60)) % 24;
upminutes = ((int) uptime_secs / (60)) % 60;
*/
strcat(shortbuf, "up ");
if (updecades) {
pos += sprintf(shortbuf + pos, "%d %s",
updecades, updecades > 1 ? "decades" : "decade");
comma += 1;
}
if (upyears) {
pos += sprintf(shortbuf + pos, "%s%d %s",
comma > 0 ? ", " : "", upyears,
upyears > 1 ? "years" : "year");
comma += 1;
}
if (upweeks) {
pos += sprintf(shortbuf + pos, "%s%d %s",
comma > 0 ? ", " : "", upweeks,
upweeks > 1 ? "weeks" : "week");
comma += 1;
}
if (updays) {
pos += sprintf(shortbuf + pos, "%s%d %s",
comma > 0 ? ", " : "", updays,
updays > 1 ? "days" : "day");
comma += 1;
}
if (uphours) {
pos += sprintf(shortbuf + pos, "%s%d %s",
comma > 0 ? ", " : "", uphours,
uphours > 1 ? "hours" : "hour");
comma += 1;
}
if (upminutes || (!upminutes && uptime_secs < 60)) {
pos += sprintf(shortbuf + pos, "%s%d %s",
comma > 0 ? ", " : "", upminutes,
upminutes != 1 ? "minutes" : "minute");
comma += 1;
}
return shortbuf;
}

69
library/version.c Normal file
View File

@@ -0,0 +1,69 @@
/*
* libprocps - Library to read proc filesystem
*
* Copyright (C) 1995 Martin Schulze <joey@infodrom.north.de>
* Copyright (C) 1996 Charles Blake <cblake@bbn.com>
* Copyright (C) 2003 Albert Cahalan
* Copyright (C) 2015 Craig Small <csmall@dropbear.xyz>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include <stdio.h>
#include "misc.h"
#include "procps-private.h"
#ifdef __CYGWIN__
#define PROCFS_OSRELEASE "/proc/version"
#define PROCFS_OSPATTERN "%*s version %u.%u.%u"
#else
#define PROCFS_OSRELEASE "/proc/sys/kernel/osrelease"
#define PROCFS_OSPATTERN "%u.%u.%u"
#endif
/*
* procps_linux_version
*
* Return the current running Linux version release as shown in
* the procps filesystem.
*
* There are three ways you can get OS release:
* 1) /proc/sys/kernel/osrelease - returns correct version of procfs
* 2) /proc/version - returns version of kernel e.g. BSD this is wrong
* 3) uname and uts.release - same as /proc/version field #3
*
* Returns: version as an integer
* Negative value means an error
*/
PROCPS_EXPORT int procps_linux_version(void)
{
FILE *fp;
char buf[256];
unsigned int x = 0, y = 0, z = 0;
int version_string_depth;
if ((fp = fopen(PROCFS_OSRELEASE, "r")) == NULL)
return -errno;
if (fgets(buf, 256, fp) == NULL) {
fclose(fp);
return -EIO;
}
fclose(fp);
version_string_depth = sscanf(buf, PROCFS_OSPATTERN, &x, &y, &z);
if ((version_string_depth < 2) || /* Non-standard for all known kernels */
((version_string_depth < 3) && (x < 3))) /* Non-standard for 2.x.x kernels */
return -ERANGE;
return LINUX_VERSION(x,y,z);
}

1513
library/vmstat.c Normal file

File diff suppressed because it is too large Load Diff

52
library/wchan.c Normal file
View File

@@ -0,0 +1,52 @@
/*
* wchan.c - kernel symbol handling
* Copyright 1998-2003 by Albert Cahalan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include "wchan.h" // to verify prototype
const char *lookup_wchan (int pid) {
static __thread char buf[64];
const char *ret = buf;
ssize_t num;
int fd;
snprintf(buf, sizeof buf, "/proc/%d/wchan", pid);
fd = open(buf, O_RDONLY);
if (fd==-1) return "?";
num = read(fd, buf, sizeof buf - 1);
close(fd);
if (num<1) return "?"; // allow for "0"
buf[num] = '\0';
if (buf[0]=='0' && buf[1]=='\0') return "-";
// lame ppc64 has a '.' in front of every name
if (*ret=='.') ret++;
while(*ret=='_') ret++;
return ret;
}