library: make that 'escape_str' private to our library
In that commit referenced below, a promise was made to
revisit an 'escape_str' function in efforts to make it
private to the library. The problem was it's needed by
both ps plus the library which is why it was exported.
So, in an effort to remove it from libprocps.sym, this
patch duplicates all the required code in ps/output.c.
Now, each version can be made private to their caller.
[ along the way we'll use this opportunity to remove ]
[ the 'restrict' qualifiers from function parameters ]
[ while swatting a compiler warning referenced below ]
Reference(s):
. April 2016, most escape functions made private
commit d916d5db86
proc/escape.c: In function `escape_command':
proc/escape.c:182:23: warning: initialization of `const char **' from incompatible pointer type `char **' [-Wincompatible-pointer-types]
182 | const char **lc = (char**)pp->cmdline;
| ^
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
117
ps/output.c
117
ps/output.c
@@ -49,8 +49,10 @@
|
||||
#if ENABLE_LIBSELINUX
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <langinfo.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
@@ -58,13 +60,14 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#include "../include/c.h"
|
||||
|
||||
#include "common.h"
|
||||
@@ -79,7 +82,6 @@ static unsigned max_rightward = OUTBUF_SIZE-1; /* space for RIGHT stuff */
|
||||
static unsigned max_leftward = OUTBUF_SIZE-1; /* space for LEFT stuff */
|
||||
|
||||
|
||||
|
||||
static int wide_signals; /* true if we have room */
|
||||
|
||||
static time_t seconds_since_1970;
|
||||
@@ -135,6 +137,117 @@ static int escaped_copy(char *restrict dst, const char *restrict src, int bufsiz
|
||||
return n;
|
||||
}
|
||||
|
||||
// duplicated from proc/escape.c so both can be made private
|
||||
static int escape_str_utf8 (char *dst, const char *src, int bufsize, int *maxcells) {
|
||||
int my_cells = 0;
|
||||
int my_bytes = 0;
|
||||
mbstate_t s;
|
||||
|
||||
SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
|
||||
|
||||
memset(&s, 0, sizeof (s));
|
||||
|
||||
for(;;) {
|
||||
wchar_t wc;
|
||||
int len = 0;
|
||||
|
||||
if(my_cells >= *maxcells || my_bytes+1 >= bufsize)
|
||||
break;
|
||||
|
||||
if (!(len = mbrtowc (&wc, src, MB_CUR_MAX, &s)))
|
||||
/* 'str' contains \0 */
|
||||
break;
|
||||
|
||||
if (len < 0) {
|
||||
/* invalid multibyte sequence -- zeroize state */
|
||||
memset (&s, 0, sizeof (s));
|
||||
*(dst++) = '?';
|
||||
src++;
|
||||
my_cells++;
|
||||
my_bytes++;
|
||||
|
||||
} else if (len==1) {
|
||||
/* non-multibyte */
|
||||
*(dst++) = isprint(*src) ? *src : '?';
|
||||
src++;
|
||||
my_cells++;
|
||||
my_bytes++;
|
||||
|
||||
} else if (!iswprint(wc)) {
|
||||
/* multibyte - no printable */
|
||||
*(dst++) = '?';
|
||||
src+=len;
|
||||
my_cells++;
|
||||
my_bytes++;
|
||||
|
||||
} else {
|
||||
/* multibyte - maybe, kinda "printable" */
|
||||
int wlen = wcwidth(wc);
|
||||
// Got space?
|
||||
if (wlen > *maxcells-my_cells || len >= bufsize-(my_bytes+1)) break;
|
||||
// safe multibyte
|
||||
memcpy(dst, src, len);
|
||||
dst += len;
|
||||
src += len;
|
||||
my_bytes += len;
|
||||
if (wlen > 0) my_cells += wlen;
|
||||
}
|
||||
//fprintf(stdout, "cells: %d\n", my_cells);
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
// fprintf(stderr, "maxcells: %d, my_cells; %d\n", *maxcells, my_cells);
|
||||
|
||||
*maxcells -= my_cells;
|
||||
return my_bytes; // bytes of text, excluding the NUL
|
||||
}
|
||||
|
||||
// duplicated from proc/escape.c so both can be made private
|
||||
static int escape_str (char *dst, const char *src, int bufsize, int *maxcells) {
|
||||
unsigned char c;
|
||||
int my_cells = 0;
|
||||
int my_bytes = 0;
|
||||
const char codes[] =
|
||||
"Z..............................."
|
||||
"||||||||||||||||||||||||||||||||"
|
||||
"||||||||||||||||||||||||||||||||"
|
||||
"|||||||||||||||||||||||||||||||."
|
||||
"????????????????????????????????"
|
||||
"????????????????????????????????"
|
||||
"????????????????????????????????"
|
||||
"????????????????????????????????";
|
||||
static int utf_init=0;
|
||||
|
||||
if(utf_init==0){
|
||||
/* first call -- check if UTF stuff is usable */
|
||||
char *enc = nl_langinfo(CODESET);
|
||||
utf_init = enc && strcasecmp(enc, "UTF-8")==0 ? 1 : -1;
|
||||
}
|
||||
if (utf_init==1 && MB_CUR_MAX>1) {
|
||||
/* UTF8 locales */
|
||||
return escape_str_utf8(dst, src, bufsize, maxcells);
|
||||
}
|
||||
|
||||
SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
|
||||
|
||||
if(bufsize > *maxcells+1) bufsize=*maxcells+1; // FIXME: assumes 8-bit locale
|
||||
|
||||
for(;;){
|
||||
if(my_cells >= *maxcells || my_bytes+1 >= bufsize)
|
||||
break;
|
||||
c = (unsigned char) *(src++);
|
||||
if(!c) break;
|
||||
if(codes[c]!='|') c=codes[c];
|
||||
my_cells++;
|
||||
my_bytes++;
|
||||
*(dst++) = c;
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
*maxcells -= my_cells;
|
||||
return my_bytes; // bytes of text, excluding the NUL
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/************ Lots of format functions, starting with the NOP **************/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user