3
3
#include "exec_cmd.h"
4
4
#include "run-command.h"
5
5
#include "strbuf.h"
6
+ #include "string-list.h"
6
7
7
8
#include <syslog.h>
8
9
@@ -734,11 +735,17 @@ static int set_reuse_addr(int sockfd)
734
735
& on , sizeof (on ));
735
736
}
736
737
738
+ struct socketlist {
739
+ int * list ;
740
+ size_t nr ;
741
+ size_t alloc ;
742
+ };
743
+
737
744
#ifndef NO_IPV6
738
745
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 )
740
747
{
741
- int socknum = 0 , * socklist = NULL ;
748
+ int socknum = 0 ;
742
749
int maxfd = -1 ;
743
750
char pbuf [NI_MAXSERV ];
744
751
struct addrinfo hints , * ai0 , * ai ;
@@ -753,8 +760,10 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
753
760
hints .ai_flags = AI_PASSIVE ;
754
761
755
762
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
+ }
758
767
759
768
for (ai = ai0 ; ai ; ai = ai -> ai_next ) {
760
769
int sockfd ;
@@ -795,22 +804,22 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
795
804
if (flags >= 0 )
796
805
fcntl (sockfd , F_SETFD , flags | FD_CLOEXEC );
797
806
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 ++ ;
800
810
801
811
if (maxfd < sockfd )
802
812
maxfd = sockfd ;
803
813
}
804
814
805
815
freeaddrinfo (ai0 );
806
816
807
- * socklist_p = socklist ;
808
817
return socknum ;
809
818
}
810
819
811
820
#else /* NO_IPV6 */
812
821
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 )
814
823
{
815
824
struct sockaddr_in sin ;
816
825
int sockfd ;
@@ -851,22 +860,39 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
851
860
if (flags >= 0 )
852
861
fcntl (sockfd , F_SETFD , flags | FD_CLOEXEC );
853
862
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 ;
856
865
return 1 ;
857
866
}
858
867
859
868
#endif
860
869
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 )
862
888
{
863
889
struct pollfd * pfd ;
864
890
int i ;
865
891
866
- pfd = xcalloc (socknum , sizeof (struct pollfd ));
892
+ pfd = xcalloc (socklist -> nr , sizeof (struct pollfd ));
867
893
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 ];
870
896
pfd [i ].events = POLLIN ;
871
897
}
872
898
@@ -877,7 +903,7 @@ static int service_loop(int socknum, int *socklist)
877
903
878
904
check_dead_children ();
879
905
880
- if (poll (pfd , socknum , -1 ) < 0 ) {
906
+ if (poll (pfd , socklist -> nr , -1 ) < 0 ) {
881
907
if (errno != EINTR ) {
882
908
logerror ("Poll failed, resuming: %s" ,
883
909
strerror (errno ));
@@ -886,7 +912,7 @@ static int service_loop(int socknum, int *socklist)
886
912
continue ;
887
913
}
888
914
889
- for (i = 0 ; i < socknum ; i ++ ) {
915
+ for (i = 0 ; i < socklist -> nr ; i ++ ) {
890
916
if (pfd [i ].revents & POLLIN ) {
891
917
struct sockaddr_storage ss ;
892
918
unsigned int sslen = sizeof (ss );
@@ -946,27 +972,27 @@ static void store_pid(const char *path)
946
972
die_errno ("failed to write pid file '%s'" , path );
947
973
}
948
974
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 )
950
976
{
951
- int socknum , * socklist ;
977
+ struct socketlist socklist = { NULL , 0 , 0 } ;
952
978
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 );
957
983
958
984
if (pass && gid &&
959
985
(initgroups (pass -> pw_name , gid ) || setgid (gid ) ||
960
986
setuid (pass -> pw_uid )))
961
987
die ("cannot drop privileges" );
962
988
963
- return service_loop (socknum , socklist );
989
+ return service_loop (& socklist );
964
990
}
965
991
966
992
int main (int argc , char * * argv )
967
993
{
968
994
int listen_port = 0 ;
969
- char * listen_addr = NULL ;
995
+ struct string_list listen_addr = STRING_LIST_INIT_NODUP ;
970
996
int inetd_mode = 0 ;
971
997
const char * pid_file = NULL , * user_name = NULL , * group_name = NULL ;
972
998
int detach = 0 ;
@@ -981,7 +1007,7 @@ int main(int argc, char **argv)
981
1007
char * arg = argv [i ];
982
1008
983
1009
if (!prefixcmp (arg , "--listen=" )) {
984
- listen_addr = xstrdup_tolower (arg + 9 );
1010
+ string_list_append ( & listen_addr , xstrdup_tolower (arg + 9 ) );
985
1011
continue ;
986
1012
}
987
1013
if (!prefixcmp (arg , "--port=" )) {
@@ -1106,7 +1132,7 @@ int main(int argc, char **argv)
1106
1132
if (inetd_mode && (group_name || user_name ))
1107
1133
die ("--user and --group are incompatible with --inetd" );
1108
1134
1109
- if (inetd_mode && (listen_port || listen_addr ))
1135
+ if (inetd_mode && (listen_port || ( listen_addr . nr > 0 ) ))
1110
1136
die ("--listen= and --port= are incompatible with --inetd" );
1111
1137
else if (listen_port == 0 )
1112
1138
listen_port = DEFAULT_GIT_PORT ;
@@ -1161,5 +1187,5 @@ int main(int argc, char **argv)
1161
1187
if (pid_file )
1162
1188
store_pid (pid_file );
1163
1189
1164
- return serve (listen_addr , listen_port , pass , gid );
1190
+ return serve (& listen_addr , listen_port , pass , gid );
1165
1191
}
0 commit comments