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.