FreeBSD/sys/kern/kern_proc.c
/*
 * This sysctl allows a process to retrieve the argument list or process
 * title for another process without groping around in the address space
 * of the other process.  It also allow a process to set its own "process 
 * title to a string of its own choice.
 */
This sysctl allows a process to retrieve the argument list or process
title for another process without groping around in the address space
of the other process.  It also allow a process to set its own "process
title to a string of its own choice.
This sysctl allows a process to retrieve the argument list or process title for another process without groping around in the address space of the other process . It also allow a process to set its own " process title to a string of its own choice .
static int
sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS)
{
	int *name = (int *)arg1;
	u_int namelen = arg2;
	struct pargs *newpa, *pa;
	struct proc *p;
	struct sbuf sb;
	int flags, error = 0, error2;
	if (namelen != 1)
		return (EINVAL);
	flags = PGET_CANSEE;
	if (req->newptr != NULL)
		flags |= PGET_ISCURRENT;
	error = pget((pid_t)name[0], flags, &p);
	if (error)
		return (error);
	pa = p->p_args;
	if (pa != NULL) {
		pargs_hold(pa);
		PROC_UNLOCK(p);
		error = SYSCTL_OUT(req, pa->ar_args, pa->ar_length);
		pargs_drop(pa);
	} else if ((p->p_flag & (P_WEXIT | P_SYSTEM)) == 0) {
		_PHOLD(p);
		PROC_UNLOCK(p);
		sbuf_new_for_sysctl(&sb, NULL, GET_PS_STRINGS_CHUNK_SZ, req);
		sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
		error = proc_getargv(curthread, p, &sb);
		error2 = sbuf_finish(&sb);
		PRELE(p);
		sbuf_delete(&sb);
		if (error == 0 && error2 != 0)
			error = error2;
	} else {
		PROC_UNLOCK(p);
	}
	if (error != 0 || req->newptr == NULL)
		return (error);
	if (req->newlen + sizeof(struct pargs) > ps_arg_cache_limit)
		return (ENOMEM);
	newpa = pargs_alloc(req->newlen);
	error = SYSCTL_IN(req, newpa->ar_args, req->newlen);
	if (error != 0) {
		pargs_free(newpa);
		return (error);
	}
	PROC_LOCK(p);
	pa = p->p_args;
	p->p_args = newpa;
	PROC_UNLOCK(p);
	pargs_drop(pa);
	return (0);
}
static int sysctl_kern_proc_args ( SYSCTL_HANDLER_ARGS ) { int * name = ( int * ) arg1 ; u_int namelen = arg2 ; struct pargs * newpa , * pa ; struct proc * p ; struct sbuf sb ; int flags , error = 0 , error2 ; if ( namelen != 1 ) return ( EINVAL ) ; flags = PGET_CANSEE ; if ( req -> newptr != NULL ) flags |= PGET_ISCURRENT ; error = pget ( ( pid_t ) name [ 0 ] , flags , & p ) ; if ( error ) return ( error ) ; pa = p -> p_args ; if ( pa != NULL ) { pargs_hold ( pa ) ; PROC_UNLOCK ( p ) ; error = SYSCTL_OUT ( req , pa -> ar_args , pa -> ar_length ) ; pargs_drop ( pa ) ; } else if ( ( p -> p_flag & ( P_WEXIT | P_SYSTEM ) ) == 0 ) { _PHOLD ( p ) ; PROC_UNLOCK ( p ) ; sbuf_new_for_sysctl ( & sb , NULL , GET_PS_STRINGS_CHUNK_SZ , req ) ; sbuf_clear_flags ( & sb , SBUF_INCLUDENUL ) ; error = proc_getargv ( curthread , p , & sb ) ; error2 = sbuf_finish ( & sb ) ; PRELE ( p ) ; sbuf_delete ( & sb ) ; if ( error == 0 && error2 != 0 ) error = error2 ; } else { PROC_UNLOCK ( p ) ; } if ( error != 0 || req -> newptr == NULL ) return ( error ) ; if ( req -> newlen + sizeof ( struct pargs ) > ps_arg_cache_limit ) return ( ENOMEM ) ; newpa = pargs_alloc ( req -> newlen ) ; error = SYSCTL_IN ( req , newpa -> ar_args , req -> newlen ) ; if ( error != 0 ) { pargs_free ( newpa ) ; return ( error ) ; } PROC_LOCK ( p ) ; pa = p -> p_args ; p -> p_args = newpa ; PROC_UNLOCK ( p ) ; pargs_drop ( pa ) ; return ( 0 ) ; }
This sysctl allows a process to retrieve the argument list or process
 title for another process without groping around in the address space
 of the other process.
This sysctl allows a process to retrieve the argument list or process title for another process without groping around in the address space of the other process .