+
+/*
+ * determine if one process (cur_procp) can trace another process (traced_procp).
+ */
+
+int
+cantrace(proc_t cur_procp, kauth_cred_t creds, proc_t traced_procp, int *errp)
+{
+ int my_err;
+ /*
+ * You can't trace a process if:
+ * (1) it's the process that's doing the tracing,
+ */
+ if (traced_procp->p_pid == cur_procp->p_pid) {
+ *errp = EINVAL;
+ return (0);
+ }
+
+ /*
+ * (2) it's already being traced, or
+ */
+ if (ISSET(traced_procp->p_flag, P_TRACED)) {
+ *errp = EBUSY;
+ return (0);
+ }
+
+ /*
+ * (3) it's not owned by you, or is set-id on exec
+ * (unless you're root).
+ */
+ if ((creds->cr_ruid != proc_ucred(traced_procp)->cr_ruid ||
+ ISSET(traced_procp->p_flag, P_SUGID)) &&
+ (my_err = suser(creds, &cur_procp->p_acflag)) != 0) {
+ *errp = my_err;
+ return (0);
+ }
+
+ if ((cur_procp->p_flag & P_TRACED) && isinferior(cur_procp, traced_procp)) {
+ *errp = EPERM;
+ return (0);
+ }
+
+ if (ISSET(traced_procp->p_flag, P_NOATTACH)) {
+ *errp = EBUSY;
+ return (0);
+ }
+ return(1);
+}