Unfortunately, in 2 cases this diff will increase "needed" variable
for non existing files too. This is the fixed version.

Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.284
diff -u -p -r1.284 kern_sysctl.c
--- sys/kern/kern_sysctl.c      28 Mar 2015 23:50:55 -0000      1.284
+++ sys/kern/kern_sysctl.c      8 May 2015 17:08:24 -0000
@@ -1288,11 +1288,32 @@ sysctl_file(int *name, u_int namelen, ch
                        if (pr->ps_tracevp)
                                FILLIT(NULL, NULL, KERN_FILE_TRACE, 
pr->ps_tracevp, pr);
                        for (i = 0; i < fdp->fd_nfiles; i++) {
-                               if ((fp = fdp->fd_ofiles[i]) == NULL)
-                                       continue;
-                               if (!FILE_IS_USABLE(fp))
-                                       continue;
-                               FILLIT(fp, fdp, i, NULL, pr);
+                               if (buflen >= elem_size && elem_count > 0) {
+                                       fdplock(fdp);
+                                       fp = fd_getfile(fdp, i);
+                                       if (fp != NULL ) {
+                                               fdpunlock(fdp);
+                                               continue;
+                                       }
+                                       fill_file(kf, fp, fdp, i, NULL, NULL,
+                                           p, show_pointers);
+                                       fdpunlock(fdp);
+       
+                                       error = copyout(kf, dp, outsize);
+                                       if (error)
+                                               break;
+                                       dp += elem_size;
+                                       buflen -= elem_size;
+                                       elem_count--;
+                               } else {
+                                       fdplock(fdp);
+                                       fp = fd_getfile(fdp, i);
+                                       fdpunlock(fdp);
+
+                                       if (fp == NULL)
+                                               continue;
+                               }
+                               needed += elem_size;
                        }
                }
                break;
@@ -1316,11 +1337,32 @@ sysctl_file(int *name, u_int namelen, ch
                        if (pr->ps_tracevp)
                                FILLIT(NULL, NULL, KERN_FILE_TRACE, 
pr->ps_tracevp, pr);
                        for (i = 0; i < fdp->fd_nfiles; i++) {
-                               if ((fp = fdp->fd_ofiles[i]) == NULL)
-                                       continue;
-                               if (!FILE_IS_USABLE(fp))
-                                       continue;
-                               FILLIT(fp, fdp, i, NULL, pr);
+                               if (buflen >= elem_size && elem_count > 0) {
+                                       fdplock(fdp);
+                                       fp = fd_getfile(fdp, i);
+                                       if (fp != NULL ) {
+                                               fdpunlock(fdp);
+                                               continue;
+                                       }
+                                       fill_file(kf, fp, fdp, i, NULL, NULL,
+                                           p, show_pointers);
+                                       fdpunlock(fdp);
+       
+                                       error = copyout(kf, dp, outsize);
+                                       if (error)
+                                               break;
+                                       dp += elem_size;
+                                       buflen -= elem_size;
+                                       elem_count--;
+                               } else {
+                                       fdplock(fdp);
+                                       fp = fd_getfile(fdp, i);
+                                       fdpunlock(fdp);
+
+                                       if (fp == NULL)
+                                               continue;
+                               }
+                               needed += elem_size;
                        }
                }
                break;

Reply via email to