Index: systrace.c
===================================================================
RCS file: /cvs/src/sys/dev/systrace.c,v
retrieving revision 1.28
diff -u -r1.28 systrace.c
--- systrace.c	20 Feb 2003 22:03:31 -0000	1.28
+++ systrace.c	3 Jun 2003 03:20:55 -0000
@@ -139,6 +261,7 @@
 int	systrace_insert_process(struct fsystrace *, struct proc *);
 struct str_policy *systrace_newpolicy(struct fsystrace *, int);
 int	systrace_msg_child(struct fsystrace *, struct str_process *, pid_t);
+int	systrace_msg_policyfree(struct fsystrace *, struct str_policy *);
 int	systrace_msg_ask(struct fsystrace *, struct str_process *,
 	    int, size_t, register_t []);
 int	systrace_msg_result(struct fsystrace *, struct str_process *,
@@ -1375,8 +1536,23 @@
 	struct str_policy *pol;
 	int i;
 
-	if (fst->npolicies > SYSTR_MAX_POLICIES && !fst->issuser)
-		return (NULL);
+	if (fst->npolicies > SYSTR_MAX_POLICIES && !fst->issuser) {
+		struct str_policy *tmp;
+
+		/* Try to find a policy for freeing */
+		TAILQ_FOREACH(tmp, &fst->policies, next) {
+			if (tmp->refcount == 1)
+				break;
+		}
+
+		if (tmp == NULL)
+			return (NULL);
+
+		/* Notify userland about freed policy */
+		systrace_msg_policyfree(fst, tmp);
+		/* Free this policy */
+		systrace_closepolicy(fst, tmp);
+	}
 
 	pol = pool_get(&systr_policy_pl, PR_NOWAIT);
 	if (pol == NULL)
@@ -1491,7 +1667,7 @@
 	while (1) {
 		st = tsleep(strp, PWAIT | PCATCH, "systrmsg", 0);
 		if (st != 0)
-			return (EINTR);
+			return (ERESTART);
 		/* If we detach, then everything is permitted */
 		if ((strp = curproc->p_systrace) == NULL)
 			return (0);
@@ -1525,6 +1701,29 @@
 	else
 		msg->msg_policy = -1;
 	msg_child->new_pid = npid;
+
+	TAILQ_INSERT_TAIL(&fst->messages, nstrp, msg_next);
+
+	systrace_wakeup(fst);
+
+	return (0);
+}
+
+int
+systrace_msg_policyfree(struct fsystrace *fst, struct str_policy *strpol)
+{
+	struct str_process *nstrp;
+	struct str_message *msg;
+
+	nstrp = pool_get(&systr_proc_pl, PR_WAITOK);
+	memset(nstrp, 0, sizeof(struct str_process));
+
+	DPRINTF(("%s: free %d\n", __func__, strpol->nr));
+
+	msg = &nstrp->msg;
+
+	msg->msg_type = SYSTR_MSG_POLICYFREE;
+	msg->msg_policy = strpol->nr;
 
 	TAILQ_INSERT_TAIL(&fst->messages, nstrp, msg_next);
 
Index: systrace.h
===================================================================
RCS file: /cvs/src/sys/dev/systrace.h,v
retrieving revision 1.12
diff -u -r1.12 systrace.h
--- systrace.h	4 Dec 2002 17:37:39 -0000	1.12
+++ systrace.h	3 Jun 2003 03:19:37 -0000
@@ -65,14 +62,16 @@
 	pid_t new_pid;
 };
 
-#define SYSTR_MSG_ASK	1
-#define SYSTR_MSG_RES	2
-#define SYSTR_MSG_EMUL	3
-#define SYSTR_MSG_CHILD	4
-#define SYSTR_MSG_UGID	5
+#define SYSTR_MSG_ASK		1
+#define SYSTR_MSG_RES		2
+#define SYSTR_MSG_EMUL		3
+#define SYSTR_MSG_CHILD		4
+#define SYSTR_MSG_UGID		5
+#define SYSTR_MSG_POLICYFREE	6
 
 #define SYSTR_MSG_NOPROCESS(x) \
-	((x)->msg.msg_type == SYSTR_MSG_CHILD)
+	((x)->msg.msg_type == SYSTR_MSG_CHILD || \
+	 (x)->msg.msg_type == SYSTR_MSG_POLICYFREE)
 
 struct str_message {
 	int msg_type;
