thrsvc.c 2.0 KB

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