build-sys: Relocate lib/

test files in lib go to src/tests
include/ goes to local/
lib/*.c goes to local/

Signed-off-by: Craig Small <csmall@dropbear.xyz>
This commit is contained in:
Craig Small
2022-08-29 20:28:03 +10:00
parent dcce8038be
commit 47a8676625
31 changed files with 63 additions and 59 deletions

10
local/Makefile.am Normal file
View File

@@ -0,0 +1,10 @@
dist_noinst_HEADERS = \
c.h \
fileutils.h \
nls.h \
procio.h \
rpmatch.h \
signals.h \
strutils.h \
tests.h \
xalloc.h

162
local/c.h Normal file
View File

@@ -0,0 +1,162 @@
/*
* This header was copied from util-linux at fall 2011.
*/
/*
* Fundamental C definitions.
*/
#ifndef PROCPS_NG_C_H
#define PROCPS_NG_C_H
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_ERROR_H
#include <error.h>
#else
#include <stdarg.h>
#endif
/*
* Compiler specific stuff
*/
#ifndef __GNUC_PREREQ
# if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
# else
# define __GNUC_PREREQ(maj, min) 0
# endif
#endif
/*
* Function attributes
*/
#ifndef __ul_alloc_size
# if __GNUC_PREREQ (4, 3)
# define __ul_alloc_size(s) __attribute__((alloc_size(s)))
# else
# define __ul_alloc_size(s)
# endif
#endif
#ifndef __ul_calloc_size
# if __GNUC_PREREQ (4, 3)
# define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s)))
# else
# define __ul_calloc_size(n, s)
# endif
#endif
/*
* Misc
*/
#ifndef PATH_MAX
# define PATH_MAX 4096
#endif
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
/*
* Program name.
*/
#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
# ifdef HAVE___PROGNAME
extern char *__progname;
# define program_invocation_short_name __progname
# else
# ifdef HAVE_GETEXECNAME
# define program_invocation_short_name \
prog_inv_sh_nm_from_file(getexecname(), 0)
# else
# define program_invocation_short_name \
prog_inv_sh_nm_from_file(__FILE__, 1)
# endif
static char prog_inv_sh_nm_buf[256];
static inline char *prog_inv_sh_nm_from_file(char *f, char stripext)
{
char *t;
if ((t = strrchr(f, '/')) != NULL)
t++;
else
t = f;
strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1);
prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0';
if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL)
*t = '\0';
return prog_inv_sh_nm_buf;
}
# endif
#endif
/*
* Error printing.
*/
#ifndef HAVE_ERROR_H
/* Emulate the error() function from glibc */
__attribute__((__format__(__printf__, 3, 4)))
static void error(int status, int errnum, const char *format, ...)
{
va_list argp;
fprintf(stderr, "%s: ", program_invocation_short_name);
va_start(argp, format);
vfprintf(stderr, format, argp);
va_end(argp);
if (errnum != 0)
fprintf(stderr, ": %s", strerror(errnum));
fprintf(stderr, "\n");
if (status != 0)
exit(status);
}
/* Emulate the error_at_line() function from glibc */
__attribute__((__format__(__printf__, 5, 6)))
static void error_at_line(int status, int errnum, const char *filename,
unsigned int linenum, const char *format, ...)
{
va_list argp;
fprintf(stderr, "%s:%s:%u: ", program_invocation_short_name,
filename, linenum);
va_start(argp, format);
vfprintf(stderr, format, argp);
va_end(argp);
if (errnum != 0)
fprintf(stderr, ": error code %d", errnum);
fprintf(stderr, "\n");
if (status != 0)
exit(status);
}
#endif
#define xwarn(...) error(0, errno, __VA_ARGS__)
#define xwarnx(...) error(0, 0, __VA_ARGS__)
#define xerr(STATUS, ...) error(STATUS, errno, __VA_ARGS__)
#define xerrx(STATUS, ...) error(STATUS, 0, __VA_ARGS__)
/*
* Constant strings for usage() functions.
*/
#define USAGE_HEADER _("\nUsage:\n")
#define USAGE_OPTIONS _("\nOptions:\n")
#define USAGE_SEPARATOR _("\n")
#define USAGE_HELP _(" -h, --help display this help and exit\n")
#define USAGE_VERSION _(" -V, --version output version information and exit\n")
#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
#define PROCPS_NG_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
#endif /* PROCPS_NG_C_H */

45
local/fileutils.c Normal file
View File

@@ -0,0 +1,45 @@
#include <errno.h>
#ifdef HAVE_ERROR_H
# include <error.h>
#endif
#ifdef HAVE_STDIO_EXT_H
# include <stdio_ext.h>
#else
/* FIXME: use a more portable definition of __fpending() (from gnulib?) */
# include <stdio.h>
# define __fpending(fp) ((fp)->_p - (fp)->_bf._base)
#endif
#include <stdlib.h>
#include <unistd.h>
#include "nls.h"
#include "fileutils.h"
#ifndef HAVE_ERROR_H
# include "c.h" /* for error() emulation */
#endif
int close_stream(FILE * stream)
{
const int some_pending = (__fpending(stream) != 0);
const int prev_fail = (ferror(stream) != 0);
const int fclose_fail = (fclose(stream) != 0);
if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) {
if (!fclose_fail && errno != EPIPE)
errno = 0;
return EOF;
}
return 0;
}
/* Use atexit(); */
void close_stdout(void)
{
if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
char const *write_error = _("write error");
error(0, errno, "%s", write_error);
_exit(EXIT_FAILURE);
}
if (close_stream(stderr) != 0)
_exit(EXIT_FAILURE);
}

7
local/fileutils.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef PROCPS_NG_FILEUTILS
#define PROCPS_NG_FILEUTILS
int close_stream(FILE * stream);
void close_stdout(void);
#endif

114
local/nls.h Normal file
View File

@@ -0,0 +1,114 @@
/*
* This header was copied from util-linux at fall 2011.
*/
#ifndef PROCPS_NG_NLS_H
#define PROCPS_NG_NLS_H
/* programs issuing textdomain() need PACKAGE string */
#include "config.h"
/* programs issuing bindtextdomain() also need LOCALEDIR string */
#ifndef LOCALEDIR
#define LOCALEDIR "/usr/share/locale"
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#else
# undef setlocale
# define setlocale(Category, Locale) /* empty */
#endif
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
# define P_(Singular, Plural, n) ngettext (Singular, Plural, n)
#else
# undef bindtextdomain
# define bindtextdomain(Domain, Directory) /* empty */
# undef textdomain
# define textdomain(Domain) /* empty */
# define _(Text) (Text)
# define N_(Text) (Text)
# define P_(Singular, Plural, n) ((n) == 1 ? (Singular) : (Plural))
#endif /* ENABLE_NLS */
#ifdef HAVE_LANGINFO_H
# include <langinfo.h>
#else
typedef int nl_item;
extern char *langinfo_fallback(nl_item item);
# define nl_langinfo langinfo_fallback
enum {
CODESET = 1,
RADIXCHAR,
THOUSEP,
D_T_FMT,
D_FMT,
T_FMT,
T_FMT_AMPM,
AM_STR,
PM_STR,
DAY_1,
DAY_2,
DAY_3,
DAY_4,
DAY_5,
DAY_6,
DAY_7,
ABDAY_1,
ABDAY_2,
ABDAY_3,
ABDAY_4,
ABDAY_5,
ABDAY_6,
ABDAY_7,
MON_1,
MON_2,
MON_3,
MON_4,
MON_5,
MON_6,
MON_7,
MON_8,
MON_9,
MON_10,
MON_11,
MON_12,
ABMON_1,
ABMON_2,
ABMON_3,
ABMON_4,
ABMON_5,
ABMON_6,
ABMON_7,
ABMON_8,
ABMON_9,
ABMON_10,
ABMON_11,
ABMON_12,
ERA_D_FMT,
ERA_D_T_FMT,
ERA_T_FMT,
ALT_DIGITS,
CRNCYSTR,
YESEXPR,
NOEXPR
};
#endif /* !HAVE_LANGINFO_H */
#endif /* PROCPS_NG_NLS_H */

292
local/procio.c Normal file
View File

@@ -0,0 +1,292 @@
/*
* procio.c -- Replace stdio for read and write on files below
* proc to be able to read and write large buffers as well.
*
* Copyright (C) 2017 Werner Fink
*
* 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 _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
typedef struct pcookie {
char *buf;
size_t count;
size_t length;
off_t offset;
int fd;
int delim;
int final:1;
} pcookie_t;
static ssize_t proc_read(void *, char *, size_t);
static ssize_t proc_write(void *, const char *, size_t);
static int proc_close(void *);
__extension__
static cookie_io_functions_t procio = {
.read = proc_read,
.write = proc_write,
.seek = NULL,
.close = proc_close,
};
FILE *fprocopen(const char *path, const char *mode)
{
pcookie_t *cookie = NULL;
FILE *handle = NULL;
mode_t flags = 0;
size_t len = 0;
int c, delim;
if (!mode || !(len = strlen(mode))) {
errno = EINVAL;
goto out;
}
/* No append mode possible */
switch (mode[0]) {
case 'r':
flags |= O_RDONLY;
break;
case 'w':
flags |= O_WRONLY|O_TRUNC;
break;
default:
errno = EINVAL;
goto out;
}
delim = ','; /* default delimeter is the comma */
for (c = 1; c < len; c++) {
switch (mode[c]) {
case '\0':
break;
case '+':
errno = EINVAL;
goto out;
case 'e':
flags |= O_CLOEXEC;
continue;
case 'b':
case 'm':
case 'x':
/* ignore this */
continue;
default:
if (mode[c] == ' ' || (mode[c] >= ',' && mode[c] <= '.') || mode[c] == ':')
delim = mode[c];
else {
errno = EINVAL;
goto out;
}
break;
}
break;
}
cookie = (pcookie_t *)malloc(sizeof(pcookie_t));
if (!cookie)
goto out;
cookie->count = BUFSIZ;
cookie->buf = (char *)malloc(cookie->count);
if (!cookie->buf) {
int errsv = errno;
free(cookie);
errno = errsv;
goto out;
}
cookie->final = 0;
cookie->offset = 0;
cookie->length = 0;
cookie->delim = delim;
cookie->fd = openat(AT_FDCWD, path, flags);
if (cookie->fd < 0) {
int errsv = errno;
free(cookie->buf);
free(cookie);
errno = errsv;
goto out;
}
handle = fopencookie(cookie, mode, procio);
if (!handle) {
int errsv = errno;
close(cookie->fd);
free(cookie->buf);
free(cookie);
errno = errsv;
goto out;
}
out:
return handle;
}
static
ssize_t proc_read(void *c, char *buf, size_t count)
{
pcookie_t *cookie = c;
ssize_t len = -1;
void *ptr;
if (cookie->count < count) {
ptr = realloc(cookie->buf, count);
if (!ptr)
goto out;
cookie->buf = ptr;
cookie->count = count;
}
while (!cookie->final) {
len = read(cookie->fd, cookie->buf, cookie->count);
if (len <= 0) {
if (len == 0) {
/* EOF */
cookie->final = 1;
cookie->buf[cookie->length] = '\0';
break;
}
goto out; /* error or done */
}
cookie->length = len;
if (cookie->length < cookie->count)
continue;
/* Likly to small buffer here */
lseek(cookie->fd, 0, SEEK_SET); /* reset for a retry */
ptr = realloc(cookie->buf, cookie->count += BUFSIZ);
if (!ptr)
goto out;
cookie->buf = ptr;
}
len = count;
if (cookie->length - cookie->offset < len)
len = cookie->length - cookie->offset;
if (len < 0)
len = 0;
if (len) {
(void)memcpy(buf, cookie->buf+cookie->offset, len);
cookie->offset += len;
} else
len = EOF;
out:
return len;
}
#define LINELEN 4096
static
ssize_t proc_write(void *c, const char *buf, size_t count)
{
pcookie_t *cookie = c;
ssize_t len = -1;
void *ptr;
if (!count) {
len = 0;
goto out;
}
/* NL is the final input */
cookie->final = memrchr(buf, '\n', count) ? 1 : 0;
while (cookie->count < cookie->offset + count) {
ptr = realloc(cookie->buf, cookie->count += count);
if (!ptr)
goto out;
cookie->buf = ptr;
}
len = count;
(void)memcpy(cookie->buf+cookie->offset, buf, count);
cookie->offset += count;
if (cookie->final) {
len = write(cookie->fd, cookie->buf, cookie->offset);
if (len < 0 && errno == EINVAL) {
size_t offset;
off_t amount;
char *token;
/*
* Oops buffer might be to large, split buffer into
* pieces at delimeter if provided
*/
if (!cookie->delim)
goto out; /* Hey dude?! */
offset = 0;
do {
token = NULL;
if (cookie->offset > LINELEN)
token = (char*)memrchr(cookie->buf+offset, cookie->delim, LINELEN);
else
token = (char*)memrchr(cookie->buf+offset, '\n', cookie->offset);
if (token)
*token = '\n';
else {
errno = EINVAL;
len = -1;
goto out; /* Wrong/Missing delimeter? */
}
if (offset > 0)
lseek(cookie->fd, 1, SEEK_CUR);
amount = token-(cookie->buf+offset)+1;
ptr = cookie->buf+offset;
len = write(cookie->fd, ptr, amount);
if (len < 1 || len >= cookie->offset)
break;
offset += len;
cookie->offset -= len;
} while (cookie->offset > 0);
}
if (len > 0)
len = count;
}
out:
return len;
}
static
int proc_close(void *c)
{
pcookie_t *cookie = c;
close(cookie->fd);
free(cookie->buf);
free(cookie);
return 0;
}

6
local/procio.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef PROCPS_PROC_PROCIO_H
#define PROCPS_PROC_PROCIO_H
FILE *fprocopen(const char *path, const char *mode);
#endif

9
local/rpmatch.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef PROCPS_NG_RPMATCH_H
#define PROCPS_NG_RPMATCH_H
#ifndef HAVE_RPMATCH
#define rpmatch(r) \
(*r == 'y' || *r == 'Y' ? 1 : *r == 'n' || *r == 'N' ? 0 : -1)
#endif
#endif /* PROCPS_NG_RPMATCH_H */

316
local/signals.c Normal file
View File

@@ -0,0 +1,316 @@
/*
* signals.c - signal name, and number, conversions
* 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 <ctype.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "signals.h"
#include "c.h"
/* Linux signals:
*
* SIGSYS is required by Unix98.
* SIGEMT is part of SysV, BSD, and ancient UNIX tradition.
*
* They are provided by these Linux ports: alpha, mips, sparc, and sparc64.
* You get SIGSTKFLT and SIGUNUSED instead on i386, m68k, ppc, and arm.
* (this is a Linux & libc bug -- both must be fixed)
*
* Total garbage: SIGIO SIGINFO SIGIOT SIGCLD
* (popular ones are handled as aliases)
* SIGLOST
* (except on the Hurd; reused to mean a server died)
* Nearly garbage: SIGSTKFLT SIGUNUSED (nothing else to fill slots)
*/
/* Linux 2.3.29 replaces SIGUNUSED with the standard SIGSYS signal */
#ifndef SIGSYS
# warning Standards require that <signal.h> define SIGSYS
# define SIGSYS SIGUNUSED
#endif
/* If we see both, it is likely SIGSTKFLT (junk) was replaced. */
#ifdef SIGEMT
# undef SIGSTKFLT
#endif
#ifndef SIGRTMIN
# warning Standards require that <signal.h> define SIGRTMIN; assuming 32
# define SIGRTMIN 32
#endif
/* It seems the SPARC libc does not know the kernel supports SIGPWR. */
#if defined(__linux__) && !defined(SIGPWR)
# warning Your header files lack SIGPWR. (assuming it is number 29)
# define SIGPWR 29
#endif
typedef struct mapstruct {
const char *name;
int num;
} mapstruct;
static const mapstruct sigtable[] = {
{"ABRT", SIGABRT}, /* IOT */
{"ALRM", SIGALRM},
{"BUS", SIGBUS},
{"CHLD", SIGCHLD}, /* CLD */
{"CONT", SIGCONT},
#ifdef SIGEMT
{"EMT", SIGEMT},
#endif
{"FPE", SIGFPE},
{"HUP", SIGHUP},
{"ILL", SIGILL},
{"INT", SIGINT},
{"KILL", SIGKILL},
#if defined(__GNU__)
{"LOST", SIGLOST}, /* Hurd-specific */
#endif
{"PIPE", SIGPIPE},
{"POLL", SIGPOLL}, /* IO */
{"PROF", SIGPROF},
#ifdef SIGPWR
{"PWR", SIGPWR},
#endif
{"QUIT", SIGQUIT},
{"SEGV", SIGSEGV},
#ifdef SIGSTKFLT
{"STKFLT", SIGSTKFLT},
#endif
{"STOP", SIGSTOP},
{"SYS", SIGSYS}, /* UNUSED */
{"TERM", SIGTERM},
{"TRAP", SIGTRAP},
{"TSTP", SIGTSTP},
{"TTIN", SIGTTIN},
{"TTOU", SIGTTOU},
{"URG", SIGURG},
{"USR1", SIGUSR1},
{"USR2", SIGUSR2},
{"VTALRM", SIGVTALRM},
{"WINCH", SIGWINCH},
{"XCPU", SIGXCPU},
{"XFSZ", SIGXFSZ}
};
#define number_of_signals (sizeof(sigtable)/sizeof(mapstruct))
#define XJOIN(a, b) JOIN(a, b)
#define JOIN(a, b) a##b
#define STATIC_ASSERT(x) typedef int XJOIN(static_assert_on_line_,__LINE__)[(x) ? 1 : -1]
/* sanity check */
#if defined(__linux__)
STATIC_ASSERT(number_of_signals == 31);
#elif defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
STATIC_ASSERT(number_of_signals == 30);
#elif defined(__GNU__)
STATIC_ASSERT(number_of_signals == 31);
#elif defined(__CYGWIN__)
STATIC_ASSERT(number_of_signals == 31);
#else
# warning Unknown operating system; assuming number_of_signals is correct
#endif
static int compare_signal_names(const void *a, const void *b){
return strcasecmp( ((const mapstruct*)a)->name, ((const mapstruct*)b)->name );
}
const char *get_sigtable_name(int row)
{
if (row < 0 || row >= number_of_signals)
return NULL;
return sigtable[row].name;
}
const int get_sigtable_num(int row)
{
if (row < 0 || row >= number_of_signals)
return -1;
return sigtable[row].num;
}
/* return -1 on failure */
int signal_name_to_number(const char *restrict name){
long val;
int offset;
/* clean up name */
if(!strncasecmp(name,"SIG",3))
name += 3;
if(!strcasecmp(name,"CLD"))
return SIGCHLD;
if(!strcasecmp(name,"IO"))
return SIGPOLL;
if(!strcasecmp(name,"IOT"))
return SIGABRT;
/* search the table */
{
const mapstruct ms = {name,0};
const mapstruct *restrict const ptr = bsearch(
&ms,
sigtable,
number_of_signals,
sizeof(mapstruct),
compare_signal_names);
if(ptr)
return ptr->num;
}
if(!strcasecmp(name,"RTMIN"))
return SIGRTMIN;
if(!strcasecmp(name,"EXIT"))
return 0;
if(!strcasecmp(name,"NULL"))
return 0;
offset = 0;
if(!strncasecmp(name,"RTMIN+",6)) {
name += 6;
offset = SIGRTMIN;
}
/* not found, so try as a number */
{
char *endp;
val = strtol(name,&endp,10);
if(*endp || endp==name)
return -1; /* not valid */
}
if(val<0 || val+SIGRTMIN>127)
return -1; /* not valid */
return val+offset;
}
const char *signal_number_to_name(int signo)
{
static char buf[32];
int n = number_of_signals;
signo &= 0x7f; /* need to process exit values too */
while (n--) {
if(sigtable[n].num==signo)
return sigtable[n].name;
}
if (signo == SIGRTMIN)
return "RTMIN";
if (signo)
sprintf(buf, "RTMIN+%d", signo-SIGRTMIN);
else
strcpy(buf,"0"); /* AIX has NULL; Solaris has EXIT */
return buf;
}
int skill_sig_option(int *argc, char **argv)
{
int i;
int signo = -1;
for (i = 1; i < *argc; i++) {
if (argv[i][0] == '-') {
signo = signal_name_to_number(argv[i] + 1);
if (-1 < signo) {
memmove(argv + i, argv + i + 1,
sizeof(char *) * (*argc - i));
(*argc)--;
return signo;
}
}
}
return signo;
}
/* strtosig is similar to print_given_signals() with exception, that
* this function takes a string, and converts it to a signal name or
* a number string depending on which way a round conversion is
* queried. Non-existing signals return NULL. Notice that the
* returned string should be freed after use.
*/
char *strtosig(const char *restrict s)
{
char *converted = NULL, *copy, *p, *endp;
int i, numsignal = 0;
copy = strdup(s);
if (!copy)
xerrx(EXIT_FAILURE, "cannot duplicate string");
for (p = copy; *p != '\0'; p++)
*p = toupper(*p);
p = copy;
if (p[0] == 'S' && p[1] == 'I' && p[2] == 'G')
p += 3;
if (isdigit(*p)){
numsignal = strtol(s,&endp,10);
if(*endp || endp==s){
free(p);
return NULL; /* not valid */
}
}
if (numsignal){
for (i = 0; i < number_of_signals; i++){
if (numsignal == get_sigtable_num(i)){
converted = strdup(get_sigtable_name(i));
break;
}
}
} else {
for (i = 0; i < number_of_signals; i++){
if (strcmp(p, get_sigtable_name(i)) == 0){
converted = malloc(12);
if (converted)
snprintf(converted, 12, "%d", sigtable[i].num);
break;
}
}
}
free(copy);
return converted;
}
void unix_print_signals(void)
{
int pos = 0;
int i = 0;
while(++i <= number_of_signals){
if(i-1) printf("%c", (pos>73)?(pos=0,'\n'):(pos++,' ') );
pos += printf("%s", signal_number_to_name(i));
}
printf("\n");
}
void pretty_print_signals(void)
{
int i = 0;
while(++i <= number_of_signals){
int n;
n = printf("%2d %s", i, signal_number_to_name(i));
if(n>0 && i%7)
printf("%s", " \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);
else
printf("\n");
}
if((i-1)%7) printf("\n");
}

33
local/signals.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef PROC_SIG_H
#define PROC_SIG_H
/*
* Copyright 1998-2003 by Albert Cahalan; all rights resered.
* This file may be used subject to the terms and conditions of the
* GNU Library General Public License Version 2, or any later version
* at your option, as published by the Free Software Foundation.
* This program 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.
*/
extern const int number_of_signals;
extern const char *get_sigtable_name(int row);
extern const int get_sigtable_num(int row);
/* return -1 on failure */
extern int signal_name_to_number(const char *__restrict name);
extern const char *signal_number_to_name(int signo);
extern int skill_sig_option(int *argc, char **argv);
extern char *strtosig(const char *restrict s);
extern void pretty_print_signals(void);
extern void unix_print_signals(void);
#endif

123
local/strutils.c Normal file
View File

@@ -0,0 +1,123 @@
/*
* strutils.c - various string routines shared by commands
* This file was copied from util-linux at fall 2011.
*
* Copyright (C) 2010 Karel Zak <kzak@redhat.com>
* Copyright (C) 2010 Davidlohr Bueso <dave@gnu.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdlib.h>
#include <ctype.h>
#include "c.h"
#include "strutils.h"
/*
* same as strtol(3) but exit on failure instead of returning crap
*/
long strtol_or_err(const char *str, const char *errmesg)
{
long num;
char *end = NULL;
if (str != NULL && *str != '\0') {
errno = 0;
num = strtol(str, &end, 10);
if (errno == 0 && str != end && end != NULL && *end == '\0')
return num;
}
error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
return 0;
}
/*
* same as strtod(3) but exit on failure instead of returning crap
*/
double strtod_or_err(const char *str, const char *errmesg)
{
double num;
char *end = NULL;
if (str != NULL && *str != '\0') {
errno = 0;
num = strtod(str, &end);
if (errno == 0 && str != end && end != NULL && *end == '\0')
return num;
}
error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
return 0;
}
/*
* Covert a string into a double in a non-locale aware way.
* This means the decimal point can be either . or ,
* Also means you cannot use the other for thousands separator
*
* Exits on failure like its other _or_err cousins
*/
double strtod_nol_or_err(char *str, const char *errmesg)
{
double num;
const char *cp, *radix;
double mult;
int negative = 0;
if (str != NULL && *str != '\0') {
num = 0.0;
cp = str;
/* strip leading spaces */
while (isspace(*cp))
cp++;
/* get sign */
if (*cp == '-') {
negative = 1;
cp++;
} else if (*cp == '+')
cp++;
/* find radix */
radix = cp;
mult=0.1;
while(isdigit(*radix)) {
radix++;
mult *= 10;
}
while(isdigit(*cp)) {
num += (*cp - '0') * mult;
mult /= 10;
cp++;
}
/* got the integers */
if (*cp == '\0')
return (negative?-num:num);
if (*cp != '.' && *cp != ',')
error(EXIT_FAILURE, EINVAL, "%s: '%s'", errmesg, str);
cp++;
mult = 0.1;
while(isdigit(*cp)) {
num += (*cp - '0') * mult;
mult /= 10;
cp++;
}
if (*cp == '\0')
return (negative?-num:num);
}
error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
return 0;
}

12
local/strutils.h Normal file
View File

@@ -0,0 +1,12 @@
/*
* This header was copied from util-linux at fall 2011.
*/
#ifndef PROCPS_NG_STRUTILS
#define PROCPS_NG_STRUTILS
extern long strtol_or_err(const char *str, const char *errmesg);
extern double strtod_or_err(const char *str, const char *errmesg);
double strtod_nol_or_err(char *str, const char *errmesg);
#endif

158
local/strverscmp.c Normal file
View File

@@ -0,0 +1,158 @@
/* Compare strings while treating digits characters numerically.
Copyright (C) 1997, 2002, 2005 Free Software Foundation, Inc.
This file is part of the libiberty library.
Contributed by Jean-Fran<61>ois Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
Libiberty 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.
Libiberty 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 the GNU C Library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA. */
/* #include "libiberty.h" */
/* #include "safe-ctype.h" */
#include <ctype.h>
/*
@deftypefun int strverscmp (const char *@var{s1}, const char *@var{s2})
The @code{strverscmp} function compares the string @var{s1} against
@var{s2}, considering them as holding indices/version numbers. Return
value follows the same conventions as found in the @code{strverscmp}
function. In fact, if @var{s1} and @var{s2} contain no digits,
@code{strverscmp} behaves like @code{strcmp}.
Basically, we compare strings normally (character by character), until
we find a digit in each string - then we enter a special comparison
mode, where each sequence of digits is taken as a whole. If we reach the
end of these two parts without noticing a difference, we return to the
standard comparison mode. There are two types of numeric parts:
"integral" and "fractional" (those begin with a '0'). The types
of the numeric parts affect the way we sort them:
@itemize @bullet
@item
integral/integral: we compare values as you would expect.
@item
fractional/integral: the fractional part is less than the integral one.
Again, no surprise.
@item
fractional/fractional: the things become a bit more complex.
If the common prefix contains only leading zeroes, the longest part is less
than the other one; else the comparison behaves normally.
@end itemize
@smallexample
strverscmp ("no digit", "no digit")
@result{} 0 // @r{same behavior as strcmp.}
strverscmp ("item#99", "item#100")
@result{} <0 // @r{same prefix, but 99 < 100.}
strverscmp ("alpha1", "alpha001")
@result{} >0 // @r{fractional part inferior to integral one.}
strverscmp ("part1_f012", "part1_f01")
@result{} >0 // @r{two fractional parts.}
strverscmp ("foo.009", "foo.0")
@result{} <0 // @r{idem, but with leading zeroes only.}
@end smallexample
This function is especially useful when dealing with filename sorting,
because filenames frequently hold indices/version numbers.
@end deftypefun
*/
/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
fractional parts, S_Z: idem but with leading Zeroes only */
#define S_N 0x0
#define S_I 0x4
#define S_F 0x8
#define S_Z 0xC
/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
#define CMP 2
#define LEN 3
/* Compare S1 and S2 as strings holding indices/version numbers,
returning less than, equal to or greater than zero if S1 is less than,
equal to or greater than S2 (for more info, see the Glibc texinfo doc). */
int
strverscmp (const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
unsigned char c1, c2;
int state;
int diff;
/* Symbol(s) 0 [1-9] others (padding)
Transition (10) 0 (01) d (00) x (11) - */
static const unsigned int next_state[] =
{
/* state x d 0 - */
/* S_N */ S_N, S_I, S_Z, S_N,
/* S_I */ S_N, S_I, S_I, S_I,
/* S_F */ S_N, S_F, S_F, S_F,
/* S_Z */ S_N, S_F, S_Z, S_Z
};
static const int result_type[] =
{
/* state x/x x/d x/0 x/- d/x d/d d/0 d/-
0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
/* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
/* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP,
+1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
/* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
/* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP,
-1, CMP, CMP, CMP
};
if (p1 == p2)
return 0;
c1 = *p1++;
c2 = *p2++;
/* Hint: '0' is a digit too. */
state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
while ((diff = c1 - c2) == 0 && c1 != '\0')
{
state = next_state[state];
c1 = *p1++;
c2 = *p2++;
state |= (c1 == '0') + (isdigit (c1) != 0);
}
state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))];
switch (state)
{
case CMP:
return diff;
case LEN:
while (isdigit (*p1++))
if (!isdigit (*p2++))
return 1;
return isdigit (*p2) ? -1 : diff;
default:
return state;
}
}

29
local/tests.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef PROCPS_NG_TESTS_H
#define PROCPS_NG_TESTS_H
#include <stdio.h>
typedef int (*TestFunction)(void *data);
char *testname;
static inline int run_tests(TestFunction *list, void *data)
{
int i;
TestFunction current;
for (i=0; list[i] != NULL; i++) {
testname = NULL;
current = list[i];
if (!current(data)) {
fprintf(stderr, "FAIL: %s\n", testname);
return EXIT_FAILURE;
} else {
fprintf(stderr, "PASS: %s\n", testname);
}
}
return EXIT_SUCCESS;
}
#endif

60
local/xalloc.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* This header was copied from util-linux at fall 2011.
*/
/*
* General memory allocation wrappers for malloc, realloc, calloc
* and strdup.
*/
#ifndef PROCPS_NG_XALLOC_H
#define PROCPS_NG_XALLOC_H
#include <stdlib.h>
#include <string.h>
#include "c.h"
#ifndef XALLOC_EXIT_CODE
# define XALLOC_EXIT_CODE EXIT_FAILURE
#endif
static inline __ul_alloc_size(1)
void *xmalloc(const size_t size)
{
void *ret = malloc(size);
if (!ret && size)
xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
return ret;
}
static inline __ul_alloc_size(2)
void *xrealloc(void *ptr, const size_t size)
{
void *ret = realloc(ptr, size);
if (!ret && size)
xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
return ret;
}
static inline __ul_calloc_size(1, 2)
void *xcalloc(const size_t nelems, const size_t size)
{
void *ret = calloc(nelems, size);
if (!ret && size && nelems)
xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
return ret;
}
static inline char *xstrdup(const char *str)
{
char *ret;
if (!str)
return NULL;
ret = strdup(str);
if (!ret)
xerrx(XALLOC_EXIT_CODE, "cannot duplicate string");
return ret;
}
#endif /* PROCPS_NG_XALLOC_H */