8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2013 Gary Mills
23 *
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 *
27 * Portions Copyright 2009 Chad Mynhier
28 */
29
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/resource.h>
33 #include <sys/priocntl.h>
34 #include <sys/rtpriocntl.h>
35 #include <sys/tspriocntl.h>
36 #include <zone.h>
37
38 #include <libintl.h>
39 #include <limits.h>
40 #include <wchar.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <stdarg.h>
45 #include <stdio.h>
46 #include <stdio_ext.h>
47 #include <errno.h>
307 char zone_name[ZONENAME_MAX];
308 size_t n;
309
310 if (getzonenamebyid(zoneid, zone_name, sizeof (zone_name)) < 0) {
311 (void) snprintf(str, len, "%-6d", (int)zoneid);
312 } else {
313 n = mbstowcs(NULL, zone_name, 0);
314 if (n == (size_t)-1)
315 (void) snprintf(str, len, "%-28s", "ERROR");
316 else if (trunc && n > width)
317 (void) snprintf(str, len, "%.*s%c", width - 1,
318 zone_name, '*');
319 else
320 (void) snprintf(str, len, "%-28s", zone_name);
321 }
322 }
323
324 /*
325 * Remove all unprintable characters from process name
326 */
327 void
328 stripfname(char *buf)
329 {
330 int bytesleft = PRFNSZ;
331 wchar_t wchar;
332 int length;
333 char *cp;
334
335 buf[bytesleft - 1] = '\0';
336
337 for (cp = buf; *cp != '\0'; cp += length) {
338 length = mbtowc(&wchar, cp, MB_LEN_MAX);
339 if (length <= 0) {
340 *cp = '\0';
341 break;
342 }
343 if (!iswprint(wchar)) {
344 if (bytesleft <= length) {
345 *cp = '\0';
346 break;
347 }
348 (void) memmove(cp, cp + length, bytesleft - length);
349 length = 0;
350 }
351 bytesleft -= length;
352 }
353 }
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2013 Gary Mills
23 *
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 *
27 * Portions Copyright 2009 Chad Mynhier
28 * Copyright 2018 Joyent, Inc. All rights reserved.
29 */
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/resource.h>
34 #include <sys/priocntl.h>
35 #include <sys/rtpriocntl.h>
36 #include <sys/tspriocntl.h>
37 #include <zone.h>
38
39 #include <libintl.h>
40 #include <limits.h>
41 #include <wchar.h>
42 #include <unistd.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <stdarg.h>
46 #include <stdio.h>
47 #include <stdio_ext.h>
48 #include <errno.h>
308 char zone_name[ZONENAME_MAX];
309 size_t n;
310
311 if (getzonenamebyid(zoneid, zone_name, sizeof (zone_name)) < 0) {
312 (void) snprintf(str, len, "%-6d", (int)zoneid);
313 } else {
314 n = mbstowcs(NULL, zone_name, 0);
315 if (n == (size_t)-1)
316 (void) snprintf(str, len, "%-28s", "ERROR");
317 else if (trunc && n > width)
318 (void) snprintf(str, len, "%.*s%c", width - 1,
319 zone_name, '*');
320 else
321 (void) snprintf(str, len, "%-28s", zone_name);
322 }
323 }
324
325 /*
326 * Remove all unprintable characters from process name
327 */
328 static void
329 stripfname(char *buf, size_t bufsize, const char *pname)
330 {
331 int bytesleft = PRFNSZ;
332 wchar_t wchar;
333 int length;
334 char *cp;
335
336 (void) strlcpy(buf, pname, bufsize);
337
338 buf[bytesleft - 1] = '\0';
339
340 for (cp = buf; *cp != '\0'; cp += length) {
341 length = mbtowc(&wchar, cp, MB_LEN_MAX);
342 if (length <= 0) {
343 *cp = '\0';
344 break;
345 }
346 if (!iswprint(wchar)) {
347 if (bytesleft <= length) {
348 *cp = '\0';
349 break;
350 }
351 (void) memmove(cp, cp + length, bytesleft - length);
352 length = 0;
353 }
354 bytesleft -= length;
355 }
356 }
357
358
359 /*
360 * prstat has always implicitly wanted a terminal width of at least 80 columns
361 * (when a TTY is present). If run in a terminal narrower than 80 columns,
362 * prstat output may wrap. For wider terminals, we allow the last column to use
363 * the additional space.
364 *
365 * We never truncate if using -c, or not outputting to a TTY.
366 */
367 static int
368 format_namewidth(void)
369 {
370 int prefixlen = 0;
371
372 if (opts.o_cols == 0 || !(opts.o_outpmode & (OPT_TERMCAP | OPT_TRUNC)))
373 return (0);
374
375 if (opts.o_outpmode & OPT_PSINFO) {
376 if (opts.o_outpmode & OPT_LGRP)
377 prefixlen = 64;
378 else
379 prefixlen = 59;
380 } else if (opts.o_outpmode & OPT_MSACCT) {
381 prefixlen = 64;
382 }
383
384 return (opts.o_cols - prefixlen);
385 }
386
387 void
388 format_name(lwp_info_t *lwp, char *buf, size_t buflen)
389 {
390 int pname_width = PRFNSZ;
391 char nr_suffix[20];
392 char pname[PRFNSZ];
393 int width;
394 int n;
395
396 stripfname(pname, sizeof (pname), lwp->li_info.pr_fname);
397
398 if (opts.o_outpmode & OPT_LWPS) {
399 n = snprintf(nr_suffix, sizeof (nr_suffix), "%d",
400 lwp->li_info.pr_lwp.pr_lwpid);
401 } else {
402 n = snprintf(nr_suffix, sizeof (nr_suffix), "%d",
403 lwp->li_info.pr_nlwp + lwp->li_info.pr_nzomb);
404 }
405
406 width = format_namewidth();
407
408 /* If we're over budget, truncate the process name not the LWP part. */
409 if (strlen(pname) > (width - n - 1)) {
410 pname_width = width - n - 1;
411 pname[pname_width - 1] = '*';
412 }
413
414 if ((opts.o_outpmode & OPT_LWPS) && lwp->li_lwpname[0] != '\0') {
415 n = snprintf(buf, buflen, "%.*s/%s [%s]", pname_width,
416 pname, nr_suffix, lwp->li_lwpname);
417 } else {
418 n = snprintf(buf, buflen, "%.*s/%s", pname_width,
419 pname, nr_suffix);
420 }
421
422 if (width > 0 && strlen(buf) > width)
423 buf[width] = '\0';
424 }
|