So, after initial input, here is improved version. Changelist:

  - Simplified handling of "matched" variable in sysctl_file(),
    from kettenis@.

  - ERRORS section for kvm_getfiles.2 (to be committed separately),
    requested by bluhm@. I also moved beginning of RETURN VALUES
    section a bit up, IMHO, that makes more sense; but if any
    our documentation maintainer will object, I'll revert, of course.

Okay to commit this version?

--
WBR,
  Vadim Zhukov


Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.300
diff -u -p -r1.300 kern_sysctl.c
--- sys/kern/kern_sysctl.c      29 Feb 2016 19:44:07 -0000      1.300
+++ sys/kern/kern_sysctl.c      3 May 2016 19:40:37 -0000
@@ -1225,7 +1225,7 @@ sysctl_file(int *name, u_int namelen, ch
        struct process *pr;
        size_t buflen, elem_size, elem_count, outsize;
        char *dp = where;
-       int arg, i, error = 0, needed = 0;
+       int arg, i, error = 0, needed = 0, matched;
        u_int op;
        int show_pointers;
 
@@ -1325,6 +1325,7 @@ sysctl_file(int *name, u_int namelen, ch
                        error = EINVAL;
                        break;
                }
+               matched = 0;
                LIST_FOREACH(pr, &allprocess, ps_list) {
                        /*
                         * skip system, exiting, embryonic and undead
@@ -1336,6 +1337,7 @@ sysctl_file(int *name, u_int namelen, ch
                                /* not the pid we are looking for */
                                continue;
                        }
+                       matched = 1;
                        fdp = pr->ps_fd;
                        if (pr->ps_textvp)
                                FILLIT(NULL, NULL, KERN_FILE_TEXT, 
pr->ps_textvp, pr);
@@ -1353,6 +1355,8 @@ sysctl_file(int *name, u_int namelen, ch
                                FILLIT(fp, fdp, i, NULL, pr);
                        }
                }
+               if (!matched)
+                       error = ESRCH;
                break;
        case KERN_FILE_BYUID:
                LIST_FOREACH(pr, &allprocess, ps_list) {
Index: lib/libkvm/kvm_file2.c
===================================================================
RCS file: /cvs/src/lib/libkvm/kvm_file2.c,v
retrieving revision 1.47
diff -u -p -r1.47 kvm_file2.c
--- lib/libkvm/kvm_file2.c      4 Sep 2015 02:58:14 -0000       1.47
+++ lib/libkvm/kvm_file2.c      3 May 2016 19:40:38 -0000
@@ -149,7 +149,7 @@ kvm_getfiles(kvm_t *kd, int op, int arg,
                        /* find size and alloc buffer */
                        rv = sysctl(mib, 6, NULL, &size, NULL, 0);
                        if (rv == -1) {
-                               if (kd->vmfd != -1)
+                               if (errno != ESRCH && kd->vmfd != -1)
                                        goto deadway;
                                _kvm_syserr(kd, kd->program, "kvm_getfiles");
                                return (NULL);
@@ -266,7 +266,7 @@ kvm_deadfile_byid(kvm_t *kd, int op, int
 {
        size_t buflen;
        struct nlist nl[4], *np;
-       int n = 0;
+       int n = 0, matched = 0;
        char *where;
        struct kinfo_file kf;
        struct file *fp, file;
@@ -312,6 +312,9 @@ kvm_deadfile_byid(kvm_t *kd, int op, int
        kd->filebase = (void *)where;
        buflen = (nfiles + 10) * esize;
 
+       if (op != KERN_FILE_BYPID || arg <= 0)
+               matched = 1;
+
        for (pr = LIST_FIRST(&allprocess);
            pr != NULL;
            pr = LIST_NEXT(&process, ps_list)) {
@@ -333,10 +336,12 @@ kvm_deadfile_byid(kvm_t *kd, int op, int
                        goto cleanup;
                }
 
-               if (op == KERN_FILE_BYPID && arg > 0 &&
-                   proc.p_pid != (pid_t)arg) {
-                               /* not the pid we are looking for */
+               if (op == KERN_FILE_BYPID) {
+                       /* check if this is the pid we are looking for */
+                       if (arg > 0 && proc.p_pid != (pid_t)arg)
                                continue;
+                       else
+                               matched = 1;
                }
 
                if (KREAD(kd, (u_long)process.ps_ucred, &ucred)) {
@@ -457,6 +462,10 @@ kvm_deadfile_byid(kvm_t *kd, int op, int
                        buflen -= esize;
                        n++;
                }
+       }
+       if (!matched) {
+               errno = ESRCH;
+               goto cleanup;
        }
 done:
        *cnt = n;
Index: lib/libkvm/kvm_getfiles.3
===================================================================
RCS file: /cvs/src/lib/libkvm/kvm_getfiles.3,v
retrieving revision 1.17
diff -u -p -r1.17 kvm_getfiles.3
--- lib/libkvm/kvm_getfiles.3   11 Feb 2015 03:03:08 -0000      1.17
+++ lib/libkvm/kvm_getfiles.3   3 May 2016 19:40:38 -0000
@@ -107,7 +107,7 @@ the kernel will only return the requeste
 each array entry and programs that use
 .Fn kvm_getfiles
 will continue to function without the need for recompilation.
-.Pp
+.Sh RETURN VALUES
 The files are returned as a contiguous array of
 .Vt kinfo_file
 structures.
@@ -118,11 +118,26 @@ This memory is owned by kvm and will be 
 and destroyed by
 .Fn kvm_close .
 Data should be copied out if it needs to be saved.
-.Sh RETURN VALUES
+.Pp
 .Fn kvm_getfiles
 will return
 .Dv NULL
 on failure.
+.Sh ERRORS
+.Fn kvm_getfiles
+will fail if:
+.Bl -tag width Er
+.It Bq Er ENOMEM
+Could not allocate enough memory for internal buffer.
+.It Bq Er ESRCH
+The
+.Fa op
+argument has
+.Dv KERN_FILE_BYPID
+value and the process specified by
+.Fa arg
+was not found.
+.El
 .Sh SEE ALSO
 .Xr kvm 3 ,
 .Xr kvm_geterr 3 ,

Reply via email to