utils: Return status 0 on clean exits
[nfs-utils.git] / utils / mountd / svc_run.c
1 /*
2  * Copyright (C) 1984 Sun Microsystems, Inc.
3  * Based on svc_run.c from statd which claimed:
4  * Modified by Jeffrey A. Uphoff, 1995, 1997-1999.
5  * Modified by Olaf Kirch, 1996.
6  *
7  */
8
9 /* 
10  * Copyright (c) 2009, Sun Microsystems, Inc.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  * - Redistributions of source code must retain the above copyright notice,
16  *   this list of conditions and the following disclaimer.
17  * - Redistributions in binary form must reproduce the above copyright notice,
18  *   this list of conditions and the following disclaimer in the documentation
19  *   and/or other materials provided with the distribution.
20  * - Neither the name of Sun Microsystems, Inc. nor the names of its
21  *   contributors may be used to endorse or promote products derived
22  *   from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36
37 /* 
38  * Allow svc_run to listen to other file descriptors as well
39  */
40
41 /* 
42  * This is the RPC server side idle loop.
43  * Wait for input, call server program.
44  */
45
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49
50 #include <sys/types.h>
51 #include <rpc/rpc.h>
52 #include "xlog.h"
53 #include <errno.h>
54 #include <time.h>
55
56 #ifdef HAVE_LIBTIRPC
57 #include <rpc/rpc_com.h>
58 #endif
59
60 void cache_set_fds(fd_set *fdset);
61 int cache_process_req(fd_set *readfds);
62
63 #if LONG_MAX != INT_MAX 
64 /* bug in glibc 2.3.6 and earlier, we need
65  * our own svc_getreqset
66  */
67 static void
68 my_svc_getreqset (fd_set *readfds)
69 {
70         fd_mask mask;
71         fd_mask *maskp;
72         int setsize;
73         int sock;
74         int bit;
75
76         setsize = _rpc_dtablesize ();
77         if (setsize > FD_SETSIZE)
78                 setsize = FD_SETSIZE;
79         maskp = readfds->fds_bits;
80         for (sock = 0; sock < setsize; sock += NFDBITS)
81                 for (mask = *maskp++;
82                      (bit = ffsl (mask));
83                      mask ^= (1L << (bit - 1)))
84                         svc_getreq_common (sock + bit - 1);
85 }
86 #define svc_getreqset my_svc_getreqset
87
88 #endif
89
90 /*
91  * The heart of the server.  A crib from libc for the most part...
92  */
93 void
94 my_svc_run(void)
95 {
96         fd_set  readfds;
97         int     selret;
98
99         for (;;) {
100
101                 readfds = svc_fdset;
102                 cache_set_fds(&readfds);
103
104                 selret = select(FD_SETSIZE, &readfds,
105                                 (void *) 0, (void *) 0, (struct timeval *) 0);
106
107
108                 switch (selret) {
109                 case -1:
110                         if (errno == EINTR || errno == ECONNREFUSED
111                          || errno == ENETUNREACH || errno == EHOSTUNREACH)
112                                 continue;
113                         xlog(L_ERROR, "my_svc_run() - select: %m");
114                         return;
115
116                 default:
117                         selret -= cache_process_req(&readfds);
118                         if (selret)
119                                 svc_getreqset(&readfds);
120                 }
121         }
122 }