setproctitle.c revision 53297
1109998Smarkm/* 255714Skris * Copyright (c) 1995 Peter Wemm <peter@freebsd.org> 355714Skris * All rights reserved. 455714Skris * 555714Skris * Redistribution and use in source and binary forms, with or without 655714Skris * modification, is permitted provided that the following conditions 755714Skris * are met: 855714Skris * 1. Redistributions of source code must retain the above copyright 955714Skris * notice immediately at the beginning of the file, without modification, 1055714Skris * this list of conditions, and the following disclaimer. 1155714Skris * 2. Redistributions in binary form must reproduce the above copyright 1255714Skris * notice, this list of conditions and the following disclaimer in the 1355714Skris * documentation and/or other materials provided with the distribution. 1455714Skris * 3. Absolutely no warranty of function or purpose is made by the author 15109998Smarkm * Peter Wemm. 16109998Smarkm * 1755714Skris * $FreeBSD: head/lib/libc/gen/setproctitle.c 53297 1999-11-17 21:12:17Z brian $ 1855714Skris */ 1955714Skris 2055714Skris#include <sys/types.h> 2155714Skris#include <sys/param.h> 2255714Skris#include <sys/exec.h> 2355714Skris#include <sys/sysctl.h> 2455714Skris 2555714Skris#include <vm/vm.h> 2655714Skris#include <vm/vm_param.h> 2755714Skris#include <vm/pmap.h> 2855714Skris 2955714Skris#include <stdio.h> 3055714Skris#include <string.h> 3155714Skris#include <stdlib.h> 3255714Skris#include <unistd.h> 3355714Skris 3455714Skris/* 3555714Skris * Older FreeBSD 2.0, 2.1 and 2.2 had different ps_strings structures and 3655714Skris * in different locations. 3755714Skris * 1: old_ps_strings at the very top of the stack. 3855714Skris * 2: old_ps_strings at SPARE_USRSPACE below the top of the stack. 3955714Skris * 3: ps_strings at the very top of the stack. 4055714Skris * This attempts to support a kernel built in the #2 and #3 era. 4155714Skris */ 4255714Skris 4355714Skrisstruct old_ps_strings { 4455714Skris char *old_ps_argvstr; 4555714Skris int old_ps_nargvstr; 4655714Skris char *old_ps_envstr; 4755714Skris int old_ps_nenvstr; 4855714Skris}; 4955714Skris#define OLD_PS_STRINGS ((struct old_ps_strings *) \ 5055714Skris (USRSTACK - SPARE_USRSPACE - sizeof(struct old_ps_strings))) 5155714Skris 5255714Skris#if defined(__STDC__) /* from other parts of sendmail */ 5355714Skris#include <stdarg.h> 5455714Skris#else 5555714Skris#include <varargs.h> 5655714Skris#endif 5755714Skris 5855714Skris 5955714Skris#define SPT_BUFSIZE 2048 /* from other parts of sendmail */ 6055714Skrisextern char * __progname; /* is this defined in a .h anywhere? */ 6155714Skris 6255714Skrisvoid 6355714Skris#if defined(__STDC__) 6455714Skrissetproctitle(const char *fmt, ...) 6555714Skris#else 6655714Skrissetproctitle(fmt, va_alist) 6755714Skris const char *fmt; 6855714Skris va_dcl 6955714Skris#endif 7055714Skris{ 7155714Skris static struct ps_strings *ps_strings; 7255714Skris static char buf[SPT_BUFSIZE]; 7355714Skris static char obuf[SPT_BUFSIZE]; 7455714Skris static char **oargv, *kbuf; 7555714Skris static int oargc = -1; 7655714Skris static char *nargv[2] = { buf, NULL }; 7755714Skris char **nargvp; 7855714Skris int nargc; 7955714Skris va_list ap; 8055714Skris size_t len; 8155714Skris unsigned long ul_ps_strings; 8255714Skris int oid[4]; 8355714Skris 8455714Skris#if defined(__STDC__) 8555714Skris va_start(ap, fmt); 8655714Skris#else 8755714Skris va_start(ap); 8855714Skris#endif 8955714Skris 9055714Skris if (fmt) { 9155714Skris buf[sizeof(buf) - 1] = '\0'; 9255714Skris 9355714Skris /* print program name heading for grep */ 9455714Skris (void) snprintf(buf, sizeof(buf), "%s: ", __progname); 9555714Skris 9655714Skris /* 9755714Skris * can't use return from sprintf, as that is the count of how 9855714Skris * much it wanted to write, not how much it actually did. 9955714Skris */ 10055714Skris 10155714Skris len = strlen(buf); 10255714Skris 10355714Skris /* print the argument string */ 10455714Skris (void) vsnprintf(buf + len, sizeof(buf) - len, fmt, ap); 10555714Skris 10655714Skris nargvp = nargv; 10755714Skris nargc = 1; 10855714Skris kbuf = buf; 10955714Skris } else if (*obuf != '\0') { 11055714Skris /* Idea from NetBSD - reset the title on fmt == NULL */ 11155714Skris nargvp = oargv; 11255714Skris nargc = oargc; 11355714Skris kbuf = obuf; 11455714Skris } else 11555714Skris /* Nothing to restore */ 11655714Skris return; 11755714Skris 11855714Skris va_end(ap); 11955714Skris 12055714Skris /* Set the title into the kernel cached command line */ 12155714Skris oid[0] = CTL_KERN; 12255714Skris oid[1] = KERN_PROC; 12355714Skris oid[2] = KERN_PROC_ARGS; 12455714Skris oid[3] = getpid(); 12555714Skris sysctl(oid, 4, 0, 0, kbuf, strlen(kbuf) + 1); 12655714Skris 12755714Skris if (ps_strings == NULL) { 12855714Skris len = sizeof(ul_ps_strings); 12955714Skris if (sysctlbyname("kern.ps_strings", &ul_ps_strings, &len, NULL, 13055714Skris 0) == -1) 13155714Skris ul_ps_strings = PS_STRINGS; 13255714Skris ps_strings = (struct ps_strings *)ul_ps_strings; 13355714Skris } 13455714Skris 13555714Skris /* PS_STRINGS points to zeroed memory on a style #2 kernel */ 13655714Skris if (ps_strings->ps_argvstr) { 13755714Skris /* style #3 */ 13855714Skris if (oargc == -1) { 13955714Skris /* Record our original args */ 14055714Skris oargc = ps_strings->ps_nargvstr; 14155714Skris oargv = ps_strings->ps_argvstr; 14255714Skris for (nargc = len = 0; nargc < oargc; nargc++) { 14355714Skris snprintf(obuf + len, sizeof(obuf) - len, "%s%s", 14455714Skris len ? " " : "", oargv[nargc]); 14555714Skris if (len) 14655714Skris len++; 14755714Skris len += strlen(oargv[nargc]); 14855714Skris if (len >= sizeof(obuf)) 14955714Skris break; 15055714Skris } 15155714Skris } 15255714Skris ps_strings->ps_nargvstr = nargc; 15355714Skris ps_strings->ps_argvstr = nargvp; 15455714Skris } else { 15555714Skris /* style #2 - we can only restore our first arg :-( */ 15655714Skris if (*obuf == '\0') 15755714Skris strncpy(obuf, OLD_PS_STRINGS->old_ps_argvstr, 15855714Skris sizeof(obuf) - 1); 15955714Skris OLD_PS_STRINGS->old_ps_nargvstr = 1; 16055714Skris OLD_PS_STRINGS->old_ps_argvstr = nargvp[0]; 16155714Skris } 16255714Skris} 16355714Skris