xref: /netbsd-src/sys/miscfs/procfs/procfs_cmdline.c (revision 286a75975105df5166ef411cdec78e52455e110a)
1*286a7597Sthorpej /*	$NetBSD: procfs_cmdline.c,v 1.33 2024/05/18 00:05:50 thorpej Exp $	*/
28aa2fc5aSchristos 
38aa2fc5aSchristos /*
48aa2fc5aSchristos  * Copyright (c) 1999 Jaromir Dolecek <dolecek@ics.muni.cz>
58aa2fc5aSchristos  * Copyright (c) 1999 The NetBSD Foundation, Inc.
68aa2fc5aSchristos  * All rights reserved.
78aa2fc5aSchristos  *
88aa2fc5aSchristos  * This code is derived from software contributed to The NetBSD Foundation
98aa2fc5aSchristos  * by Jaromir Dolecek.
108aa2fc5aSchristos  *
118aa2fc5aSchristos  * Redistribution and use in source and binary forms, with or without
128aa2fc5aSchristos  * modification, are permitted provided that the following conditions
138aa2fc5aSchristos  * are met:
148aa2fc5aSchristos  * 1. Redistributions of source code must retain the above copyright
158aa2fc5aSchristos  *    notice, this list of conditions and the following disclaimer.
168aa2fc5aSchristos  * 2. Redistributions in binary form must reproduce the above copyright
178aa2fc5aSchristos  *    notice, this list of conditions and the following disclaimer in the
188aa2fc5aSchristos  *    documentation and/or other materials provided with the distribution.
198aa2fc5aSchristos  *
208aa2fc5aSchristos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
218aa2fc5aSchristos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
228aa2fc5aSchristos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
238aa2fc5aSchristos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
248aa2fc5aSchristos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
258aa2fc5aSchristos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
268aa2fc5aSchristos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
278aa2fc5aSchristos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
288aa2fc5aSchristos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
298aa2fc5aSchristos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
308aa2fc5aSchristos  * POSSIBILITY OF SUCH DAMAGE.
318aa2fc5aSchristos  */
328aa2fc5aSchristos 
33e4b00f43Slukem #include <sys/cdefs.h>
34*286a7597Sthorpej __KERNEL_RCSID(0, "$NetBSD: procfs_cmdline.c,v 1.33 2024/05/18 00:05:50 thorpej Exp $");
35e4b00f43Slukem 
368aa2fc5aSchristos #include <sys/param.h>
378aa2fc5aSchristos #include <sys/systm.h>
388aa2fc5aSchristos #include <sys/syslimits.h>
398aa2fc5aSchristos #include <sys/proc.h>
408aa2fc5aSchristos #include <sys/vnode.h>
418aa2fc5aSchristos #include <sys/exec.h>
4248717cfcSjoerg #include <sys/sysctl.h>
438aa2fc5aSchristos #include <miscfs/procfs/procfs.h>
448aa2fc5aSchristos 
454865d6ffSthorpej #include <uvm/uvm_extern.h>
464865d6ffSthorpej 
4748717cfcSjoerg static int
procfs_doprocargs_helper(void * cookie,const void * src,size_t off,size_t len)48262138d2Schristos procfs_doprocargs_helper(void *cookie, const void *src, size_t off, size_t len)
4948717cfcSjoerg {
5048717cfcSjoerg 	struct uio *uio = cookie;
5148717cfcSjoerg 	char *buf = __UNCONST(src);
5248717cfcSjoerg 
5348717cfcSjoerg 	buf += uio->uio_offset - off;
5437c269d9Schristos 	if (off + len <= (uintmax_t)uio->uio_offset)
5548717cfcSjoerg 		return 0;
5648717cfcSjoerg 	return uiomove(buf, off + len - uio->uio_offset, cookie);
5748717cfcSjoerg }
5848717cfcSjoerg 
598aa2fc5aSchristos /*
60262138d2Schristos  * code for returning process's command line arguments/environment
618aa2fc5aSchristos  */
628aa2fc5aSchristos int
procfs_doprocargs(struct lwp * curl,struct proc * p,struct pfsnode * pfs,struct uio * uio,int oid)63262138d2Schristos procfs_doprocargs(
64168cd830Schristos     struct lwp *curl,
654d595fd7Schristos     struct proc *p,
66168cd830Schristos     struct pfsnode *pfs,
67878c60d1Schristos     struct uio *uio,
68878c60d1Schristos     int oid
694d595fd7Schristos )
708aa2fc5aSchristos {
7148717cfcSjoerg 	size_t len, start;
7248717cfcSjoerg 	int error;
738aa2fc5aSchristos 
744865d6ffSthorpej 	/* Don't allow writing. */
754865d6ffSthorpej 	if (uio->uio_rw != UIO_READ)
76262138d2Schristos 		return EOPNOTSUPP;
778aa2fc5aSchristos 
784865d6ffSthorpej 	/*
794865d6ffSthorpej 	 * Zombies don't have a stack, so we can't read their psstrings.
804865d6ffSthorpej 	 * System processes also don't have a user stack.  This is what
814865d6ffSthorpej 	 * ps(1) would display.
824865d6ffSthorpej 	 */
83934634a1Spavel 	if (P_ZOMBIE(p) || (p->p_flag & PK_SYSTEM) != 0) {
8448717cfcSjoerg 		static char msg[] = "()";
8548717cfcSjoerg 		error = 0;
8648717cfcSjoerg 		if (0 == uio->uio_offset) {
8748717cfcSjoerg 			error = uiomove(msg, 1, uio);
8848717cfcSjoerg 			if (error)
89262138d2Schristos 				return error;
9048717cfcSjoerg 		}
9148717cfcSjoerg 		len = strlen(p->p_comm);
9237c269d9Schristos 		if (len >= (uintmax_t)uio->uio_offset) {
9348717cfcSjoerg 			start = uio->uio_offset - 1;
9448717cfcSjoerg 			error = uiomove(p->p_comm + start, len - start, uio);
9548717cfcSjoerg 			if (error)
96262138d2Schristos 				return error;
9748717cfcSjoerg 		}
9837c269d9Schristos 		if (len + 2 >= (uintmax_t)uio->uio_offset) {
9948717cfcSjoerg 			start = uio->uio_offset - 1 - len;
10048717cfcSjoerg 			error = uiomove(msg + 1 + start, 2 - start, uio);
10148717cfcSjoerg 		}
102262138d2Schristos 		return error;
1034865d6ffSthorpej 	}
1044865d6ffSthorpej 
10548717cfcSjoerg 	len = uio->uio_offset + uio->uio_resid;
106262138d2Schristos 	return copy_procargs(p, oid, &len, procfs_doprocargs_helper, uio);
1078aa2fc5aSchristos }
108