39#include <sys/resource.h> 
   50static struct fdleaks {
 
   53    unsigned int isopen:1;
 
   58} fdleaks[1024] = { { 
"", }, };
 
   65#define COPY(dst, src)                                             \ 
   67        int dlen = sizeof(dst), slen = strlen(src);                \ 
   68        if (slen + 1 > dlen) {                                     \ 
   69            const char *slash = strrchr(src, '/');                 \ 
   71                ast_copy_string(dst, slash + 1, dlen);             \ 
   73                ast_copy_string(dst, src + slen - dlen + 1, dlen); \ 
   76            ast_copy_string(dst, src, dlen);                       \ 
   80#define STORE_COMMON(offset, name, ...)     \ 
   82        struct fdleaks *tmp = &fdleaks[offset]; \ 
   83        tmp->now = ast_tvnow(); \ 
   84        COPY(tmp->file, file);      \ 
   86        COPY(tmp->function, func);  \ 
   87        tmp->callname = name;       \ 
   88        snprintf(tmp->callargs, sizeof(tmp->callargs), __VA_ARGS__); \ 
   93int __ast_fdleak_open(
const char *file, 
int line, 
const char *func, 
const char *path, 
int flags, ...)
 
   99    if (flags & O_CREAT) {
 
  101        mode = va_arg(ap, 
int);
 
  103        res = open(path, flags, mode);
 
  104        if (res > -1 && res < 
ARRAY_LEN(fdleaks)) {
 
  106            snprintf(sflags, 
sizeof(sflags), 
"O_CREAT%s%s%s%s%s%s%s%s",
 
  107                flags & O_APPEND ? 
"|O_APPEND" : 
"",
 
  108                flags & O_EXCL ? 
"|O_EXCL" : 
"",
 
  109                flags & O_NONBLOCK ? 
"|O_NONBLOCK" : 
"",
 
  110                flags & O_TRUNC ? 
"|O_TRUNC" : 
"",
 
  111                flags & O_RDWR ? 
"|O_RDWR" : 
"",
 
  113                !(flags & (O_WRONLY | O_RDWR)) ? 
"|O_RDONLY" : 
"",
 
  115                flags & O_RDONLY ? 
"|O_RDONLY" : 
"",
 
  117                flags & O_WRONLY ? 
"|O_WRONLY" : 
"",
 
  119            flags &= ~(O_CREAT | O_APPEND | O_EXCL | O_NONBLOCK | O_TRUNC | O_RDWR | O_RDONLY | O_WRONLY);
 
  121                STORE_COMMON(res, 
"open", 
"\"%s\",%s|%d,%04o", path, sflags, flags, mode);
 
  123                STORE_COMMON(res, 
"open", 
"\"%s\",%s,%04o", path, sflags, mode);
 
  127        res = open(path, flags);
 
  128        if (res > -1 && res < 
ARRAY_LEN(fdleaks)) {
 
  129            STORE_COMMON(res, 
"open", 
"\"%s\",%d", path, flags);
 
  136int __ast_fdleak_accept(
int socket, 
struct sockaddr *
address, socklen_t *address_len,
 
  137    const char *file, 
int line, 
const char *func)
 
  139    int res = accept(socket, 
address, address_len);
 
  142        STORE_COMMON(res, 
"accept", 
"{%d}", socket);
 
  149int __ast_fdleak_pipe(
int *fds, 
const char *file, 
int line, 
const char *func)
 
  151    int i, res = pipe(fds);
 
  155    for (i = 0; i < 2; i++) {
 
  156        if (fds[i] > -1 && fds[i] < 
ARRAY_LEN(fdleaks)) {
 
  157            STORE_COMMON(fds[i], 
"pipe", 
"{%d,%d}", fds[0], fds[1]);
 
  164int __ast_fdleak_socketpair(
int domain, 
int type, 
int protocol, 
int sv[2],
 
  165    const char *file, 
int line, 
const char *func)
 
  167    int i, res = socketpair(domain, 
type, protocol, sv);
 
  171    for (i = 0; i < 2; i++) {
 
  172        if (sv[i] > -1 && sv[i] < 
ARRAY_LEN(fdleaks)) {
 
  173            STORE_COMMON(sv[i], 
"socketpair", 
"{%d,%d}", sv[0], sv[1]);
 
  179#if defined(HAVE_EVENTFD) 
  181#include <sys/eventfd.h> 
  182int __ast_fdleak_eventfd(
unsigned int initval, 
int flags, 
const char *file, 
int line, 
const char *func)
 
  184    int res = eventfd(initval, flags);
 
  187        STORE_COMMON(res, 
"eventfd", 
"{%d}", res);
 
  194#if defined(HAVE_TIMERFD) 
  196#include <sys/timerfd.h> 
  197int __ast_fdleak_timerfd_create(
int clockid, 
int flags, 
const char *file, 
int line, 
const char *func)
 
  199    int res = timerfd_create(clockid, flags);
 
  202        STORE_COMMON(res, 
"timerfd_create", 
"{%d}", res);
 
  210int __ast_fdleak_socket(
int domain, 
int type, 
int protocol, 
const char *file, 
int line, 
const char *func)
 
  212    char sdomain[20], stype[20], *sproto = 
NULL;
 
  214    int res = socket(domain, 
type, protocol);
 
  215    if (res < 0 || res >= 
ARRAY_LEN(fdleaks)) {
 
  219    if ((pe = getprotobynumber(protocol))) {
 
  223    if (domain == PF_UNIX) {
 
  225    } 
else if (domain == PF_INET) {
 
  228        snprintf(sdomain, 
sizeof(sdomain), 
"%d", domain);
 
  231    if (
type == SOCK_DGRAM) {
 
  236    } 
else if (
type == SOCK_STREAM) {
 
  242        snprintf(stype, 
sizeof(stype), 
"%d", 
type);
 
  246        STORE_COMMON(res, 
"socket", 
"%s,%s,\"%s\"", sdomain, stype, sproto);
 
  248        STORE_COMMON(res, 
"socket", 
"%s,%s,\"%d\"", sdomain, stype, protocol);
 
  254int __ast_fdleak_close(
int fd)
 
  257    if (!res && fd > -1 && fd < 
ARRAY_LEN(fdleaks)) {
 
  258        fdleaks[fd].isopen = 0;
 
  264FILE *__ast_fdleak_fopen(
const char *path, 
const char *mode, 
const char *file, 
int line, 
const char *func)
 
  266    FILE *res = fopen(path, mode);
 
  272    if (fd > -1 && fd < 
ARRAY_LEN(fdleaks)) {
 
  273        STORE_COMMON(fd, 
"fopen", 
"\"%s\",\"%s\"", path, mode);
 
  279int __ast_fdleak_fclose(FILE *ptr)
 
  288    if ((res = fclose(ptr)) || fd < 0 || fd >= 
ARRAY_LEN(fdleaks)) {
 
  291    fdleaks[fd].isopen = 0;
 
  296int __ast_fdleak_dup2(
int oldfd, 
int newfd, 
const char *file, 
int line, 
const char *func)
 
  298    int res = dup2(oldfd, newfd);
 
  299    if (res < 0 || res >= 
ARRAY_LEN(fdleaks)) {
 
  305    STORE_COMMON(res, 
"dup2", 
"%d,%d", oldfd, newfd); 
 
  310int __ast_fdleak_dup(
int oldfd, 
const char *file, 
int line, 
const char *func)
 
  312    int res = dup(oldfd);
 
  313    if (res < 0 || res >= 
ARRAY_LEN(fdleaks)) {
 
  316    STORE_COMMON(res, 
"dup2", 
"%d", oldfd);
 
  329            "Usage: core show fd\n" 
  330            "       List all file descriptors currently in use and where\n" 
  331            "       each was opened, and with what command.\n";
 
  336    getrlimit(RLIMIT_NOFILE, &rl);
 
  337    if (rl.rlim_cur == RLIM_INFINITY) {
 
  340        snprintf(line, 
sizeof(line), 
"%d", (
int) rl.rlim_cur);
 
  342    ast_cli(
a->fd, 
"Current maxfiles: %s\n", line);
 
  343    for (i = 0; i < 
ARRAY_LEN(fdleaks); i++) {
 
  344        if (fdleaks[i].isopen) {
 
  346            char datestring[256];
 
  349            ast_strftime(datestring, 
sizeof(datestring), 
"%F %T", &tm);
 
  350            snprintf(line, 
sizeof(line), 
"%d", fdleaks[i].line);
 
  351            ast_cli(
a->fd, 
"%5d [%s] %22s:%-7.7s (%-25s): %s(%s)\n", i, datestring, fdleaks[i].file, line, fdleaks[i].function, fdleaks[i].callname, fdleaks[i].callargs);
 
  359static void fd_shutdown(
void)
 
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Standard Command Line Interface.
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
#define ast_cli_register(e)
Registers a command or an array of commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
Support for logging to various files, console and syslog Configuration in file logger....
Custom localtime functions for multiple timezones.
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Asterisk locking-related definitions:
Options provided by main asterisk program.
String manipulation functions.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
descriptor for a cli entry.
Time-related functions and macros.
Handle unaligned data access.