Subject: Re: core file name format: diffs
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-kern
Date: 09/21/1999 17:48:53
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
On Mon, Sep 20, 1999 at 11:55:08AM -0400, der Mouse wrote:
> > so I've got the core name format stuff ready to commit (I hope :).
>
> Most excellent!
>
> I personally have little use for the core-name stuff, but I'm very
> pleased by the supporting mechanisms you've added - they look like
> something that can be leveraged usefully in the future.
I hope so :)
>
> > The basename of the per-process corename format have to be either
> > 'core' or end with '.core', so that it's easy to locate core dumps
> > with 'find'.
>
> I'm not at all sure I like this; I think syscall calls made by root
> should be exempt from this, and personally would argue an option should
Easy to change
> exist to disable the check entirely. (What I'm thinking here is
> something like a database startup script that does something like
> "sysctl -w proc.$$.corename = /var/mydb/cores/%p.%t" - appending
> ".core" is redundant and having to do it is annoying.)
I'm not sure adding yet another kernel option or sysctl variable for this
is the rigth thing to do. We should really change the semantic of securelevel
to a mask-based one.
>
> Mind you, I do think such a restriction should be available. :-) It's
> probably better to have it all the time than not have it at all.
>
> > One thing I've found really usefull is that it's now possible to
> > change limits of other processes.
>
> That rocks.
>
> > +.It Li n The process's name
> > +.It Li p The PID of the process
> > +.It Li t The process's creation date
> > +.It Li u The login name, as returned by
> > +.Xr getlogin 2
>
> It would be good to state how %p and %t are rendered into text
> (primarily for completeness).
What about this ? :
.It Li n The process's name
.It Li p The PID of the process (integer)
.It Li t The process's creation date (in seconds)
.It Li u The login name, as returned by
.Xr getlogin 2
>
> > +.It Li PROC_PID_LIMIT
> > +Return resources limits, as defined for the
>
> > +The fourth level name is one of:
> [...]
>
> > +The fifth level name is one of PROC_PID_LIMIT_TYPE_SOFT or
> > +PROC_PID_LIMIT_TYPE_HARD, to select respectively the soft or hard limit.
>
> What type is the value at the end of the chain? My first reaction is
> to assume it's a struct rlimit, but of course this doesn't make sense
> on close examination. In any case, I'd prefer to see an explicit
> statement here describing it.
Ok, what about this ? :
The fifth level name is one of PROC_PID_LIMIT_TYPE_SOFT or
PROC_PID_LIMIT_TYPE_HARD, to select respectively the soft or hard limit.
Both are of type integer.
>
> > + if (*s != '%') {
> [...]
> > + continue;
> > + }
> > + if (*(s+1) == 'n') { /* %n */
> [...]
> > + }
> > + if (*(s+1) == 'p') { /* %p */
> [...]
> > + }
> [...]
>
> Why do sequential tests here, rather than just using a switch, any
> particular reason?
No. This function is poorly written in general, I've re-done it.
It's better now (and uses a switch :)
>
> > + /* don't allow '.core' as a valid file name */
>
> Why not?
I though .core would not be detected by
'find . \( -name core -o -name \*.core \) -print'
It turns out I was wrong, I removed this restriction.
>
> > + if ((indx = findname(string, "third", bufpp, lp)) == -1)
> [...]
> > + if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
> [...]
> > + if ((indx = findname(string, "5th", bufpp, lp)) == -1)
>
> Shouldn't that be "fifth", for consistency?
When I wrote this I didn't know how to spell 'fifth' :)
I fixed it.
Thanks for your comments !
Appened below are diff for the current state of the changes. What are missing
now is support in /etc/rc*, I'll do this soon.
--
Manuel Bouyer <bouyer@antioche.eu.org>
--
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=sysctl-diff
Index: bin/csh/csh.1
===================================================================
RCS file: /cvsroot/basesrc/bin/csh/csh.1,v
retrieving revision 1.25
diff -u -r1.25 csh.1
--- csh.1 1999/07/30 01:08:12 1.25
+++ csh.1 1999/09/21 15:13:05
@@ -1408,6 +1408,10 @@
names and scale factors, unambiguous prefixes
of the names suffice.
.Pp
+Limits of an arbitrary process can be displayed or set using the
+.Xr sysctl(8)
+utility.
+.Pp
.It Ic login
Terminate a login shell, replacing it with an instance of
.Pa /usr/bin/login.
@@ -2133,6 +2137,7 @@
.Xr tty 4 ,
.Xr a.out 5 ,
.Xr environ 7 ,
+.Xr sysctl 8 ,
.br
.Em "An introduction to the C shell"
.Sh HISTORY
Index: bin/sh/sh.1
===================================================================
RCS file: /cvsroot/basesrc/bin/sh/sh.1,v
retrieving revision 1.30
diff -u -r1.30 sh.1
--- sh.1 1999/07/06 14:01:01 1.30
+++ sh.1 1999/09/21 15:13:14
@@ -1389,6 +1389,10 @@
or set. If value is specified, the limit is set to that number; otherwise
the current limit is displayed.
.Pp
+Limits of an arbitrary process can be displayed or set using the
+.Xr sysctl 8
+utility.
+.Pp
.It umask Op Ar mask
Set the value of umask (see
.Xr umask 2 )
@@ -1500,6 +1504,7 @@
.Xr passwd 4 ,
.Xr profile 4 ,
.Xr environ 5
+.Xr sysctl 8
.Sh HISTORY
A
.Nm
Index: lib/libc/gen/sysctl.3
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/gen/sysctl.3,v
retrieving revision 1.36
diff -u -r1.36 sysctl.3
--- sysctl.3 1999/06/24 14:18:10 1.36
+++ sysctl.3 1999/09/21 15:14:28
@@ -127,6 +127,7 @@
.It CTL\_KERN sys/sysctl.h High kernel limits
.It CTL\_MACHDEP sys/sysctl.h Machine dependent
.It CTL\_NET sys/socket.h Networking
+.It CTL\_PROC sys/sysctl.h Per-process
.It CTL\_USER sys/sysctl.h User-level
.It CTL\_VM vm/vm_param.h Virtual memory
.El
@@ -255,6 +256,7 @@
.It KERN\_BOOTTIME struct timeval no
.It KERN\_CHOWN\_RESTRICTED integer no
.It KERN\_CLOCKRATE struct clockinfo no
+.It KERN\_DEFCORENAME string yes
.It KERN\_DOMAINNAME string yes
.It KERN\_FILE struct file no
.It KERN\_FSYNC integer no
@@ -288,7 +290,6 @@
.It KERN\_RAWPARTITION integer no
.It KERN\_SAVED\_IDS integer no
.It KERN\_SECURELVL integer raise only
-.It KERN\_SHORTCORENAME integer yes
.It KERN\_SYNCHRONIZED\_IO integer no
.It KERN\_SYSVMSG integer no
.It KERN\_SYSVSEM integer no
@@ -326,6 +327,26 @@
This structure contains the clock, statistics clock and profiling clock
frequencies, the number of micro-seconds per hz tick, and the clock
skew rate.
+.It Li KERN_DEFCORENAME
+Default template for the name of core dumps (see also PROC_PID_CORENAME in the
+per-process variables CTL_PROC). This can be either an absolute
+or relative path name. Format characters can be used in the template,
+preceeded by the percent character (``%''). The following characters
+are recognised as format and subsitued:
+.Bl -column "cAA" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -offset indent
+.It Li n The process's name
+.It Li p The PID of the process (integer)
+.It Li t The process's creation date (in seconds)
+.It Li u The login name, as returned by
+.Xr getlogin 2
+.El
+The default value is
+.Nm %n.core
+and can be changed with the kernel configuration option
+.Cd options DEFCORENAME
+(see
+.Xr options 4 ,
+.Xr core 5 ).
.It Li KERN_DOMAINNAME
Get or set the YP domain name.
.It Li KERN_FILE
@@ -466,17 +487,6 @@
The system security level.
This level may be raised by processes with appropriate privilege.
It may only be lowered by process 1.
-.It Li KERN_SHORTCORENAME
-Whether core dumps are named
-.Nm programname.core
-(default, value 0) or
-.Nm core
-(value 1).
-The default value can be changed to 1 with the kernel configuration option
-.Cd options SHORTCORENAME
-(see
-.Xr options 4 ,
-.Xr core 5 ).
.It Li KERN_SYNCHRONIZED_IO
Returns 1 if the POSIX 1003.1b Synchronized I/O Option is available
on this system,
@@ -717,6 +727,77 @@
Returns the default UDP receive buffer size.
.El
.El
+.Sh CTL_PROC
+The string and integer information available for the CTL_PROC
+is detailed below.
+The changeable column shows whether a process with appropriate
+privilege may change the value.
+These values are per-process, and as such may change from one process
+to another. When a process is created, the default values are inherited from
+its parent. When a set-user-ID or set-group-ID binary is executed, the
+value of PROC_PID_CORENAME is reset to the system default value.
+The second level name is either the magic value PROC_CURPROC, which
+points to the current process, or the PID of the target process.
+.Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" "yes" -offset indent
+.It Sy Pa Third level name Type Changeable
+.It PROC\_PID\_CORENAME string yes
+.It PROC\_PID\_LIMIT node not applicable
+.El
+.Bl -tag -width "123456"
+.Pp
+.It Li PROC_PID_CORENAME
+The template of the core dump file name. Modifiers are the same as for
+KERN_DEFCORENAME. The base name must either be
+.Nm core
+or end with the suffix ``.core''.
+.It Li PROC_PID_LIMIT
+Return resources limits, as defined for the
+.Xr getrlimit 2
+and
+.Xr setrlimit 2
+system calls.
+The fourth level name is one of:
+.Bl -tag -width PROC_PID_LIMIT_MEMLOCKAA
+.It Li PROC_PID_LIMIT_CPU
+The maximum amount of cpu time (in seconds) to be used by each process.
+.It Li PROC_PID_LIMIT_FSIZE
+The largest size (in bytes) file that may be created.
+.It Li PROC_PID_LIMIT_DATA
+The maximum size (in bytes) of the data segment for a process;
+this defines how far a program may extend its break with the
+.Xr sbrk 2
+system call.
+.It Li PROC_PID_LIMIT_STACK
+The maximum size (in bytes) of the stack segment for a process;
+this defines how far a program's stack segment may be extended.
+Stack extension is performed automatically by the system.
+.It Li PROC_PID_LIMIT_CORE
+The largest size (in bytes)
+.Pa core
+file that may be created.
+.It Li PROC_PID_LIMIT_RSS
+The maximum size (in bytes) to which a process's resident set size may
+grow.
+This imposes a limit on the amount of physical memory to be given to
+a process; if memory is tight, the system will prefer to take memory
+from processes that are exceeding their declared resident set size.
+.It Li PROC_PID_LIMIT_MEMLOCK
+The maximum size (in bytes) which a process may lock into memory
+using the
+.Xr mlock 2
+function.
+.It Li PROC_PID_LIMIT_NPROC
+The maximum number of simultaneous processes for this user id.
+.It Li PROC_PID_LIMIT_NOFILE
+The maximum number of open files for this process.
+.El
+.Pp
+The fifth level name is one of PROC_PID_LIMIT_TYPE_SOFT or
+PROC_PID_LIMIT_TYPE_HARD, to select respectively the soft or hard limit.
+Both are of type integer.
+.El
+.Pp
+
.Sh CTL_USER
The string and integer information available for the CTL_USER level
is detailed below.
Index: lib/libc/sys/getrlimit.2
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/sys/getrlimit.2,v
retrieving revision 1.13
diff -u -r1.13 getrlimit.2
--- getrlimit.2 1999/03/22 19:45:04 1.13
+++ getrlimit.2 1999/09/21 15:14:29
@@ -54,7 +54,9 @@
.Fn getrlimit
call, and set with the
.Fn setrlimit
-call.
+call. Resources of an arbitrary process can be obtained/changed using
+.Xr sysctl 3 .
+..
.Pp
The
.Fa resource
Index: sbin/init/init.8
===================================================================
RCS file: /cvsroot/basesrc/sbin/init/init.8,v
retrieving revision 1.18
diff -u -r1.18 init.8
--- init.8 1998/11/14 07:47:36 1.18
+++ init.8 1999/09/21 15:14:30
@@ -116,6 +116,9 @@
.Xr ipf 8
(the in-kernel IP filtering facility) may not be changed.
+Users may not change the per-process core name template format, only the
+default can be changed.
+
Downgrading from highly secure mode to insecure mode (that is, to single-user
mode) always requires the root password to be entered on the console, whether
the console is marked as 'secure' in
Index: share/man/man5/core.5
===================================================================
RCS file: /cvsroot/sharesrc/share/man/man5/core.5,v
retrieving revision 1.8
diff -u -r1.8 core.5
--- core.5 1999/03/17 20:19:44 1.8
+++ core.5 1999/09/21 15:15:32
@@ -56,14 +56,10 @@
.Xr savecore 8 . )
The file is normally named
.Nm programname.core ,
-but is called
-.Nm core
-if the
-kernel configuration option
-.Cd options SHORTCORENAME
-is defined or the sysctl variable
-.Em kern.shortcorename
-is set to 1.
+but the name can be changed with the sysctl variables
+.Em kern.defcorename
+and
+.Em proc.<pid>.corename
.Pp
The maximum size of a
.Nm programname.core
Index: sys/compat/common/kern_resource_43.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/common/kern_resource_43.c,v
retrieving revision 1.5
diff -u -r1.5 kern_resource_43.c
--- kern_resource_43.c 1997/10/15 17:03:52 1.5
+++ kern_resource_43.c 1999/09/21 15:16:09
@@ -101,5 +101,5 @@
return (error);
lim.rlim_cur = olim.rlim_cur;
lim.rlim_max = olim.rlim_max;
- return (dosetrlimit(p, which, &lim));
+ return (dosetrlimit(p, p->p_cred, which, &lim));
}
Index: sys/compat/netbsd32/netbsd32_netbsd.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/netbsd32/netbsd32_netbsd.c,v
retrieving revision 1.17
diff -u -r1.17 netbsd32_netbsd.c
--- netbsd32_netbsd.c 1999/08/05 18:08:15 1.17
+++ netbsd32_netbsd.c 1999/09/21 15:16:11
@@ -3591,7 +3591,7 @@
error = copyin((caddr_t)(u_long)SCARG(uap, rlp), &alim, sizeof(struct rlimit));
if (error)
return (error);
- return (dosetrlimit(p, which, &alim));
+ return (dosetrlimit(p, p->p_cred, which, &alim));
}
int
Index: sys/compat/svr4/svr4_resource.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/svr4/svr4_resource.c,v
retrieving revision 1.4
diff -u -r1.4 svr4_resource.c
--- svr4_resource.c 1999/09/07 18:20:19 1.4
+++ svr4_resource.c 1999/09/21 15:16:11
@@ -185,7 +185,7 @@
else if (slim.rlim_cur == SVR4_RLIM_SAVED_CUR)
blim.rlim_cur = limp->rlim_cur;
- return dosetrlimit(p, rl, &blim);
+ return dosetrlimit(p, p->p_cred, rl, &blim);
}
@@ -283,5 +283,5 @@
else if (slim.rlim_cur == SVR4_RLIM64_SAVED_CUR)
blim.rlim_cur = limp->rlim_cur;
- return dosetrlimit(p, rl, &blim);
+ return dosetrlimit(p, p->p_cred, rl, &blim);
}
Index: sys/conf/files
===================================================================
RCS file: /cvsroot/syssrc/sys/conf/files,v
retrieving revision 1.316
diff -u -r1.316 files
--- files 1999/09/19 21:48:09 1.316
+++ files 1999/09/21 15:16:15
@@ -9,7 +9,7 @@
defopt KTRACE
defopt LOCKDEBUG
defopt RTC_OFFSET
-defopt SHORTCORENAME
+defopt DEFCORENAME
defopt UCONSOLE
defopt MULTIPROCESSOR
Index: sys/kern/init_main.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/init_main.c,v
retrieving revision 1.156
diff -u -r1.156 init_main.c
--- init_main.c 1999/09/17 20:11:56 1.156
+++ init_main.c 1999/09/21 15:17:30
@@ -182,6 +182,7 @@
#if defined(NFSSERVER) || defined(NFS)
extern void nfs_init __P((void));
#endif
+ extern char defcorename[];
/*
* Initialize the current process pointer (curproc) before
@@ -286,6 +287,7 @@
limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
+ limit0.pl_corename = defcorename;
limit0.p_refcnt = 1;
/*
Index: sys/kern/kern_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
retrieving revision 1.102
diff -u -r1.102 kern_exec.c
--- kern_exec.c 1999/08/09 02:42:20 1.102
+++ kern_exec.c 1999/09/21 15:17:30
@@ -457,7 +457,7 @@
p->p_ucred->cr_uid = attr.va_uid;
if (attr.va_mode & S_ISGID)
p->p_ucred->cr_gid = attr.va_gid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
} else
p->p_flag &= ~P_SUGID;
p->p_cred->p_svuid = p->p_ucred->cr_uid;
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_proc.c,v
retrieving revision 1.34
diff -u -r1.34 kern_proc.c
--- kern_proc.c 1999/07/25 06:30:34 1.34
+++ kern_proc.c 1999/09/21 15:17:31
@@ -519,6 +519,25 @@
}
}
+/* mark process as suid/sgid, reset some values do defaults */
+void
+p_sugid(p)
+ struct proc *p;
+{
+ extern char defcorename[];
+
+ p->p_flag |= P_SUGID;
+ /* reset what needs to be reset in plimit */
+ if (p->p_limit->pl_corename != defcorename) {
+ if (p->p_limit->p_refcnt > 1) {
+ p->p_limit->p_refcnt--;
+ p->p_limit = limcopy(p->p_limit);
+ }
+ p->p_limit->pl_corename = defcorename;
+ }
+}
+
+
#ifdef DEBUG
void
pgrpdump()
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_prot.c,v
retrieving revision 1.54
diff -u -r1.54 kern_prot.c
--- kern_prot.c 1999/04/30 05:30:32 1.54
+++ kern_prot.c 1999/09/21 15:17:32
@@ -335,7 +335,7 @@
pc->pc_ucred->cr_uid = uid;
pc->p_ruid = uid;
pc->p_svuid = uid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -363,7 +363,7 @@
*/
pc->pc_ucred = crcopy(pc->pc_ucred);
pc->pc_ucred->cr_uid = euid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -408,7 +408,7 @@
}
if (euid != (uid_t)-1 && ruid != (uid_t)-1)
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -434,7 +434,7 @@
pc->pc_ucred->cr_gid = gid;
pc->p_rgid = gid;
pc->p_svgid = gid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -458,7 +458,7 @@
return (error);
pc->pc_ucred = crcopy(pc->pc_ucred);
pc->pc_ucred->cr_gid = egid;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -501,7 +501,7 @@
}
if (egid != (gid_t)-1 && rgid != (gid_t)-1)
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
@@ -531,7 +531,7 @@
if (error)
return (error);
pc->pc_ucred->cr_ngroups = ngrp;
- p->p_flag |= P_SUGID;
+ p_sugid(p);
return (0);
}
Index: sys/kern/kern_resource.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_resource.c,v
retrieving revision 1.52
diff -u -r1.52 kern_resource.c
--- kern_resource.c 1999/07/25 06:30:34 1.52
+++ kern_resource.c 1999/09/21 15:17:32
@@ -225,12 +225,13 @@
error = copyin(SCARG(uap, rlp), &alim, sizeof(struct rlimit));
if (error)
return (error);
- return (dosetrlimit(p, which, &alim));
+ return (dosetrlimit(p, p->p_cred, which, &alim));
}
int
-dosetrlimit(p, which, limp)
+dosetrlimit(p, cred, which, limp)
struct proc *p;
+ struct pcred *cred;
int which;
struct rlimit *limp;
{
@@ -247,7 +248,7 @@
alimp = &p->p_rlimit[which];
if (limp->rlim_cur > alimp->rlim_max ||
limp->rlim_max > alimp->rlim_max)
- if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+ if ((error = suser(cred->pc_ucred, &p->p_acflag)) != 0)
return (error);
if (limp->rlim_cur > limp->rlim_max)
limp->rlim_cur = limp->rlim_max;
@@ -458,6 +459,7 @@
newlim = pool_get(&plimit_pool, PR_WAITOK);
memcpy(newlim->pl_rlimit, lim->pl_rlimit,
sizeof(struct rlimit) * RLIM_NLIMITS);
+ newlim->pl_corename = lim->pl_corename;
newlim->p_lflags = 0;
newlim->p_refcnt = 1;
return (newlim);
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sig.c,v
retrieving revision 1.93
diff -u -r1.93 kern_sig.c
--- kern_sig.c 1999/08/31 12:30:35 1.93
+++ kern_sig.c 1999/09/21 15:17:33
@@ -79,6 +79,7 @@
void stop __P((struct proc *p));
void killproc __P((struct proc *, char *));
+static int build_corename __P((char *));
sigset_t contsigmask, stopsigmask, sigcantmask;
@@ -1264,9 +1265,8 @@
struct nameidata nd;
struct vattr vattr;
int error, error1;
- char name[MAXCOMLEN+6]; /* progname.core */
+ char name[MAXPATHLEN];
struct core core;
- extern int shortcorename;
/*
* Make sure the process has not set-id, to prevent data leaks.
@@ -1293,11 +1293,10 @@
(vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0)
return (EPERM);
- if (shortcorename)
- sprintf(name, "core");
- else
- sprintf(name, "%s.core", p->p_comm);
-
+ error = build_corename(name);
+ if (error)
+ return error;
+
NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
error = vn_open(&nd, O_CREAT | FWRITE | FNOSYMLINK, S_IRUSR | S_IWUSR);
if (error)
@@ -1393,4 +1392,52 @@
psignal(p, SIGSYS);
return (ENOSYS);
+}
+
+static int
+build_corename(dst)
+ char *dst;
+{
+ const char *s;
+ char *d;
+ int len, i;
+
+ for (s = curproc->p_limit->pl_corename, len = 0, d = dst;
+ *s != '\0'; s++) {
+ if (*s == '%') {
+ switch (*(s+1)) {
+ case 'n':
+ i = snprintf(d,MAXPATHLEN - 1 - len, "%s",
+ curproc->p_comm);
+ break;
+ case 'p':
+ i = snprintf(d, MAXPATHLEN - 1 - len, "%d",
+ curproc->p_pid);
+ break;
+ case 'u':
+ i = snprintf(d, MAXPATHLEN - 1 - len, "%s",
+ curproc->p_pgrp->pg_session->s_login);
+ break;
+ case 't':
+ i = snprintf(d, MAXPATHLEN - 1 - len, "%ld",
+ curproc->p_stats->p_start.tv_sec);
+ break;
+ default:
+ goto copy;
+ }
+ if (i >= MAXPATHLEN - 1 - len)
+ return ENAMETOOLONG;
+ len += i;
+ d += i;
+ s++;
+ } else {
+copy: *d = *s;
+ d++;
+ len++;
+ if (len >= MAXPATHLEN - 1)
+ return ENAMETOOLONG;
+ }
+ }
+ *d = '\0';
+ return 0;
}
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sysctl.c,v
retrieving revision 1.50
diff -u -r1.50 kern_sysctl.c
--- kern_sysctl.c 1999/07/25 06:30:35 1.50
+++ kern_sysctl.c 1999/09/21 15:17:33
@@ -44,7 +44,7 @@
#include "opt_ddb.h"
#include "opt_insecure.h"
-#include "opt_shortcorename.h"
+#include "opt_defcorename.h"
#include "opt_sysv.h"
#include <sys/param.h>
@@ -68,6 +68,8 @@
#include <sys/mount.h>
#include <sys/syscallargs.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
#if defined(DDB)
@@ -102,9 +104,6 @@
sysctlfn *fn;
int name[CTL_MAXNAME];
- if (SCARG(uap, new) != NULL &&
- (error = suser(p->p_ucred, &p->p_acflag)))
- return (error);
/*
* all top-level sysctl names are non-terminal
*/
@@ -115,6 +114,15 @@
if (error)
return (error);
+ /*
+ * For all but CTL_PROC, must be root to change a value.
+ * For CTL_PROC, must be root, or owner of the proc (and not suid),
+ * this is checked in proc_sysctl() (once we know the targer proc).
+ */
+ if (SCARG(uap, new) != NULL && name[0] != CTL_PROC &&
+ (error = suser(p->p_ucred, &p->p_acflag)))
+ return error;
+
switch (name[0]) {
case CTL_KERN:
fn = kern_sysctl;
@@ -146,6 +154,9 @@
fn = ddb_sysctl;
break;
#endif
+ case CTL_PROC:
+ fn = proc_sysctl;
+ break;
default:
return (EOPNOTSUPP);
}
@@ -210,10 +221,12 @@
#else
int securelevel = 0;
#endif
-#ifdef SHORTCORENAME
-int shortcorename = 1;
+#ifdef DEFCORENAME
+char defcorename[MAXPATHLEN] = DEFCORENAME;
+int defcorenamelen = sizeof(DEFCORENAME);
#else
-int shortcorename = 0;
+char defcorename[MAXPATHLEN] = "%n.core";
+int defcorenamelen = sizeof("%n.core");
#endif
/*
@@ -232,7 +245,6 @@
int error, level, inthostid;
int old_autonicetime;
int old_vnodes;
- int old_shortcorename;
extern char ostype[], osrelease[], version[];
/* All sysctl names at this level, except for a few, are terminal. */
@@ -304,7 +316,7 @@
case KERN_VNODE:
return (sysctl_vnode(oldp, oldlenp, p));
case KERN_PROC:
- return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));
+ return (sysctl_doeproc(name + 1, namelen - 1, oldp, oldlenp));
case KERN_FILE:
return (sysctl_file(oldp, oldlenp));
#ifdef GPROF
@@ -380,16 +392,14 @@
#else
return (sysctl_rdint(oldp, oldlenp, newp, 0));
#endif
- case KERN_SHORTCORENAME:
- /* Only allow values of zero or one. */
- old_shortcorename = shortcorename;
- error = sysctl_int(oldp, oldlenp, newp, newlen,
- &shortcorename);
- if (shortcorename != 0 && shortcorename != 1) {
- shortcorename = old_shortcorename;
- return (EINVAL);
- }
- return (error);
+ case KERN_DEFCORENAME:
+ if (newp && newlen < 1)
+ return (EINVAL);
+ error = sysctl_string(oldp, oldlenp, newp, newlen,
+ defcorename, sizeof(defcorename));
+ if (newp && !error)
+ defcorenamelen = newlen;
+ return (error);
case KERN_SYNCHRONIZED_IO:
return (sysctl_rdint(oldp, oldlenp, newp, 1));
case KERN_IOV_MAX:
@@ -498,6 +508,133 @@
}
#endif /* DEBUG */
+int
+proc_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ struct proc *p;
+{
+ struct proc *ptmp;
+ const struct proclist_desc *pd;
+ int error = 0;
+ struct rlimit alim;
+ char *tmps;
+ int i, curlen, len;
+
+ if (namelen < 2)
+ return EINVAL;
+
+ if (name[0] == PROC_CURPROC) {
+ ptmp = p;
+ } else {
+ proclist_lock_read();
+ for (pd = proclists; pd->pd_list != NULL; pd++) {
+ for (ptmp = LIST_FIRST(pd->pd_list); ptmp != NULL;
+ ptmp = LIST_NEXT(ptmp, p_list)) {
+ /* Skip embryonic processes. */
+ if (ptmp->p_stat == SIDL)
+ continue;
+ if (ptmp->p_pid == (pid_t)name[0])
+ break;
+ }
+ if (ptmp != NULL)
+ break;
+ }
+ proclist_unlock_read();
+ if (ptmp == NULL)
+ return(ESRCH);
+ if (p->p_ucred->cr_uid != 0) {
+ if(p->p_cred->p_ruid != ptmp->p_cred->p_ruid ||
+ p->p_cred->p_ruid != ptmp->p_cred->p_svuid)
+ return EPERM;
+ if (ptmp->p_cred->p_rgid != ptmp->p_cred->p_svgid)
+ return EPERM; /* sgid proc */
+ for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
+ if (p->p_ucred->cr_groups[i] ==
+ ptmp->p_cred->p_rgid)
+ break;
+ }
+ if (i == p->p_ucred->cr_ngroups)
+ return EPERM;
+ }
+ }
+ if (name[1] == PROC_PID_CORENAME) {
+ if (namelen != 2)
+ return EINVAL;
+ /*
+ * Can't use sysctl_string() here because we may malloc a new
+ * area during the process, so we have to do it by hand.
+ */
+ curlen = strlen(ptmp->p_limit->pl_corename) + 1;
+ if (oldp && *oldlenp < curlen)
+ return (ENOMEM);
+ if (newp) {
+ tmps = (char*)newp;
+ if (securelevel > 2)
+ return EPERM;
+ if (newlen > MAXPATHLEN)
+ return ENAMETOOLONG;
+ /* Enforce to be either 'core' for end with '.core' */
+ if (newlen < 4) /* c.o.r.e */
+ return EINVAL;
+ len = newlen - 4;
+ if (len > 0) {
+ if (tmps[len - 1] != '.' &&
+ tmps[len - 1] != '/')
+ return EINVAL;
+ }
+ if (strcmp(&tmps[len], "core") != 0)
+ return EINVAL;
+ }
+ if (oldp) {
+ *oldlenp = curlen;
+ error = copyout(ptmp->p_limit->pl_corename, oldp,
+ curlen);
+ }
+ if (newp && error == 0) {
+ if (ptmp->p_limit->p_refcnt > 1 &&
+ (ptmp->p_limit->p_lflags & PL_SHAREMOD) == 0) {
+ ptmp->p_limit->p_refcnt--;
+ ptmp->p_limit = limcopy(ptmp->p_limit);
+ } else if (ptmp->p_limit->pl_corename != defcorename) {
+ free(ptmp->p_limit->pl_corename, M_TEMP);
+ }
+ ptmp->p_limit->pl_corename = malloc(newlen + 1,
+ M_TEMP, M_WAITOK);
+ error = copyin(newp, ptmp->p_limit->pl_corename,
+ newlen + 1);
+ ptmp->p_limit->pl_corename[newlen] = 0;
+ }
+ return (error);
+ }
+ if (name[1] == PROC_PID_LIMIT) {
+ if (namelen != 4 || name[2] >= PROC_PID_LIMIT_MAXID)
+ return EINVAL;
+ memcpy(&alim, &ptmp->p_rlimit[name[2] - 1], sizeof(alim));
+ if (name[3] == PROC_PID_LIMIT_TYPE_HARD)
+ error = sysctl_quad(oldp, oldlenp, newp, newlen,
+ &alim.rlim_max);
+ else if (name[3] == PROC_PID_LIMIT_TYPE_SOFT)
+ error = sysctl_quad(oldp, oldlenp, newp, newlen,
+ &alim.rlim_cur);
+ else
+ error = EINVAL;
+
+ if (error)
+ return error;
+
+ if (newp)
+ error = dosetrlimit(ptmp, p->p_cred,
+ name[2] - 1, &alim);
+ return error;
+ }
+ return (EINVAL);
+}
+
/*
* Validate parameters and get old / set new parameters
* for an integer-valued sysctl function.
@@ -548,6 +685,55 @@
/*
* Validate parameters and get old / set new parameters
+ * for an quad-valued sysctl function.
+ */
+int
+sysctl_quad(oldp, oldlenp, newp, newlen, valp)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ quad_t *valp;
+{
+ int error = 0;
+
+ if (oldp && *oldlenp < sizeof(quad_t))
+ return (ENOMEM);
+ if (newp && newlen != sizeof(quad_t))
+ return (EINVAL);
+ *oldlenp = sizeof(quad_t);
+ if (oldp)
+ error = copyout(valp, oldp, sizeof(quad_t));
+ if (error == 0 && newp)
+ error = copyin(newp, valp, sizeof(quad_t));
+ return (error);
+}
+
+/*
+ * As above, but read-only.
+ */
+int
+sysctl_rdquad(oldp, oldlenp, newp, val)
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ quad_t val;
+{
+ int error = 0;
+
+ if (oldp && *oldlenp < sizeof(quad_t))
+ return (ENOMEM);
+ if (newp)
+ return (EPERM);
+ *oldlenp = sizeof(quad_t);
+ if (oldp)
+ error = copyout((caddr_t)&val, oldp, sizeof(quad_t));
+ return (error);
+}
+
+
+/*
+ * Validate parameters and get old / set new parameters
* for a string-valued sysctl function.
*/
int
@@ -709,7 +895,7 @@
#define KERN_PROCSLOP (5 * sizeof(struct kinfo_proc))
int
-sysctl_doproc(name, namelen, where, sizep)
+sysctl_doeproc(name, namelen, where, sizep)
int *name;
u_int namelen;
char *where;
Index: sys/sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.83
diff -u -r1.83 proc.h
--- proc.h 1999/08/10 23:33:27 1.83
+++ proc.h 1999/09/21 15:17:47
@@ -392,5 +392,6 @@
void proclist_unlock_read __P((void));
int proclist_lock_write __P((void));
void proclist_unlock_write __P((int));
+void p_sugid __P((struct proc*));
#endif /* _KERNEL */
#endif /* !_SYS_PROC_H_ */
Index: sys/sys/resource.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/resource.h,v
retrieving revision 1.19
diff -u -r1.19 resource.h
--- resource.h 1998/12/09 14:39:09 1.19
+++ resource.h 1999/09/21 15:17:47
@@ -120,7 +120,8 @@
#ifdef _KERNEL
extern struct loadavg averunnable;
-int dosetrlimit __P((struct proc *, int, struct rlimit *));
+struct pcred;
+int dosetrlimit __P((struct proc *, struct pcred *, int, struct rlimit *));
int donice __P((struct proc *, struct proc *, int));
#else
Index: sys/sys/resourcevar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/resourcevar.h,v
retrieving revision 1.13
diff -u -r1.13 resourcevar.h
--- resourcevar.h 1998/03/01 02:24:14 1.13
+++ resourcevar.h 1999/09/21 15:17:47
@@ -73,6 +73,7 @@
*/
struct plimit {
struct rlimit pl_rlimit[RLIM_NLIMITS];
+ char *pl_corename;
#define PL_SHAREMOD 0x01 /* modifications are shared */
int p_lflags;
int p_refcnt; /* number of references */
@@ -88,8 +89,7 @@
void addupc_task __P((struct proc *p, u_long pc, u_int ticks));
void calcru __P((struct proc *p, struct timeval *up, struct timeval *sp,
struct timeval *ip));
-struct plimit
- *limcopy __P((struct plimit *lim));
+struct plimit *limcopy __P((struct plimit *lim));
void ruadd __P((struct rusage *ru, struct rusage *ru2));
#endif
#endif /* !_SYS_RESOURCEVAR_H_ */
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/sysctl.h,v
retrieving revision 1.35
diff -u -r1.35 sysctl.h
--- sysctl.h 1999/06/24 14:18:12 1.35
+++ sysctl.h 1999/09/21 15:17:48
@@ -92,7 +92,8 @@
#define CTL_MACHDEP 7 /* machine dependent */
#define CTL_USER 8 /* user-level */
#define CTL_DDB 9 /* in-kernel debugger */
-#define CTL_MAXID 10 /* number of valid top-level ids */
+#define CTL_PROC 10 /* per-proc attr */
+#define CTL_MAXID 11 /* number of valid top-level ids */
#define CTL_NAMES { \
{ 0, 0 }, \
@@ -105,6 +106,7 @@
{ "machdep", CTLTYPE_NODE }, \
{ "user", CTLTYPE_NODE }, \
{ "ddb", CTLTYPE_NODE }, \
+ { "proc", CTLTYPE_NODE }, \
}
/*
@@ -145,7 +147,7 @@
#define KERN_SYSVMSG 33 /* int: SysV message queue suppoprt */
#define KERN_SYSVSEM 34 /* int: SysV semaphore support */
#define KERN_SYSVSHM 35 /* int: SysV shared memory support */
-#define KERN_SHORTCORENAME 36 /* int: programs dump core as "core" */
+#define KERN_DEFCORENAME 36 /* string: default corename format */
#define KERN_SYNCHRONIZED_IO 37 /* int: POSIX synchronized I/O */
#define KERN_IOV_MAX 38 /* int: max iovec's for readv(2) etc. */
#define KERN_MBUF 39 /* node: mbuf parameters */
@@ -192,7 +194,7 @@
{ "sysvmsg", CTLTYPE_INT }, \
{ "sysvsem", CTLTYPE_INT }, \
{ "sysvshm", CTLTYPE_INT }, \
- { "shortcorename", CTLTYPE_INT }, \
+ { "defcorename", CTLTYPE_STRING }, \
{ "synchronized_io", CTLTYPE_INT }, \
{ "iov_max", CTLTYPE_INT }, \
{ "mbuf", CTLTYPE_NODE }, \
@@ -356,6 +358,61 @@
#define CTL_DEBUG_VALUE 1 /* int: variable value */
#define CTL_DEBUG_MAXID 20
+/*
+ * CTL_PROC subtype. Either a PID, or a magic value for the current proc.
+ */
+
+#define PROC_CURPROC (~((u_int)1 << 31))
+
+/*
+ * CTL_PROC tree: either corename (string), or a limit
+ * (rlimit.<type>.{hard,soft}, int).
+ */
+#define PROC_PID_CORENAME 1
+#define PROC_PID_LIMIT 2
+#define PROC_PID_MAXID 3
+
+#define PROC_PID_NAMES { \
+ { 0, 0 }, \
+ { "corename", CTLTYPE_STRING }, \
+ { "rlimit", CTLTYPE_NODE }, \
+}
+
+/* Limit types from <sys/resources.h> */
+#define PROC_PID_LIMIT_CPU (RLIMIT_CPU+1)
+#define PROC_PID_LIMIT_FSIZE (RLIMIT_FSIZE+1)
+#define PROC_PID_LIMIT_DATA (RLIMIT_DATA+1)
+#define PROC_PID_LIMIT_STACK (RLIMIT_STACK+1)
+#define PROC_PID_LIMIT_CORE (RLIMIT_CORE+1)
+#define PROC_PID_LIMIT_RSS (RLIMIT_RSS+1)
+#define PROC_PID_LIMIT_MEMLOCK (RLIMIT_MEMLOCK+1)
+#define PROC_PID_LIMIT_NPROC (RLIMIT_NPROC+1)
+#define PROC_PID_LIMIT_NOFILE (RLIMIT_NOFILE+1)
+#define PROC_PID_LIMIT_MAXID 10
+
+#define PROC_PID_LIMIT_NAMES { \
+ { 0, 0 }, \
+ { "cputime", CTLTYPE_NODE }, \
+ { "filesize", CTLTYPE_NODE }, \
+ { "datasize", CTLTYPE_NODE }, \
+ { "stacksize", CTLTYPE_NODE }, \
+ { "coredumpsize", CTLTYPE_NODE }, \
+ { "memoryuse", CTLTYPE_NODE }, \
+ { "memorylocked", CTLTYPE_NODE }, \
+ { "maxproc", CTLTYPE_NODE }, \
+ { "descriptors", CTLTYPE_NODE }, \
+}
+/* for each type, either hard or soft value */
+#define PROC_PID_LIMIT_TYPE_SOFT 1
+#define PROC_PID_LIMIT_TYPE_HARD 2
+#define PROC_PID_LIMIT_TYPE_MAXID 3
+
+#define PROC_PID_LIMIT_TYPE_NAMES { \
+ {0, 0}, \
+ { "soft", CTLTYPE_QUAD }, \
+ { "hard", CTLTYPE_QUAD }, \
+}
+
#ifdef _KERNEL
/*
* CTL_DEBUG variables.
@@ -394,12 +451,14 @@
int sysctl_int __P((void *, size_t *, void *, size_t, int *));
int sysctl_rdint __P((void *, size_t *, void *, int));
+int sysctl_quad __P((void *, size_t *, void *, size_t, quad_t *));
+int sysctl_rdquad __P((void *, size_t *, void *, quad_t));
int sysctl_string __P((void *, size_t *, void *, size_t, char *, int));
int sysctl_rdstring __P((void *, size_t *, void *, char *));
int sysctl_rdstruct __P((void *, size_t *, void *, void *, int));
int sysctl_struct __P((void *, size_t *, void *, size_t, void *, int));
int sysctl_file __P((char *, size_t *));
-int sysctl_doproc __P((int *, u_int, char *, size_t *));
+int sysctl_doeproc __P((int *, u_int, char *, size_t *));
struct radix_node;
struct walkarg;
int sysctl_dumpentry __P((struct radix_node *, void *));
@@ -421,6 +480,8 @@
struct proc *));
int hw_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
struct proc *));
+int proc_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
+ struct proc *));
#ifdef DEBUG
int debug_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
struct proc *));
Index: usr.sbin/sysctl/sysctl.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/sysctl/sysctl.8,v
retrieving revision 1.30
diff -u -r1.30 sysctl.8
--- sysctl.8 1999/07/02 08:58:22 1.30
+++ sysctl.8 1999/09/21 15:18:05
@@ -86,6 +86,13 @@
flag must be specified and the MIB name followed
by an equal sign and the new value to be used.
.Pp
+The proc top-level MIB has a special semantic: it represent per-process values
+and as such may differ from one process to another. The second-level name
+is the pid of the process (in decimal form), or the special word 'curproc'.
+For variables below 'proc.<pid>.rlimit', the integer value may be remplaced
+with the string 'unlimited' if it matches the magic value used to disable
+a limit.
+.Pp
The information available from
.Nm sysctl
consists of integers, strings, and tables.
@@ -137,7 +144,7 @@
.It kern.sysvmsg integer no
.It kern.sysvsem integer no
.It kern.sysvshm integer no
-.It kern.shortcorename integer yes
+.It kern.defcorename string yes
.It kern.synchronized_io integer no
.It kern.iov_max integer no
.It kern.mbuf.msize integer no
@@ -281,6 +288,23 @@
.It ddb.tabstops integer yes
.It ddb.lines integer yes
.It ddb.onpanic integer yes
+.It proc.<pid>.corename string yes
+.It proc.<pid>.rlimit.cputime.soft integer yes
+.It proc.<pid>.rlimit.cputime.hard integer yes
+.It proc.<pid>.rlimit.filesize.soft integer yes
+.It proc.<pid>.rlimit.filesize.hard integer yes
+.It proc.<pid>.rlimit.datasize.soft integer yes
+.It proc.<pid>.rlimit.datasize.hard integer yes
+.It proc.<pid>.rlimit.stacksize.soft integer yes
+.It proc.<pid>.rlimit.stacksize.hard integer yes
+.It proc.<pid>.rlimit.coredumpsize.soft integer yes
+.It proc.<pid>.rlimit.coredumpsize.hard integer yes
+.It proc.<pid>.rlimit.memoryuse.soft integer yes
+.It proc.<pid>.rlimit.memoryuse.hard integer yes
+.It proc.<pid>.rlimit.memorylocked.soft integer yes
+.It proc.<pid>.rlimit.memorylocked.hard integer yes
+.It proc.<pid>.rlimit.maxproc.soft integer yes
+.It proc.<pid>.rlimit.maxproc.hard integer yes
.El
.Sh EXAMPLES
.Pp
@@ -305,6 +329,26 @@
.Bd -literal -offset indent -compact
sysctl vm.loadavg
.Ed
+.Pp
+To view the values of the per-process variables of the current shell,
+the request:
+.Bd -literal -offset indent -compact
+sysctl proc.$$
+.Ed
+can be used if the shell interpreter remplaces $$ with it's pid (this is true
+for most shells).
+.Pp
+To redirect core dumps to the /var/tmp/<username> directory,
+.Bd -literal -offset indent -compact
+sysctl -w proc.$$.corename=/var/tmp/%u/%n.core
+.Ed
+Shall be used.
+.Bd -literal -offset indent -compact
+sysctl -w proc.curproc.corename=/var/tmp/%u/%n.core
+.Ed
+changes the value for the sysctl process itself, and will not have the desired
+effect.
+
.Sh FILES
.Bl -tag -width <netinet/icmpXvar.h> -compact
.It Pa <sys/sysctl.h>
Index: usr.sbin/sysctl/sysctl.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/sysctl/sysctl.c,v
retrieving revision 1.21
diff -u -r1.21 sysctl.c
--- sysctl.c 1999/07/30 10:29:35 1.21
+++ sysctl.c 1999/09/21 15:18:05
@@ -55,6 +55,7 @@
#include <sys/socket.h>
#include <sys/mount.h>
#include <sys/mbuf.h>
+#include <sys/resource.h>
#include <vm/vm_param.h>
#include <machine/cpu.h>
@@ -119,6 +120,9 @@
#ifdef CTL_MACHDEP_NAMES
struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
#endif
+/* this one is dummy, it's used only for '-a' or '-A' */
+struct ctlname procname[] = { {0, 0}, {"curproc", CTLTYPE_NODE} };
+
char names[BUFSIZ];
struct list {
@@ -141,6 +145,7 @@
#endif
{ username, USER_MAXID }, /* CTL_USER_NAMES */
{ ddbname, DDBCTL_MAXID }, /* CTL_DDB_NAMES */
+ { procname, 2 }, /* dummy name */
};
int Aflag, aflag, nflag, wflag;
@@ -152,6 +157,11 @@
#define BOOTTIME 0x00000002
#define CONSDEV 0x00000004
+/*
+ * A dummy type for limits, which requires special parsing
+ */
+#define CTLTYPE_LIMIT ((~0x1) << 31)
+
int main __P((int, char *[]));
static void listall __P((char *, struct list *));
@@ -167,6 +177,7 @@
static int sysctl_vfs __P((char *, char **, int[], int, int *));
static int sysctl_vfsgen __P((char *, char **, int[], int, int *));
static int sysctl_mbuf __P((char *, char **, int[], int, int *));
+static int sysctl_proc __P((char *, char **, int[], int, int *));
static int findname __P((char *, char *, char **, struct list *));
static void usage __P((void));
@@ -279,21 +290,26 @@
mib[0] = indx;
if (indx == CTL_DEBUG)
debuginit();
- lp = &secondlevel[indx];
- if (lp->list == 0) {
- warnx("Class `%s' is not implemented",
- topname[indx].ctl_name);
- return;
- }
- if (bufp == NULL) {
- listall(topname[indx].ctl_name, lp);
- return;
+ if (mib[0] == CTL_PROC) {
+ type = CTLTYPE_NODE;
+ len = 1;
+ } else {
+ lp = &secondlevel[indx];
+ if (lp->list == 0) {
+ warnx("Class `%s' is not implemented",
+ topname[indx].ctl_name);
+ return;
+ }
+ if (bufp == NULL) {
+ listall(topname[indx].ctl_name, lp);
+ return;
+ }
+ if ((indx = findname(string, "second", &bufp, lp)) == -1)
+ return;
+ mib[1] = indx;
+ type = lp->list[indx].ctl_type;
+ len = 2;
}
- if ((indx = findname(string, "second", &bufp, lp)) == -1)
- return;
- mib[1] = indx;
- type = lp->list[indx].ctl_type;
- len = 2;
switch (mib[0]) {
case CTL_KERN:
@@ -423,7 +439,11 @@
case CTL_USER:
case CTL_DDB:
break;
-
+ case CTL_PROC:
+ len = sysctl_proc(string, &bufp, mib, flags, &type);
+ if (len < 0)
+ return;
+ break;
default:
warnx("Illegal top level value: %d", mib[0]);
return;
@@ -441,6 +461,14 @@
newsize = sizeof intval;
break;
+ case CTLTYPE_LIMIT:
+ if (strcmp(newval, "unlimited") == 0) {
+ quadval = RLIM_INFINITY;
+ newval = &quadval;
+ newsize = sizeof quadval;
+ break;
+ }
+ /* FALLTHROUGH */
case CTLTYPE_QUAD:
sscanf(newval, "%qd", (long long *)&quadval);
newval = &quadval;
@@ -526,6 +554,30 @@
}
return;
+ case CTLTYPE_LIMIT:
+#define PRINTF_LIMIT(lim) { \
+if ((lim) == RLIM_INFINITY) \
+ fprintf(stdout, "unlimited");\
+else \
+ fprintf(stdout, "%qd", (lim)); \
+}
+
+ if (newsize == 0) {
+ if (!nflag)
+ fprintf(stdout, "%s = ", string);
+ PRINTF_LIMIT((long long)(*(quad_t *)buf));
+ } else {
+ if (!nflag) {
+ fprintf(stdout, "%s: ", string);
+ PRINTF_LIMIT((long long)(*(quad_t *)buf));
+ fprintf(stdout, " -> ");
+ }
+ PRINTF_LIMIT((long long)(*(quad_t *)newval));
+ }
+ fprintf(stdout, "\n");
+ return;
+#undef PRINTF_LIMIT
+
case CTLTYPE_QUAD:
if (newsize == 0) {
if (!nflag)
@@ -897,9 +949,85 @@
return (3);
}
+struct ctlname procnames[] = PROC_PID_NAMES;
+struct list procvars = {procnames, PROC_PID_MAXID};
+struct ctlname proclimitnames[] = PROC_PID_LIMIT_NAMES;
+struct list proclimitvars = {proclimitnames, PROC_PID_LIMIT_MAXID};
+struct ctlname proclimittypenames[] = PROC_PID_LIMIT_TYPE_NAMES;
+struct list proclimittypevars = {proclimittypenames,
+ PROC_PID_LIMIT_TYPE_MAXID};
+/*
+ * handle kern.proc requests
+ */
+static int
+sysctl_proc(string, bufpp, mib, flags, typep)
+ char *string;
+ char **bufpp;
+ int mib[];
+ int flags;
+ int *typep;
+{
+ char *cp, name[BUFSIZ];
+ struct list *lp;
+ int indx;
+
+ if (*bufpp == NULL) {
+ strcpy(name, string);
+ cp = &name[strlen(name)];
+ *cp++ = '.';
+ strcpy(cp, "curproc");
+ parse (name, Aflag);
+ return (-1);
+ }
+ cp = strsep(bufpp, ".");
+ if (cp == NULL) {
+ warnx("%s: incomplete specification", string);
+ return (-1);
+ }
+ if (strcmp(cp, "curproc") == 0) {
+ mib[1] = PROC_CURPROC;
+ } else {
+ mib[1] = atoi(cp);
+ if (mib[1] == 0) {
+ warnx("second level name %s in %s is invalid", cp,
+ string);
+ return (-1);
+ }
+ }
+ *typep = CTLTYPE_NODE;
+ lp = &procvars;
+ if (*bufpp == NULL) {
+ listall(string, lp);
+ return (-1);
+ }
+ if ((indx = findname(string, "third", bufpp, lp)) == -1)
+ return (-1);
+ mib[2] = indx;
+ *typep = lp->list[indx].ctl_type;
+ if (*typep != CTLTYPE_NODE)
+ return(3);
+ lp = &proclimitvars;
+ if (*bufpp == NULL) {
+ listall(string, lp);
+ return (-1);
+ }
+ if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
+ return (-1);
+ mib[3] = indx;
+ lp = &proclimittypevars;
+ if (*bufpp == NULL) {
+ listall(string, lp);
+ return (-1);
+ }
+ if ((indx = findname(string, "fifth", bufpp, lp)) == -1)
+ return (-1);
+ mib[4] = indx;
+ *typep = CTLTYPE_LIMIT;
+ return(5);
+}
+
struct ctlname mbufnames[] = CTL_MBUF_NAMES;
struct list mbufvars = { mbufnames, MBUF_MAXID };
-
/*
* handle kern.mbuf requests
*/
--RnlQjJ0d97Da+TV1--