diff options
Diffstat (limited to 'contrib/netbsd-tests/lib/libc/rpc/t_rpc.c')
-rw-r--r-- | contrib/netbsd-tests/lib/libc/rpc/t_rpc.c | 279 |
1 files changed, 266 insertions, 13 deletions
diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c index a9715cf..28a8763 100644 --- a/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c +++ b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c @@ -1,18 +1,19 @@ -/* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */ +/* $NetBSD: t_rpc.c,v 1.9 2015/11/27 13:59:40 christos Exp $ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $"); +__RCSID("$NetBSD: t_rpc.c,v 1.9 2015/11/27 13:59:40 christos Exp $"); #include <sys/types.h> #include <sys/socket.h> #include <rpc/rpc.h> #include <stdlib.h> +#include <string.h> #include <err.h> #include <netdb.h> #include <stdio.h> +#include <errno.h> #include <unistd.h> - #ifndef TEST #include <atf-c.h> @@ -23,11 +24,24 @@ __RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $"); return; \ } while(/*CONSTCOND*/0) +#ifdef __FreeBSD__ +#define SKIPXI(ev, msg, ...) do { \ + atf_tc_skip(msg, __VA_ARGS__); \ + return ev; \ +} while(/*CONSTCOND*/0) +#endif + #else #define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) #define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) #endif +#ifdef DEBUG +#define DPRINTF(...) printf(__VA_ARGS__) +#else +#define DPRINTF(...) +#endif + #define RPCBPROC_NULL 0 @@ -51,7 +65,7 @@ reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) #define __rpc_control rpc_control #endif -extern bool __rpc_control(int, void *); +extern bool_t __rpc_control(int, void *); static void onehost(const char *host, const char *transp) @@ -86,9 +100,146 @@ onehost(const char *host, const char *transp) reply(NULL, &addr, NULL); } +#define PROGNUM 0x81 +#define VERSNUM 0x01 +#define PLUSONE 1 +#define DESTROY 2 + +static struct timeval tout = {1, 0}; + +static void +server(struct svc_req *rqstp, SVCXPRT *transp) +{ + int num; + + DPRINTF("Starting server\n"); + + switch (rqstp->rq_proc) { + case NULLPROC: + if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) + ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 0); + return; + case PLUSONE: + break; + case DESTROY: + if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) + ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 0); + svc_destroy(transp); + exit(0); + default: + svcerr_noproc(transp); + return; + } + + if (!svc_getargs(transp, (xdrproc_t)xdr_int, (void *)&num)) { + svcerr_decode(transp); + return; + } + DPRINTF("About to increment\n"); + num++; + if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (void *)&num)) + ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 1); + DPRINTF("Leaving server procedure.\n"); +} + +static int +rawtest(const char *arg) +{ + CLIENT *clnt; + SVCXPRT *svc; + int num, resp; + enum clnt_stat rv; + + if (arg) + num = atoi(arg); + else + num = 0; + + svc = svc_raw_create(); + if (svc == NULL) + ERRX(EXIT_FAILURE, "Cannot create server %d", num); + if (!svc_reg(svc, PROGNUM, VERSNUM, server, NULL)) + ERRX(EXIT_FAILURE, "Cannot register server %d", num); + + clnt = clnt_raw_create(PROGNUM, VERSNUM); + if (clnt == NULL) + ERRX(EXIT_FAILURE, "%s", + clnt_spcreateerror("clnt_raw_create")); + rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, + (xdrproc_t)xdr_int, (void *)&resp, tout); + if (rv != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); + DPRINTF("Got %d\n", resp); + clnt_destroy(clnt); + svc_destroy(svc); + if (++num != resp) + ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); + + return EXIT_SUCCESS; +} + +static int +regtest(const char *hostname, const char *transp, const char *arg, int p) +{ + CLIENT *clnt; + int num, resp; + enum clnt_stat rv; + pid_t pid; + + if (arg) + num = atoi(arg); + else + num = 0; + +#ifdef __NetBSD__ + svc_fdset_init(p ? SVC_FDSET_POLL : 0); +#endif + if (!svc_create(server, PROGNUM, VERSNUM, transp)) +#ifdef __NetBSD__ + ERRX(EXIT_FAILURE, "Cannot create server %d", num); +#else + { + SKIPXI(EXIT_FAILURE, "Cannot create server %d", num); + } +#endif + + switch ((pid = fork())) { + case 0: + DPRINTF("Calling svc_run\n"); + svc_run(); + ERRX(EXIT_FAILURE, "svc_run returned %d!", num); + case -1: + ERRX(EXIT_FAILURE, "Fork failed (%s)", strerror(errno)); + default: + sleep(1); + break; + } + + DPRINTF("Initializing client\n"); + clnt = clnt_create(hostname, PROGNUM, VERSNUM, transp); + if (clnt == NULL) + ERRX(EXIT_FAILURE, "%s", + clnt_spcreateerror("clnt_raw_create")); + rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, + (xdrproc_t)xdr_int, (void *)&resp, tout); + if (rv != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); + DPRINTF("Got %d\n", resp); + if (++num != resp) + ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); + rv = clnt_call(clnt, DESTROY, (xdrproc_t)xdr_void, NULL, + (xdrproc_t)xdr_void, NULL, tout); + if (rv != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); + clnt_destroy(clnt); + + return EXIT_SUCCESS; +} + + #ifdef TEST static void -allhosts(void) +allhosts(const char *transp) { enum clnt_stat clnt_stat; @@ -103,28 +254,49 @@ int main(int argc, char *argv[]) { int ch; + int s, p; const char *transp = "udp"; - - while ((ch = getopt(argc, argv, "ut")) != -1) + p = s = 0; + while ((ch = getopt(argc, argv, "prstu")) != -1) switch (ch) { + case 'p': + p = 1; + break; + case 's': + s = 1; + break; case 't': transp = "tcp"; break; case 'u': transp = "udp"; break; + case 'r': + transp = NULL; + break; default: - fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n", + fprintf(stderr, + "Usage: %s -[r|s|t|u] [<hostname>...]\n", getprogname()); return EXIT_FAILURE; } - if (argc == optind) - allhosts(); - else - for (; optind < argc; optind++) - onehost(argv[optind], transp); + if (argc == optind) { + if (transp) + allhosts(transp); + else + rawtest(NULL); + } else { + for (; optind < argc; optind++) { + if (transp) + s == 0 ? + onehost(argv[optind], transp) : + regtest(argv[optind], transp, "1", p); + else + rawtest(argv[optind]); + } + } return EXIT_SUCCESS; } @@ -156,10 +328,91 @@ ATF_TC_BODY(get_svc_addr_udp, tc) } +ATF_TC(raw); +ATF_TC_HEAD(raw, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc raw"); +} + +ATF_TC_BODY(raw, tc) +{ +#ifdef __FreeBSD__ + atf_tc_expect_fail("fails with: clnt_call: " + "RPC: Can't decode result -- PR # 211804"); +#endif + rawtest(NULL); + +} + +ATF_TC(tcp); +ATF_TC_HEAD(tcp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc tcp (select)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(tcp, tc) +{ + regtest("localhost", "tcp", "1", 0); + +} + +ATF_TC(udp); +ATF_TC_HEAD(udp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc udp (select)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(udp, tc) +{ + regtest("localhost", "udp", "1", 0); + +} + +ATF_TC(tcp_poll); +ATF_TC_HEAD(tcp_poll, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc tcp (poll)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(tcp_poll, tc) +{ + regtest("localhost", "tcp", "1", 1); + +} + +ATF_TC(udp_poll); +ATF_TC_HEAD(udp_poll, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc udp (poll)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(udp_poll, tc) +{ + regtest("localhost", "udp", "1", 1); + +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, get_svc_addr_udp); ATF_TP_ADD_TC(tp, get_svc_addr_tcp); + ATF_TP_ADD_TC(tp, raw); + ATF_TP_ADD_TC(tp, tcp); + ATF_TP_ADD_TC(tp, udp); + ATF_TP_ADD_TC(tp, tcp_poll); + ATF_TP_ADD_TC(tp, udp_poll); return atf_no_error(); } |