1 #include <pthread.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <rpc/rpc.h>
6 #include <arpa/inet.h>
7 
8 #define PROGNUM 1234
9 #define VERSNUM 1
10 #define PROCNUM 1
11 #define PROCQUIT 2
12 
13 static int exitcode;
14 
15 struct rpc_arg
16 {
17   CLIENT *client;
18   u_long proc;
19 };
20 
21 static void
dispatch(struct svc_req * request,SVCXPRT * xprt)22 dispatch(struct svc_req *request, SVCXPRT *xprt)
23 {
24   svc_sendreply(xprt, (xdrproc_t)xdr_void, 0);
25   if (request->rq_proc == PROCQUIT)
26     exit (0);
27 }
28 
29 static void
test_one_call(struct rpc_arg * a)30 test_one_call (struct rpc_arg *a)
31 {
32   struct timeval tout = { 60, 0 };
33   enum clnt_stat result;
34 
35   printf ("test_one_call: ");
36   result = clnt_call (a->client, a->proc,
37 		      (xdrproc_t) xdr_void, 0,
38 		      (xdrproc_t) xdr_void, 0, tout);
39   if (result == RPC_SUCCESS)
40     puts ("success");
41   else
42     {
43       clnt_perrno (result);
44       putchar ('\n');
45       exitcode = 1;
46     }
47 }
48 
49 static void *
thread_wrapper(void * arg)50 thread_wrapper (void *arg)
51 {
52   struct rpc_arg a;
53 
54   a.client = (CLIENT *)arg;
55   a.proc = PROCNUM;
56   test_one_call (&a);
57   a.client = (CLIENT *)arg;
58   a.proc = PROCQUIT;
59   test_one_call (&a);
60   return 0;
61 }
62 
63 int
main(void)64 main (void)
65 {
66   pthread_t tid;
67   pid_t pid;
68   int err;
69   SVCXPRT *svx;
70   CLIENT *clnt;
71   struct sockaddr_in sin;
72   struct timeval wait = { 5, 0 };
73   int sock = RPC_ANYSOCK;
74   struct rpc_arg a;
75 
76   svx = svcudp_create (RPC_ANYSOCK);
77   svc_register (svx, PROGNUM, VERSNUM, dispatch, 0);
78 
79   pid = fork ();
80   if (pid == -1)
81     {
82       perror ("fork");
83       return 1;
84     }
85   if (pid == 0)
86     svc_run ();
87 
88   inet_aton ("127.0.0.1", &sin.sin_addr);
89   sin.sin_port = htons (svx->xp_port);
90   sin.sin_family = AF_INET;
91 
92   clnt = clntudp_create (&sin, PROGNUM, VERSNUM, wait, &sock);
93 
94   a.client = clnt;
95   a.proc = PROCNUM;
96 
97   /* Test in this thread */
98   test_one_call (&a);
99 
100   /* Test in a child thread */
101   err = pthread_create (&tid, 0, thread_wrapper, (void *) clnt);
102   if (err)
103     fprintf (stderr, "pthread_create: %s\n", strerror (err));
104   err = pthread_join (tid, 0);
105   if (err)
106     fprintf (stderr, "pthread_join: %s\n", strerror (err));
107 
108   return exitcode;
109 }
110