我是使用rpcgen编程的新手。我创建了一个简单的rpc程序,它在Ubuntu 14.04中提供远程目录列表服务。它使用rpcgen不仅可以生成存根例程,还可以生成XDR例程。
首先是协议文件
const MAXNAMELEM = 255;
typedef string nametype<MAXNAMELEM>; /*a directory entry*/
typedef struct namenode *namelist; /*a link in the listing*/
/*a node in the directory listing*/
struct namenode {
nametype name; /*name of directory entry*/
namelist next; /*next entry*/
};
/*the result of READDIR operation*/
union readdir_res switch (int errornumber) {
case 0:
namelist list; /*no error: return directory listing*/
default:
void; /*error occurred: nothing else to return*/
};
/*the directory program definition*/
program DIRPROG {
version DIRVERS {
readdir_res READDIR(nametype) = 1;
} = 1;
} = 76;
服务器:
#include <rpc/rpc.h>
#include <sys/dir.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "rdir.h"
readdir_res *readdir_1_svc(nametype *dirname, struct svc_req *req)
{
DIR *dirp = NULL;
struct direct *d = NULL;
namelist nl;
namelist *nlp = NULL;
static readdir_res res; /*must be static*/
/*open directory*/
dirp = opendir(*dirname);
if (dirp == NULL)
{
res.errornumber = errno;
return (&res);
}
/*Free previous result*/
xdr_free(xdr_readdir_res, &res);
nlp = &res.readdir_res_u.list;
while (d = readdir(dirp))
{
nl = *nlp = (namenode*)malloc(sizeof(namenode));
nl->name = strdup(d->d_name);
nlp = &nl->next;
}
*nlp = NULL;
res.errornumber = 0;
closedir(dirp);
return (&res);
}
客户:
#include <stdio.h>
#include <rpc/rpc.h>
#include "rdir.h"
int main(int argc, char *argv[])
{
CLIENT *cl;
char *server = NULL;
char *dir = NULL;
readdir_res *result = NULL;
namelist nl;
if (argc != 3)
{
fprintf(stderr, "usage: %s host directory\n", argv[0]);
exit(1);
}
/*remember what our command line arguments refer to*/
server = argv[1];
dir = argv[2];
cl = clnt_create(server, DIRPROG, DIRVERS, "tcp");
if (cl == NULL)
{
clnt_pcreateerror(server);
exit(1);
}
result = readdir_1(&dir, cl);
if (result == NULL)
{
clnt_perror(cl, server);
exit(1);
}
if (result->errornumber != 0)
{
perror(dir);
exit(1);
}
for (nl = result->readdir_res_u.list; nl!=NULL; nl=nl->next)
{
printf("%s\n", nl->name);
}
return 0;
}
然后我编译它们:
rpcgen rdir.x
gcc rls.c rdir_clnt.c rdir_xdr.c -o rls
gcc rdir_svc.c dir_proc.c rdir_xdr.c -o dir_svc
当我用指令编译时:
gcc rdir_svc.c dir_proc.c rdir_xdr.c -o dir_svc
我收到了以下警告:
esta@esta-U48L:~/Learning/rpcgen/dir_ls$ gcc rdir_svc.c dir_proc.c rdir_xdr.c -o dir_svc
dir_proc.c: In function ‘readdir_1_svc’:
dir_proc.c:27:2: warning: passing argument 1 of ‘xdr_free’ from incompatible pointer type [enabled by default]
xdr_free(xdr_readdir_res, &res);
^
In file included from /usr/include/rpc/rpc.h:42:0,
from dir_proc.c:1:
/usr/include/rpc/xdr.h:373:13: note: expected ‘xdrproc_t’ but argument is of type ‘bool_t (*)(struct XDR *, struct readdir_res *)’
extern void xdr_free (xdrproc_t __proc, char *__objp) __THROW;
^
dir_proc.c:27:2: warning: passing argument 2 of ‘xdr_free’ from incompatible pointer type [enabled by default]
xdr_free(xdr_readdir_res, &res);
^
In file included from /usr/include/rpc/rpc.h:42:0,
from dir_proc.c:1:
/usr/include/rpc/xdr.h:373:13: note: expected ‘char *’ but argument is of type ‘struct readdir_res *’
extern void xdr_free (xdrproc_t __proc, char *__objp) __THROW;
^
有人可以帮我解决警告吗? 附:即使有这些警告,程序运行也很好。
答案 0 :(得分:0)
您可以安全地将传递的参数转换为xdr_free
:
xdr_free((xdrproc_t)xdr_readdir_res, (char *)&res);