From bcbac913d65275cc9e22534a8b4cda6994b75977 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 29 Jul 2011 13:25:52 +0200 Subject: socketpair() usage tracking to allow fd leak detection --- lib/http_ntlm.c | 55 ++++++++++++++++++++++++++++--------------------------- lib/memdebug.c | 18 ++++++++++++++++++ lib/memdebug.h | 9 +++++++++ lib/urldata.h | 4 ++-- 4 files changed, 57 insertions(+), 29 deletions(-) (limited to 'lib') diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index 4163b8245..dc90604d7 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -680,20 +680,20 @@ static void unicodecpy(unsigned char *dest, #ifdef USE_NTLM_SSO static void sso_ntlm_close(struct connectdata *conn) { - if(conn->fd_helper != -1) { - close(conn->fd_helper); - conn->fd_helper = -1; + if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) { + sclose(conn->ntlm_auth_hlpr_socket); + conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; } - if(conn->pid) { - int ret, i; + if(conn->ntlm_auth_hlpr_pid) { + int i; for(i = 0; i < 4; i++) { - ret = waitpid(conn->pid, NULL, WNOHANG); - if(ret == conn->pid || errno == ECHILD) + pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG); + if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD) break; switch(i) { case 0: - kill(conn->pid, SIGTERM); + kill(conn->ntlm_auth_hlpr_pid, SIGTERM); break; case 1: /* Give the process another moment to shut down cleanly before @@ -701,13 +701,13 @@ static void sso_ntlm_close(struct connectdata *conn) Curl_wait_ms(1); break; case 2: - kill(conn->pid, SIGKILL); + kill(conn->ntlm_auth_hlpr_pid, SIGKILL); break; case 3: break; } } - conn->pid = 0; + conn->ntlm_auth_hlpr_pid = 0; } Curl_safefree(conn->challenge_header); @@ -719,8 +719,8 @@ static void sso_ntlm_close(struct connectdata *conn) static CURLcode sso_ntlm_initiate(struct connectdata *conn, const char *userp) { - int sockfds[2]; - pid_t pid; + curl_socket_t sockfds[2]; + pid_t child_pid; const char *username; char *slash, *domain = NULL; const char *ntlm_auth = NULL; @@ -728,9 +728,9 @@ static CURLcode sso_ntlm_initiate(struct connectdata *conn, int error; /* Return if communication with ntlm_auth already set up */ - if(conn->fd_helper != -1 || conn->pid) { + if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD || + conn->ntlm_auth_hlpr_pid) return CURLE_OK; - } username = userp; slash = strpbrk(username, "\\/"); @@ -768,21 +768,21 @@ static CURLcode sso_ntlm_initiate(struct connectdata *conn, goto done; } - pid = fork(); - if(pid == -1) { + child_pid = fork(); + if(child_pid == -1) { error = ERRNO; - close(sockfds[0]); - close(sockfds[1]); + sclose(sockfds[0]); + sclose(sockfds[1]); failf(conn->data, "Could not fork. errno %d: %s", error, Curl_strerror(conn, error)); goto done; } - else if(!pid) { + else if(!child_pid) { /* * child process */ - close(sockfds[0]); + sclose(sockfds[0]); if(dup2(sockfds[1], STDIN_FILENO) == -1) { error = ERRNO; @@ -813,14 +813,15 @@ static CURLcode sso_ntlm_initiate(struct connectdata *conn, NULL); error = ERRNO; + sclose(sockfds[1]); failf(conn->data, "Could not execl(). errno %d: %s", error, Curl_strerror(conn, error)); exit(1); } - close(sockfds[1]); - conn->fd_helper = sockfds[0]; - conn->pid = pid; + sclose(sockfds[1]); + conn->ntlm_auth_hlpr_socket = sockfds[0]; + conn->ntlm_auth_hlpr_pid = child_pid; Curl_safefree(domain); Curl_safefree(ntlm_auth_alloc); return CURLE_OK; @@ -840,7 +841,7 @@ static CURLcode sso_ntlm_response(struct connectdata *conn, size_t len_in = strlen(input), len_out = sizeof(buf); while(len_in > 0) { - ssize_t written = write(conn->fd_helper, input, len_in); + ssize_t written = write(conn->ntlm_auth_hlpr_socket, input, len_in); if(written == -1) { /* Interrupted by a signal, retry it */ if(errno == EINTR) @@ -853,7 +854,7 @@ static CURLcode sso_ntlm_response(struct connectdata *conn, } /* Read one line */ while(len_out > 0) { - size = read(conn->fd_helper, tmpbuf, len_out); + size = read(conn->ntlm_auth_hlpr_socket, tmpbuf, len_out); if(size == -1) { if(errno == EINTR) continue; @@ -946,8 +947,8 @@ CURLcode Curl_output_ntlm_sso(struct connectdata *conn, * handling process. */ /* Clean data before using them */ - conn->fd_helper = -1; - conn->pid = 0; + conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; + conn->ntlm_auth_hlpr_pid = 0; conn->challenge_header = NULL; conn->response_header = NULL; /* Create communication with ntlm_auth */ diff --git a/lib/memdebug.c b/lib/memdebug.c index 60d938ade..3e3c1bc4f 100644 --- a/lib/memdebug.c +++ b/lib/memdebug.c @@ -285,6 +285,24 @@ curl_socket_t curl_socket(int domain, int type, int protocol, return sockfd; } +#ifdef HAVE_SOCKETPAIR +int curl_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source) +{ + const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? + "FD %s:%d socketpair() = %d %d\n" : + (sizeof(curl_socket_t) == sizeof(long)) ? + "FD %s:%d socketpair() = %ld %ld\n" : + "FD %s:%d socketpair() = %zd %zd\n" ; + + int res = socketpair(domain, type, protocol, socket_vector); + if(source && (0 == res)) + curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]); + return res; +} +#endif + curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen, int line, const char *source) { diff --git a/lib/memdebug.h b/lib/memdebug.h index 3dc481577..b18bb39da 100644 --- a/lib/memdebug.h +++ b/lib/memdebug.h @@ -65,6 +65,11 @@ CURL_EXTERN int curl_sclose(curl_socket_t sockfd, int line , const char *source); CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen, int line, const char *source); +#ifdef HAVE_SOCKETPAIR +CURL_EXTERN int curl_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line , const char *source); +#endif /* FILE functions */ CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line, @@ -90,6 +95,10 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source); #undef accept /* for those with accept as a macro */ #define accept(sock,addr,len)\ curl_accept(sock,addr,len,__LINE__,__FILE__) +#ifdef HAVE_SOCKETPAIR +#define socketpair(domain,type,protocol,socket_vector)\ + curl_socketpair(domain,type,protocol,socket_vector,__LINE__,__FILE__) +#endif #ifdef HAVE_GETADDRINFO #if defined(getaddrinfo) && defined(__osf__) diff --git a/lib/urldata.h b/lib/urldata.h index d2638aa93..f4057cbbd 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -908,8 +908,8 @@ struct connectdata { #ifdef USE_NTLM_SSO /* data used for communication with Samba's winbind daemon helper ntlm_auth */ - int fd_helper; - pid_t pid; + curl_socket_t ntlm_auth_hlpr_socket; + pid_t ntlm_auth_hlpr_pid; char* challenge_header; char* response_header; #endif -- cgit v1.2.3