summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--proc/escape.c29
-rw-r--r--proc/escape.h6
-rw-r--r--proc/libprocps.sym1
-rw-r--r--ps/common.h4
-rw-r--r--ps/output.c117
6 files changed, 129 insertions, 29 deletions
diff --git a/Makefile.am b/Makefile.am
index 3c21658..e49dc10 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -276,7 +276,6 @@ proc_libprocps_la_includedir = $(includedir)/procps/
proc_libprocps_la_include_HEADERS = \
proc/devname.h \
proc/diskstats.h \
- proc/escape.h \
proc/meminfo.h \
proc/namespace.h \
proc/numa.h \
diff --git a/proc/escape.c b/proc/escape.c
index 9546ed7..8d35840 100644
--- a/proc/escape.c
+++ b/proc/escape.c
@@ -17,21 +17,19 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <ctype.h>
+#include <langinfo.h>
#include <limits.h>
#include <stdio.h>
-#include <sys/types.h>
+#include <stdlib.h> /* MB_CUR_MAX */
#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <sys/types.h>
#include "escape.h"
#include "readproc.h"
-#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
-# include <wchar.h>
-# include <wctype.h>
-# include <stdlib.h> /* MB_CUR_MAX */
-# include <ctype.h>
-# include <langinfo.h>
-#endif
#define SECURE_ESCAPE_ARGS(dst, bytes, cells) do { \
if ((bytes) <= 0) return 0; \
@@ -42,8 +40,7 @@
} while (0)
-#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
-static int escape_str_utf8(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
+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;
@@ -107,10 +104,9 @@ static int escape_str_utf8(char *restrict dst, const char *restrict src, int buf
return my_bytes; // bytes of text, excluding the NUL
}
-#endif /* __GNU_LIBRARY__ */
/* sanitize a string via one-way mangle */
-int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
+int escape_str (char *dst, const char *src, int bufsize, int *maxcells) {
unsigned char c;
int my_cells = 0;
int my_bytes = 0;
@@ -124,7 +120,6 @@ int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *m
"????????????????????????????????"
"????????????????????????????????";
-#if (__GNU_LIBRARY__ >= 6) && (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_WCHAR__))
static int utf_init=0;
if(utf_init==0){
@@ -136,7 +131,6 @@ int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *m
/* UTF8 locales */
return escape_str_utf8(dst, src, bufsize, maxcells);
}
-#endif
SECURE_ESCAPE_ARGS(dst, bufsize, *maxcells);
@@ -163,7 +157,7 @@ int escape_str(char *restrict dst, const char *restrict src, int bufsize, int *m
// escape an argv or environment string array
//
// bytes arg means sizeof(buf)
-static int escape_strlist(char *restrict dst, char *restrict const *restrict src, size_t bytes, int *cells){
+static int escape_strlist (char *dst, const char **src, size_t bytes, int *cells) {
size_t i = 0;
for(;;){
@@ -180,12 +174,12 @@ static int escape_strlist(char *restrict dst, char *restrict const *restrict src
///////////////////////////////////////////////////
-int escape_command(char *restrict const outbuf, const proc_t *restrict const pp, int bytes, int *cells, unsigned flags){
+int escape_command (char *const outbuf, const proc_t *pp, int bytes, int *cells, unsigned flags) {
int overhead = 0;
int end = 0;
if(flags & ESC_ARGS){
- char **lc = (char**)pp->cmdline;
+ const char **lc = (const char**)pp->cmdline;
if(lc && *lc) return escape_strlist(outbuf, lc, bytes, cells);
}
if(flags & ESC_BRACKETS){
@@ -217,4 +211,3 @@ int escape_command(char *restrict const outbuf, const proc_t *restrict const pp,
outbuf[end] = '\0';
return end; // bytes, not including the NUL
}
-
diff --git a/proc/escape.h b/proc/escape.h
index 75e830b..684eba1 100644
--- a/proc/escape.h
+++ b/proc/escape.h
@@ -3,14 +3,12 @@
#include "readproc.h"
-
#define ESC_ARGS 0x1 // try to use cmdline instead of cmd
#define ESC_BRACKETS 0x2 // if using cmd, put '[' and ']' around it
#define ESC_DEFUNCT 0x4 // mark zombies with " <defunct>"
-int escape_command(char *__restrict const outbuf, const proc_t *__restrict const pp, int bytes, int *cells, unsigned flags);
+int escape_command (char *outbuf, const proc_t *pp, int bytes, int *cells, unsigned flags);
-#define ESC_STRETCH 1 // since we mangle to '?' this is 1 (would be 4 for octal escapes)
-int escape_str(char *__restrict dst, const char *__restrict src, int bufsize, int *maxcells);
+int escape_str (char *dst, const char *src, int bufsize, int *maxcells);
#endif
diff --git a/proc/libprocps.sym b/proc/libprocps.sym
index 8853048..9cdbd24 100644
--- a/proc/libprocps.sym
+++ b/proc/libprocps.sym
@@ -1,6 +1,5 @@
LIBPROCPS_0 {
global:
- escape_str;
fatal_proc_unmounted;
procps_cpu_count;
procps_diskstats_new;
diff --git a/ps/common.h b/ps/common.h
index 097b89d..9511c32 100644
--- a/ps/common.h
+++ b/ps/common.h
@@ -13,7 +13,6 @@
#define PROCPS_PS_H
#include "../include/nls.h"
-#include <proc/escape.h>
#include <proc/meminfo.h>
#include <proc/pids.h>
#include <proc/stat.h>
@@ -204,7 +203,6 @@ makEXT(noop)
* Try not to overflow the output buffer:
* 32 pages for env+cmd
* 64 kB pages on IA-64
- * 4 chars for "\377", or 1 when mangling to '?' (ESC_STRETCH)
* plus some slack for other stuff
* That is about 8.5 MB on IA-64, or 0.6 MB on i386
*
@@ -214,7 +212,7 @@ makEXT(noop)
*/
/* output buffer size */
-#define OUTBUF_SIZE (2 * 64*1024 * ESC_STRETCH)
+#define OUTBUF_SIZE (2 * 64*1024)
/******************* PS DEFINE *******************/
diff --git a/ps/output.c b/ps/output.c
index b594592..20f9a53 100644
--- a/ps/output.c
+++ b/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 **************/