about summary refs log tree commit diff
path: root/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'sunrpc')
-rw-r--r--sunrpc/Makefile8
-rw-r--r--sunrpc/thrsvc.c89
2 files changed, 96 insertions, 1 deletions
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index b7858d6c89..dd21ddf102 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1994,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
+# Copyright (C) 1994-2001, 2002 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -84,6 +84,10 @@ all: # Make this the default target; it will be defined in Rules.
 
 include ../Makeconfig
 
+ifeq ($(have-thread-library),yes)
+xtests += thrsvc
+endif
+
 ifeq (yes,$(build-static-nss))
 otherlibs += $(nssobjdir)/libnss_files.a $(resolvobjdir)/libnss_dns.a \
 	     $(resolvobjdir)/libresolv.a
@@ -178,3 +182,5 @@ $(objpfx)rpc-proto.c: $(rpcsvc:%=rpcsvc/%)
 	  echo '#include <rpc/rpc.h>'; \
 	  sed -n '/^%#include/s/%//p' $^; } > $@T
 	mv -f $@T $@
+
+$(objpfx)thrsvc: $(shared-thread-library)
diff --git a/sunrpc/thrsvc.c b/sunrpc/thrsvc.c
new file mode 100644
index 0000000000..ac6af09f5b
--- /dev/null
+++ b/sunrpc/thrsvc.c
@@ -0,0 +1,89 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <arpa/inet.h>
+
+#define PROGNUM 1234
+#define VERSNUM 1
+#define PROCNUM 1
+
+static int exitcode;
+
+static void
+dispatch(struct svc_req *request, SVCXPRT *xprt)
+{
+    svc_sendreply(xprt, (xdrproc_t)xdr_void, 0);
+}
+
+static void
+test_one_call (CLIENT *c)
+{
+  struct timeval tout = { 60, 0 };
+  enum clnt_stat result;
+
+  printf ("test_one_call: ");
+  result = clnt_call (c, PROCNUM,
+		      (xdrproc_t) xdr_void, 0,
+		      (xdrproc_t) xdr_void, 0, tout);
+  if (result == RPC_SUCCESS)
+    puts ("success");
+  else
+    {
+      clnt_perrno (result);
+      putchar ('\n');
+      exitcode = 1;
+    }
+}
+
+static void *
+thread_wrapper (void *arg)
+{
+  test_one_call ((CLIENT *)arg);
+  return 0;
+}
+
+int
+main (void)
+{
+  pthread_t tid;
+  pid_t pid;
+  int err;
+  SVCXPRT *svx;
+  CLIENT *clnt;
+  struct sockaddr_in sin;
+  struct timeval wait = { 5, 0 };
+  int sock = RPC_ANYSOCK;
+
+  svx = svcudp_create (RPC_ANYSOCK);
+  svc_register (svx, PROGNUM, VERSNUM, dispatch, 0);
+
+  pid = fork ();
+  if (pid == -1)
+    {
+      perror ("fork");
+      return 1;
+    }
+  if (pid == 0)
+    svc_run ();
+
+  inet_aton ("127.0.0.1", &sin.sin_addr);
+  sin.sin_port = htons (svx->xp_port);
+  sin.sin_family = AF_INET;
+
+  clnt = clntudp_create (&sin, PROGNUM, VERSNUM, wait, &sock);
+
+  /* Test in this thread */
+  test_one_call (clnt);
+
+  /* Test in a child thread */
+  err = pthread_create (&tid, 0, thread_wrapper, (void *) clnt);
+  if (err)
+    fprintf (stderr, "pthread_create: %s\n", strerror (err));
+  err = pthread_join (tid, 0);
+  if (err)
+    fprintf (stderr, "pthread_join: %s\n", strerror (err));
+
+  return exitcode;
+}