/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 1992, 1993, 19944* The Regents of the University of California. All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14* 3. Neither the name of the University nor the names of its contributors15* may be used to endorse or promote products derived from this software16* without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND19* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE22* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL23* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS24* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)25* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY27* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGE.29*/3031#include <sys/types.h>32#include <sys/time.h>33#include <sys/resource.h>3435#include <err.h>36#include <limits.h>37#include <stdio.h>38#include <stdint.h>39#include <stdlib.h>40#include <string.h>41#include <unistd.h>42#include <vis.h>4344#include "ps.h"4546static char *cmdpart(char *);47static char *shquote(char **);4849static char *50shquote(char **argv)51{52long arg_max;53static size_t buf_size;54size_t len;55char **p, *dst, *src;56static char *buf = NULL;5758if (buf == NULL) {59if ((arg_max = sysconf(_SC_ARG_MAX)) == -1)60errx(1, "sysconf _SC_ARG_MAX failed");61if (arg_max >= LONG_MAX / 4 || arg_max >= (long)(SIZE_MAX / 4))62errx(1, "sysconf _SC_ARG_MAX preposterously large");63buf_size = 4 * arg_max + 1;64if ((buf = malloc(buf_size)) == NULL)65errx(1, "malloc failed");66}6768if (*argv == NULL) {69buf[0] = '\0';70return (buf);71}72dst = buf;73for (p = argv; (src = *p++) != NULL; ) {74if (*src == '\0')75continue;76len = (buf_size - 1 - (dst - buf)) / 4;77strvisx(dst, src, strlen(src) < len ? strlen(src) : len,78VIS_NL | VIS_CSTYLE);79while (*dst != '\0')80dst++;81if ((buf_size - 1 - (dst - buf)) / 4 > 0)82*dst++ = ' ';83}84/* Chop off trailing space */85if (dst != buf && dst[-1] == ' ')86dst--;87*dst = '\0';88return (buf);89}9091static char *92cmdpart(char *arg0)93{94char *cp;9596return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);97}9899const char *100fmt_argv(char **argv, char *cmd, char *thread, size_t maxlen)101{102size_t len;103char *ap, *cp;104105if (argv == NULL || argv[0] == NULL) {106if (cmd == NULL)107return ("");108ap = NULL;109len = maxlen + 3;110} else {111ap = shquote(argv);112len = strlen(ap) + maxlen + 4;113}114cp = malloc(len);115if (cp == NULL)116errx(1, "malloc failed");117if (ap == NULL) {118if (thread != NULL) {119asprintf(&ap, "%s/%s", cmd, thread);120sprintf(cp, "[%.*s]", (int)maxlen, ap);121free(ap);122} else123sprintf(cp, "[%.*s]", (int)maxlen, cmd);124} else if (strncmp(cmdpart(argv[0]), cmd, maxlen) != 0)125sprintf(cp, "%s (%.*s)", ap, (int)maxlen, cmd);126else127strcpy(cp, ap);128return (cp);129}130131132