41 #include <sys/resource.h>
50 static struct fdleaks {
56 unsigned int isopen:1;
57 } fdleaks[1024] = { {
"", }, };
59 #define COPY(dst, src) \
61 int dlen = sizeof(dst), slen = strlen(src); \
62 if (slen + 1 > dlen) { \
63 char *slash = strrchr(src, '/'); \
65 ast_copy_string(dst, slash + 1, dlen); \
67 ast_copy_string(dst, src + slen - dlen + 1, dlen); \
70 ast_copy_string(dst, src, dlen); \
74 #define STORE_COMMON(offset, name, ...) \
75 COPY(fdleaks[offset].file, file); \
76 fdleaks[offset].line = line; \
77 COPY(fdleaks[offset].function, func); \
78 strcpy(fdleaks[offset].callname, name); \
79 snprintf(fdleaks[offset].callargs, sizeof(fdleaks[offset].callargs), __VA_ARGS__); \
80 fdleaks[offset].isopen = 1;
83 int __ast_fdleak_open(
const char *file,
int line,
const char *func,
const char *path,
int flags, ...)
89 if (flags & O_CREAT) {
91 mode = va_arg(ap,
int);
93 res = open(path, flags, mode);
94 if (res > -1 && res < (
sizeof(fdleaks) /
sizeof(fdleaks[0]))) {
96 snprintf(sflags,
sizeof(sflags),
"O_CREAT%s%s%s%s%s%s%s%s",
97 flags & O_APPEND ?
"|O_APPEND" :
"",
98 flags & O_EXCL ?
"|O_EXCL" :
"",
99 flags & O_NONBLOCK ?
"|O_NONBLOCK" :
"",
100 flags & O_TRUNC ?
"|O_TRUNC" :
"",
101 flags & O_RDWR ?
"|O_RDWR" :
"",
103 !(flags & (O_WRONLY | O_RDWR)) ?
"|O_RDONLY" :
"",
105 flags & O_RDONLY ?
"|O_RDONLY" :
"",
107 flags & O_WRONLY ?
"|O_WRONLY" :
"",
109 flags &= ~(O_CREAT | O_APPEND | O_EXCL | O_NONBLOCK | O_TRUNC | O_RDWR | O_RDONLY | O_WRONLY);
111 STORE_COMMON(res,
"open",
"\"%s\",%s|%d,%04o", path, sflags, flags, mode);
113 STORE_COMMON(res,
"open",
"\"%s\",%s,%04o", path, sflags, mode);
117 res = open(path, flags);
118 if (res > -1 && res < (
sizeof(fdleaks) /
sizeof(fdleaks[0]))) {
119 STORE_COMMON(res,
"open",
"\"%s\",%d", path, flags);
126 int __ast_fdleak_pipe(
int *fds,
const char *file,
int line,
const char *func)
128 int i, res = pipe(fds);
132 for (i = 0; i < 2; i++) {
133 STORE_COMMON(fds[i],
"pipe",
"{%d,%d}", fds[0], fds[1]);
139 int __ast_fdleak_socket(
int domain,
int type,
int protocol,
const char *file,
int line,
const char *func)
141 char sdomain[20], stype[20], *sproto = NULL;
143 int res = socket(domain, type, protocol);
144 if (res < 0 || res > 1023) {
148 if ((pe = getprotobynumber(protocol))) {
152 if (domain == PF_UNIX) {
154 }
else if (domain == PF_INET) {
157 snprintf(sdomain,
sizeof(sdomain),
"%d", domain);
160 if (type == SOCK_DGRAM) {
165 }
else if (type == SOCK_STREAM) {
171 snprintf(stype,
sizeof(stype),
"%d", type);
175 STORE_COMMON(res,
"socket",
"%s,%s,\"%s\"", sdomain, stype, sproto);
177 STORE_COMMON(res,
"socket",
"%s,%s,\"%d\"", sdomain, stype, protocol);
183 int __ast_fdleak_close(
int fd)
186 if (!res && fd > -1 && fd < 1024) {
187 fdleaks[fd].isopen = 0;
193 FILE *__ast_fdleak_fopen(
const char *path,
const char *mode,
const char *file,
int line,
const char *func)
195 FILE *res = fopen(path, mode);
201 STORE_COMMON(fd,
"fopen",
"\"%s\",\"%s\"", path, mode);
206 int __ast_fdleak_fclose(FILE *ptr)
214 if ((res = fclose(ptr)) || fd < 0 || fd > 1023) {
217 fdleaks[fd].isopen = 0;
222 int __ast_fdleak_dup2(
int oldfd,
int newfd,
const char *file,
int line,
const char *func)
224 int res = dup2(oldfd, newfd);
225 if (res < 0 || res > 1023) {
228 STORE_COMMON(res,
"dup2",
"%d,%d", oldfd, newfd);
233 int __ast_fdleak_dup(
int oldfd,
const char *file,
int line,
const char *func)
235 int res = dup(oldfd);
236 if (res < 0 || res > 1023) {
239 STORE_COMMON(res,
"dup2",
"%d", oldfd);
252 "Usage: core show fd\n"
253 " List all file descriptors currently in use and where\n"
254 " each was opened, and with what command.\n";
259 getrlimit(RLIMIT_FSIZE, &rl);
260 if (rl.rlim_cur == RLIM_INFINITY || rl.rlim_max == RLIM_INFINITY) {
263 snprintf(line,
sizeof(line),
"%d/%d", (
int) rl.rlim_cur, (
int) rl.rlim_max);
265 ast_cli(a->
fd,
"Current maxfiles: %s\n", line);
266 for (i = 0; i < 1024; i++) {
267 if (fdleaks[i].isopen) {
268 snprintf(line,
sizeof(line),
"%d", fdleaks[i].line);
269 ast_cli(a->
fd,
"%5d %15s:%-7.7s (%-25s): %s(%s)\n", i, fdleaks[i].file, line, fdleaks[i].function, fdleaks[i].callname, fdleaks[i].callargs);
277 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.
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
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.
void ast_cli(int fd, const char *fmt,...)
Handle unaligned data access.
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
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.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.