39 #include <sys/resource.h> 50 static 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__); \ 93 int __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);
136 int __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);
149 int __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]);
164 int __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> 182 int __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) 195 #undef timerfd_create 196 #include <sys/timerfd.h> 197 int __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);
210 int __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);
254 int __ast_fdleak_close(
int fd)
257 if (!res && fd > -1 && fd <
ARRAY_LEN(fdleaks)) {
258 fdleaks[fd].isopen = 0;
264 FILE *__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);
279 int __ast_fdleak_fclose(FILE *ptr)
287 if ((res = fclose(ptr)) || fd < 0 || fd >=
ARRAY_LEN(fdleaks)) {
290 fdleaks[fd].isopen = 0;
295 int __ast_fdleak_dup2(
int oldfd,
int newfd,
const char *file,
int line,
const char *func)
297 int res = dup2(oldfd, newfd);
298 if (res < 0 || res >=
ARRAY_LEN(fdleaks)) {
304 STORE_COMMON(res,
"dup2",
"%d,%d", oldfd, newfd);
309 int __ast_fdleak_dup(
int oldfd,
const char *file,
int line,
const char *func)
311 int res = dup(oldfd);
312 if (res < 0 || res >=
ARRAY_LEN(fdleaks)) {
315 STORE_COMMON(res,
"dup2",
"%d", oldfd);
328 "Usage: core show fd\n" 329 " List all file descriptors currently in use and where\n" 330 " each was opened, and with what command.\n";
335 getrlimit(RLIMIT_NOFILE, &rl);
336 if (rl.rlim_cur == RLIM_INFINITY) {
339 snprintf(line,
sizeof(line),
"%d", (
int) rl.rlim_cur);
341 ast_cli(a->
fd,
"Current maxfiles: %s\n", line);
342 for (i = 0; i <
ARRAY_LEN(fdleaks); i++) {
343 if (fdleaks[i].isopen) {
345 char datestring[256];
348 ast_strftime(datestring,
sizeof(datestring),
"%F %T", &tm);
349 snprintf(line,
sizeof(line),
"%d", fdleaks[i].line);
350 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);
358 static void fd_shutdown(
void)
#define AST_CLI_DEFINE(fn, txt,...)
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
String manipulation functions.
Time-related functions and macros.
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
descriptor for a cli entry.
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register(e)
Registers a command or an array of commands.
Custom localtime functions for multiple timezones.
Handle unaligned data access.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
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...
Support for logging to various files, console and syslog Configuration in file logger.conf.
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Options provided by main asterisk program.