Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6424394

(process) Consider dynamically detecting closefrom, fdwalk

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 6
    • core-libs
    • Fix Understood
    • generic
    • generic

      The Unix process native code is rather fragile, and despite fixes,
      some obscure problems remain.

      We've said in the past that we can't use closefrom(3) on Solaris
      because of its uncertain availability, but ...

      An anonymous SDN commenter rightly suggests that a dynamic lookup
      might be an excellent solution.

      You can have different implementations depending on which environment the application is running in. Below is an outline that uses fdwalk in where it is available but provides an alternative for other platforma such as solaris 8.


      /**
       * Pointer to fdwalk implementation. In Solaris 9 this points to the
       * solaris fdwalk implemenation and in Solaris 8 or other systems
       * where that isn't available it will point to the much less effective
       * my_fdwalk defined below.
       */
      static int (*fdwalkptr)(int(*)(void*,int), void*) = NULL;

      /**
       * Callback function for fdwalk
       */
      static int close_func(void *keepfdp, int fd)
      {
        if ( ! ( fd == ((int *) keepfdp)[0]
                || fd == ((int *) keepfdp)[1]
                || fd == ((int *) keepfdp)[2]))
        {
          (void) close(fd);
          return 0;
        }
      }

      /*
       * An alternative to fdwalk in solaris 8. It loops over all
       * available filedescriptors and calls func for each.
       */
      static int my_fdwalk(int (*func)(void *, int), void *cd)
      {
        struct rlimit rl;
        int i;

        // Get max no. of open files we can have
        getrlimit(RLIMIT_NOFILE, &rl);
        
        // loop over all of them
        for (i = 0; i < rl.rlim_max; i++)
        {
          (void) func(cd, i);
        }
        return 0;
      }



      /*
       * Library init function
       * Dynamically determines the fdwalk implementation to use
       */
      static void my_init()
      {
        // Try locate fdwalk
        void *handle = NULL;
        handle = dlopen("libmp.so", RTLD_LAZY);
        
        if (!handle)
        {
          fdwalkptr = &my_fdwalk;
        }
        else
        {
          // Try locate fdwalk
          fdwalkptr = (int (*)(int(*)(void*,int), void*))dlsym(handle,"fdwalk");
          if (!fdwalkptr)
          {
            dlclose(handle);
            handle= NULL;
            fdwalkptr = &my_fdwalk;
          }
        }
      }

      // Register library init function
      #pragma init (my_init)

            Unassigned Unassigned
            martin Martin Buchholz
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: