mirror of
https://github.com/pissnet/pissircd.git
synced 2025-08-06 10:15:24 +01:00
I/O engine: track if a fd is a file or socket, needed for Windows.
This fixes a file descriptor leak in Windows that happened in the logging code. The most visible effect of this was if you had a log::maxsize set then on Windows you would see: "Max file size reached, starting new log file" Every other line, forever (and not actually starting a new log). fd_close() previously did not close the file descriptor of a file on Windows because on Windows it needs to call close() for a file and closesocket() for a socket, and it always did the latter. On *NIX it's more easy and you can just always close() any fd.
This commit is contained in:
parent
a44b1cb63e
commit
329f48334c
4 changed files with 46 additions and 13 deletions
|
@ -15,12 +15,13 @@ typedef struct fd_entry {
|
|||
void *data;
|
||||
time_t deadline;
|
||||
unsigned char is_open;
|
||||
unsigned char is_file;
|
||||
unsigned int backend_flags;
|
||||
} FDEntry;
|
||||
|
||||
extern MODVAR FDEntry fd_table[MAXCONNECTIONS + 1];
|
||||
|
||||
extern int fd_open(int fd, const char *desc);
|
||||
extern int fd_open(int fd, const char *desc, int file);
|
||||
extern void fd_close(int fd);
|
||||
extern int fd_unmap(int fd);
|
||||
extern void fd_unnotify(int fd);
|
||||
|
|
|
@ -108,7 +108,7 @@ static void unrealdns_sock_state_cb(void *data, ares_socket_t fd, int read, int
|
|||
*/
|
||||
static int unrealdns_sock_create_cb(ares_socket_t fd, int type, void *data)
|
||||
{
|
||||
fd_open(fd, "DNS Resolver Socket");
|
||||
fd_open(fd, "DNS Resolver Socket", 0);
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
52
src/fdlist.c
52
src/fdlist.c
|
@ -24,7 +24,13 @@
|
|||
*/
|
||||
FDEntry fd_table[MAXCONNECTIONS + 1];
|
||||
|
||||
int fd_open(int fd, const char *desc)
|
||||
/** Notify I/O engine that a file descriptor opened.
|
||||
* @param fd The file descriptor
|
||||
* @param desc Description for in the fd table
|
||||
* @param file Set to 1 if the fd is a file, 0 otherwise (eg: socket)
|
||||
* @returns The file descriptor 'fd' or -1 in case of fatal error.
|
||||
*/
|
||||
int fd_open(int fd, const char *desc, int file)
|
||||
{
|
||||
FDEntry *fde;
|
||||
|
||||
|
@ -46,6 +52,7 @@ int fd_open(int fd, const char *desc)
|
|||
fde->fd = fd;
|
||||
fde->is_open = 1;
|
||||
fde->backend_flags = 0;
|
||||
fde->is_file = file;
|
||||
strlcpy(fde->desc, desc, FD_DESC_SZ);
|
||||
|
||||
return fde->fd;
|
||||
|
@ -71,13 +78,16 @@ int fd_fileopen(const char *path, unsigned int flags)
|
|||
|
||||
snprintf(comment, sizeof comment, "File: %s", unreal_getfilename(pathbuf));
|
||||
|
||||
return fd_open(fd, comment);
|
||||
return fd_open(fd, comment, 1);
|
||||
}
|
||||
|
||||
int fd_unmap(int fd)
|
||||
/** Internal function to unmap and optionally close the fd.
|
||||
*/
|
||||
int fd_close_ex(int fd, int close_fd)
|
||||
{
|
||||
FDEntry *fde;
|
||||
unsigned int befl;
|
||||
int is_file = 0;
|
||||
|
||||
if ((fd < 0) || (fd >= MAXCONNECTIONS))
|
||||
{
|
||||
|
@ -105,6 +115,7 @@ int fd_unmap(int fd)
|
|||
}
|
||||
|
||||
befl = fde->backend_flags;
|
||||
is_file = fde->is_file;
|
||||
memset(fde, 0, sizeof(FDEntry));
|
||||
|
||||
fde->fd = fd;
|
||||
|
@ -112,16 +123,37 @@ int fd_unmap(int fd)
|
|||
/* only notify the backend if it is actively tracking the FD */
|
||||
if (befl)
|
||||
fd_refresh(fd);
|
||||
|
||||
|
||||
/* Finally, close the file or socket if requested to do so */
|
||||
if (close_fd)
|
||||
{
|
||||
if (is_file)
|
||||
close(fd);
|
||||
else
|
||||
CLOSE_SOCK(fd);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Unmap file descriptor.
|
||||
* That is: remove it from our list, but don't actually do any
|
||||
* close() or closesocket() call.
|
||||
* @param fd The file descriptor
|
||||
* @returns 1 on success, 0 on failure
|
||||
*/
|
||||
int fd_unmap(int fd)
|
||||
{
|
||||
return fd_close_ex(fd, 0);
|
||||
}
|
||||
|
||||
/** Close file descriptor.
|
||||
* That is: remove it from our list AND call close() or closesocket().
|
||||
* @param fd The file descriptor
|
||||
*/
|
||||
void fd_close(int fd)
|
||||
{
|
||||
if (!fd_unmap(fd))
|
||||
return;
|
||||
|
||||
CLOSE_SOCK(fd);
|
||||
fd_close_ex(fd, 1);
|
||||
}
|
||||
|
||||
/* Deregister I/O notification for this file descriptor */
|
||||
|
@ -150,7 +182,7 @@ int fd_socket(int family, int type, int protocol, const char *desc)
|
|||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
return fd_open(fd, desc);
|
||||
return fd_open(fd, desc, 0);
|
||||
}
|
||||
|
||||
int fd_accept(int sockfd)
|
||||
|
@ -162,7 +194,7 @@ int fd_accept(int sockfd)
|
|||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
return fd_open(fd, buf);
|
||||
return fd_open(fd, buf, 0);
|
||||
}
|
||||
|
||||
void fd_desc(int fd, const char *desc)
|
||||
|
|
|
@ -336,7 +336,7 @@ static int url_socket_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *so
|
|||
|
||||
if (!fde->is_open)
|
||||
{
|
||||
fd_open(s, "CURL transfer");
|
||||
fd_open(s, "CURL transfer", 0);
|
||||
}
|
||||
|
||||
if (what == CURL_POLL_IN || what == CURL_POLL_INOUT)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue