LCOV - code coverage report
Current view: top level - lib/cmdline - closefrom_except.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 30 40 75.0 %
Date: 2024-01-11 09:59:51 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  This program is free software; you can redistribute it and/or modify
       3             :  *  it under the terms of the GNU General Public License as published by
       4             :  *  the Free Software Foundation; either version 3 of the License, or
       5             :  *  (at your option) any later version.
       6             :  *
       7             :  *  This program is distributed in the hope that it will be useful,
       8             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       9             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10             :  *  GNU General Public License for more details.
      11             :  *
      12             :  *  You should have received a copy of the GNU General Public License
      13             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      14             :  */
      15             : 
      16             : #include "replace.h"
      17             : #include "closefrom_except.h"
      18             : #include <popt.h>
      19             : 
      20          40 : int closefrom_except(int lower, int *fds, size_t num_fds)
      21             : {
      22           0 :         size_t i;
      23          40 :         int max_keep = -1;
      24           0 :         int fd, ret;
      25             : 
      26         108 :         for (i=0; i<num_fds; i++) {
      27          68 :                 max_keep = MAX(max_keep, fds[i]);
      28             :         }
      29          40 :         if (max_keep == -1) {
      30          12 :                 return 0;
      31             :         }
      32             : 
      33         714 :         for (fd = lower; fd < max_keep; fd++) {
      34         686 :                 bool keep = false;
      35             : 
      36             :                 /*
      37             :                  * O(num_fds*max_keep), but we expect the number of
      38             :                  * fds to keep to be very small, typically 0,1,2 and
      39             :                  * very few more.
      40             :                  */
      41        2058 :                 for (i=0; i<num_fds; i++) {
      42        1372 :                         if (fd == fds[i]) {
      43           0 :                                 keep = true;
      44           0 :                                 break;
      45             :                         }
      46             :                 }
      47         686 :                 if (keep) {
      48           0 :                         continue;
      49             :                 }
      50         686 :                 ret = close(fd);
      51         686 :                 if ((ret == -1) && (errno != EBADF)) {
      52           0 :                         return errno;
      53             :                 }
      54             :         }
      55             : 
      56          28 :         closefrom(MAX(lower, max_keep+1));
      57          28 :         return 0;
      58             : }
      59             : 
      60          40 : int closefrom_except_fd_params(
      61             :         int lower,
      62             :         size_t num_fd_params,
      63             :         const char *fd_params[],
      64             :         int argc,
      65             :         const char *argv[])
      66          40 : {
      67          40 :         int fds[num_fd_params];
      68           0 :         size_t i;
      69          40 :         struct poptOption long_options[num_fd_params + 1];
      70           0 :         poptContext pc;
      71           0 :         int ret;
      72             : 
      73         108 :         for (i=0; i<num_fd_params; i++) {
      74          68 :                 fds[i] = -1;
      75          68 :                 long_options[i] = (struct poptOption) {
      76          68 :                         .longName = fd_params[i],
      77             :                         .argInfo = POPT_ARG_INT,
      78          68 :                         .arg = &fds[i],
      79             :                 };
      80             :         }
      81          40 :         long_options[num_fd_params] = (struct poptOption) { .longName=NULL, };
      82             : 
      83          40 :         pc = poptGetContext(argv[0], argc, argv, long_options, 0);
      84             : 
      85         212 :         while ((ret = poptGetNextOpt(pc)) != -1) {
      86             :                 /* do nothing */
      87           0 :         }
      88             : 
      89          40 :         poptFreeContext(pc);
      90             : 
      91          40 :         ret = closefrom_except(lower, fds, ARRAY_SIZE(fds));
      92          40 :         return ret;
      93             : }

Generated by: LCOV version 1.14