33#include "exec_cmd.h"
44#include "run-command.h"
55#include "strbuf.h"
6+ #include "string-list.h"
67
78#include <syslog.h>
89
@@ -734,11 +735,17 @@ static int set_reuse_addr(int sockfd)
734735 & on , sizeof (on ));
735736}
736737
738+ struct socketlist {
739+ int * list ;
740+ size_t nr ;
741+ size_t alloc ;
742+ };
743+
737744#ifndef NO_IPV6
738745
739- static int socksetup (char * listen_addr , int listen_port , int * * socklist_p )
746+ static int setup_named_sock (char * listen_addr , int listen_port , struct socketlist * socklist )
740747{
741- int socknum = 0 , * socklist = NULL ;
748+ int socknum = 0 ;
742749 int maxfd = -1 ;
743750 char pbuf [NI_MAXSERV ];
744751 struct addrinfo hints , * ai0 , * ai ;
@@ -753,8 +760,10 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
753760 hints .ai_flags = AI_PASSIVE ;
754761
755762 gai = getaddrinfo (listen_addr , pbuf , & hints , & ai0 );
756- if (gai )
757- die ("getaddrinfo() failed: %s" , gai_strerror (gai ));
763+ if (gai ) {
764+ logerror ("getaddrinfo() for %s failed: %s" , listen_addr , gai_strerror (gai ));
765+ return 0 ;
766+ }
758767
759768 for (ai = ai0 ; ai ; ai = ai -> ai_next ) {
760769 int sockfd ;
@@ -795,22 +804,22 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
795804 if (flags >= 0 )
796805 fcntl (sockfd , F_SETFD , flags | FD_CLOEXEC );
797806
798- socklist = xrealloc (socklist , sizeof (int ) * (socknum + 1 ));
799- socklist [socknum ++ ] = sockfd ;
807+ ALLOC_GROW (socklist -> list , socklist -> nr + 1 , socklist -> alloc );
808+ socklist -> list [socklist -> nr ++ ] = sockfd ;
809+ socknum ++ ;
800810
801811 if (maxfd < sockfd )
802812 maxfd = sockfd ;
803813 }
804814
805815 freeaddrinfo (ai0 );
806816
807- * socklist_p = socklist ;
808817 return socknum ;
809818}
810819
811820#else /* NO_IPV6 */
812821
813- static int socksetup (char * listen_addr , int listen_port , int * * socklist_p )
822+ static int setup_named_sock (char * listen_addr , int listen_port , struct socketlist * socklist )
814823{
815824 struct sockaddr_in sin ;
816825 int sockfd ;
@@ -851,22 +860,39 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
851860 if (flags >= 0 )
852861 fcntl (sockfd , F_SETFD , flags | FD_CLOEXEC );
853862
854- * socklist_p = xmalloc ( sizeof ( int ) );
855- * * socklist_p = sockfd ;
863+ ALLOC_GROW ( socklist -> list , socklist -> nr + 1 , socklist -> alloc );
864+ socklist -> list [ socklist -> nr ++ ] = sockfd ;
856865 return 1 ;
857866}
858867
859868#endif
860869
861- static int service_loop (int socknum , int * socklist )
870+ static void socksetup (struct string_list * listen_addr , int listen_port , struct socketlist * socklist )
871+ {
872+ if (!listen_addr -> nr )
873+ setup_named_sock (NULL , listen_port , socklist );
874+ else {
875+ int i , socknum ;
876+ for (i = 0 ; i < listen_addr -> nr ; i ++ ) {
877+ socknum = setup_named_sock (listen_addr -> items [i ].string ,
878+ listen_port , socklist );
879+
880+ if (socknum == 0 )
881+ logerror ("unable to allocate any listen sockets for host %s on port %u" ,
882+ listen_addr -> items [i ].string , listen_port );
883+ }
884+ }
885+ }
886+
887+ static int service_loop (struct socketlist * socklist )
862888{
863889 struct pollfd * pfd ;
864890 int i ;
865891
866- pfd = xcalloc (socknum , sizeof (struct pollfd ));
892+ pfd = xcalloc (socklist -> nr , sizeof (struct pollfd ));
867893
868- for (i = 0 ; i < socknum ; i ++ ) {
869- pfd [i ].fd = socklist [i ];
894+ for (i = 0 ; i < socklist -> nr ; i ++ ) {
895+ pfd [i ].fd = socklist -> list [i ];
870896 pfd [i ].events = POLLIN ;
871897 }
872898
@@ -877,7 +903,7 @@ static int service_loop(int socknum, int *socklist)
877903
878904 check_dead_children ();
879905
880- if (poll (pfd , socknum , -1 ) < 0 ) {
906+ if (poll (pfd , socklist -> nr , -1 ) < 0 ) {
881907 if (errno != EINTR ) {
882908 logerror ("Poll failed, resuming: %s" ,
883909 strerror (errno ));
@@ -886,7 +912,7 @@ static int service_loop(int socknum, int *socklist)
886912 continue ;
887913 }
888914
889- for (i = 0 ; i < socknum ; i ++ ) {
915+ for (i = 0 ; i < socklist -> nr ; i ++ ) {
890916 if (pfd [i ].revents & POLLIN ) {
891917 struct sockaddr_storage ss ;
892918 unsigned int sslen = sizeof (ss );
@@ -946,27 +972,27 @@ static void store_pid(const char *path)
946972 die_errno ("failed to write pid file '%s'" , path );
947973}
948974
949- static int serve (char * listen_addr , int listen_port , struct passwd * pass , gid_t gid )
975+ static int serve (struct string_list * listen_addr , int listen_port , struct passwd * pass , gid_t gid )
950976{
951- int socknum , * socklist ;
977+ struct socketlist socklist = { NULL , 0 , 0 } ;
952978
953- socknum = socksetup (listen_addr , listen_port , & socklist );
954- if (socknum == 0 )
955- die ("unable to allocate any listen sockets on host %s port %u" ,
956- listen_addr , listen_port );
979+ socksetup (listen_addr , listen_port , & socklist );
980+ if (socklist . nr == 0 )
981+ die ("unable to allocate any listen sockets on port %u" ,
982+ listen_port );
957983
958984 if (pass && gid &&
959985 (initgroups (pass -> pw_name , gid ) || setgid (gid ) ||
960986 setuid (pass -> pw_uid )))
961987 die ("cannot drop privileges" );
962988
963- return service_loop (socknum , socklist );
989+ return service_loop (& socklist );
964990}
965991
966992int main (int argc , char * * argv )
967993{
968994 int listen_port = 0 ;
969- char * listen_addr = NULL ;
995+ struct string_list listen_addr = STRING_LIST_INIT_NODUP ;
970996 int inetd_mode = 0 ;
971997 const char * pid_file = NULL , * user_name = NULL , * group_name = NULL ;
972998 int detach = 0 ;
@@ -981,7 +1007,7 @@ int main(int argc, char **argv)
9811007 char * arg = argv [i ];
9821008
9831009 if (!prefixcmp (arg , "--listen=" )) {
984- listen_addr = xstrdup_tolower (arg + 9 );
1010+ string_list_append ( & listen_addr , xstrdup_tolower (arg + 9 ) );
9851011 continue ;
9861012 }
9871013 if (!prefixcmp (arg , "--port=" )) {
@@ -1106,7 +1132,7 @@ int main(int argc, char **argv)
11061132 if (inetd_mode && (group_name || user_name ))
11071133 die ("--user and --group are incompatible with --inetd" );
11081134
1109- if (inetd_mode && (listen_port || listen_addr ))
1135+ if (inetd_mode && (listen_port || ( listen_addr . nr > 0 ) ))
11101136 die ("--listen= and --port= are incompatible with --inetd" );
11111137 else if (listen_port == 0 )
11121138 listen_port = DEFAULT_GIT_PORT ;
@@ -1161,5 +1187,5 @@ int main(int argc, char **argv)
11611187 if (pid_file )
11621188 store_pid (pid_file );
11631189
1164- return serve (listen_addr , listen_port , pass , gid );
1190+ return serve (& listen_addr , listen_port , pass , gid );
11651191}
0 commit comments