Sat Apr 26 2014 22:03:19

Asterisk developer's documentation


strcompat.c File Reference

Compatibility functions for strsep and strtoq missing on Solaris. More...

#include "asterisk.h"
#include <ctype.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include "asterisk/utils.h"
Include dependency graph for strcompat.c:

Go to the source code of this file.

Functions

void closefrom (int n)
uint64_t htonll (uint64_t host64)
uint64_t ntohll (uint64_t net64)

Detailed Description

Compatibility functions for strsep and strtoq missing on Solaris.

.. and lots of other functions too.

Definition in file strcompat.c.


Function Documentation

void closefrom ( int  n)

Definition at line 426 of file strcompat.c.

References errno.

Referenced by ast_close_fds_above_n().

{
   long x;
   struct rlimit rl;
   DIR *dir;
   char path[16], *result;
   struct dirent *entry;

   snprintf(path, sizeof(path), "/proc/%d/fd", (int) getpid());
   if ((dir = opendir(path))) {
      while ((entry = readdir(dir))) {
         /* Skip . and .. */
         if (entry->d_name[0] == '.') {
            continue;
         }
         if ((x = strtol(entry->d_name, &result, 10)) && x >= n) {
#ifdef STRICT_COMPAT
            close(x);
#else
            /* This isn't strictly compatible, but it's actually faster
             * for our purposes to set the CLOEXEC flag than to close
             * file descriptors.
             */
            long flags = fcntl(x, F_GETFD);
            if (flags == -1 && errno == EBADF) {
               continue;
            }
            fcntl(x, F_SETFD, flags | FD_CLOEXEC);
#endif
         }
      }
      closedir(dir);
   } else {
      getrlimit(RLIMIT_NOFILE, &rl);
      if (rl.rlim_cur > 65535) {
         /* A more reasonable value.  Consider that the primary source of
          * file descriptors in Asterisk are UDP sockets, of which we are
          * limited to 65,535 per address.  We additionally limit that down
          * to about 10,000 sockets per protocol.  While the kernel will
          * allow us to set the fileno limit higher (up to 4.2 billion),
          * there really is no practical reason for it to be that high.
          */
         rl.rlim_cur = 65535;
      }
      for (x = n; x < rl.rlim_cur; x++) {
#ifdef STRICT_COMPAT
         close(x);
#else
         long flags = fcntl(x, F_GETFD);
         if (flags == -1 && errno == EBADF) {
            continue;
         }
         fcntl(x, F_SETFD, flags | FD_CLOEXEC);
#endif
      }
   }
}
uint64_t htonll ( uint64_t  host64)

Definition at line 387 of file strcompat.c.

Referenced by iax_ie_append_versioned_uint64().

{
#if BYTE_ORDER == BIG_ENDIAN
   return host64;
#elif BYTE_ORDER == LITTLE_ENDIAN
   union {
      unsigned char c[8];
      uint64_t u;
   } number;
   number.u = host64;
   return
      (((uint64_t) number.c[0]) << 56) |
      (((uint64_t) number.c[1]) << 48) |
      (((uint64_t) number.c[2]) << 40) |
      (((uint64_t) number.c[3]) << 32) |
      (((uint64_t) number.c[4]) << 24) |
      (((uint64_t) number.c[5]) << 16) |
      (((uint64_t) number.c[6]) <<  8) |
      (((uint64_t) number.c[7]) <<  0);
#else
   #error "Unknown byte order"
#endif
}
uint64_t ntohll ( uint64_t  net64)

Definition at line 361 of file strcompat.c.

Referenced by dump_versioned_codec(), and iax_parse_ies().

{
#if BYTE_ORDER == BIG_ENDIAN
   return net64;
#elif BYTE_ORDER == LITTLE_ENDIAN
   union {
      unsigned char c[8];
      uint64_t u;
   } number;
   number.u = net64;
   return
      (((uint64_t) number.c[0]) << 56) |
      (((uint64_t) number.c[1]) << 48) |
      (((uint64_t) number.c[2]) << 40) |
      (((uint64_t) number.c[3]) << 32) |
      (((uint64_t) number.c[4]) << 24) |
      (((uint64_t) number.c[5]) << 16) |
      (((uint64_t) number.c[6]) <<  8) |
      (((uint64_t) number.c[7]) <<  0);
#else
   #error "Unknown byte order"
#endif
}