我正在开发一个带保险丝的自定义文件系统。我想要做的是从远程服务器读取目录的内容,并在挂载点列出它们。我的rpc程序运行得很好。但是当我尝试将它与rpc结合使用时,会出现一些构建错误。我正在使用rpcgen创建我的rpc程序,但我不知道我应该如何一起构建它们。
这是我的cfs_client.c:
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
gcc -Wall cfs.c `pkg-config fuse --cflags --libs` -o cfs
*/
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "cfs.h"
static const char *cfs_str = "Hello World!\n";
static const char *cfs_path = "/cfs";
static int cfs_getattr(const char *path, struct stat *stbuf) {
int res = 0;
memset(stbuf, 0, sizeof (struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, cfs_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(cfs_str);
} else
res = -ENOENT;
return res;
}
static int cfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi) {
(void) offset;
(void) fi;
char *host = "localhost";
char *dirname = "/home/hamed/test";
CLIENT *clnt;
readdir_res *result_1;
if (strcmp(path, "/") != 0)
return -ENOENT;
#ifndef DEBUG
clnt = clnt_create(host, CFSPROG, CFSVERS, "udp");
if (clnt == NULL) {
clnt_pcreateerror(host);
exit(1);
}
#endif /* DEBUG */
result_1 = readdir_1(&dirname, clnt);
if (result_1 == (readdir_res *) NULL) {
clnt_perror(clnt, "call failed");
}
namelist nl;
nl = result_1->readdir_res_u.list;
while (nl) {
printf("dirname = %s\n", nl->name);
filler(buf, nl->name, NULL, 0);
nl = nl->next;
}
#ifndef DEBUG
clnt_destroy(clnt);
#endif /* DEBUG */
return 0;
}
static int cfs_open(const char *path, struct fuse_file_info *fi) {
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
static int cfs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
size_t len;
(void) fi;
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
len = strlen(cfs_str);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, cfs_str + offset, size);
} else
size = 0;
return size;
}
static struct fuse_operations cfs_oper = {
.getattr = cfs_getattr,
.readdir = cfs_readdir,
.open = cfs_open,
.read = cfs_read,
};
int main(int argc, char *argv[]) {
return fuse_main(argc, argv, &cfs_oper, NULL);
}
这是我的cfs_server.c:
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "cfs.h"
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <rpc/pmap_clnt.h>
readdir_res * readdir_1_svc(nametype *dirname, struct svc_req *rqstp) {
DIR *dp;
struct dirent *directory;
static readdir_res result;
int inode;
namelist nl;
namelist *nlp;
dp = opendir(*dirname);
if (dp != NULL) {
nlp = &result.readdir_res_u.list;
while (directory = readdir(dp)) {
nl = *nlp = (namenode *) malloc(sizeof (namenode));
nl->name = directory->d_name;
nlp = &nl->next;
}
}
*nlp = NULL;
result.errnum = 0;
closedir(dp);
return &result;
}
这是我使用的make文件:
# This is a template Makefile generated by rpcgen
# Parameters
CLIENT = cfs_client
SERVER = cfs_server
SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = cfs.x
TARGETS_SVC.c = cfs_svc.c cfs_server.c cfs_xdr.c
TARGETS_CLNT.c = cfs_clnt.c cfs_client.c cfs_xdr.c
TARGETS = cfs.h cfs_xdr.c cfs_clnt.c cfs_svc.c cfs_client.c cfs_server.c
OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
# Compiler flags
CFLAGS += -g -Wall -DRPC_SVC_FG $(shell pkg-config fuse --cflags --libs)
LDLIBS += -lnsl
RPCGENFLAGS = -g
# Targets
all : $(CLIENT) $(SERVER)
$(TARGETS) : $(SOURCES.x)
rpcgen $(RPCGENFLAGS) $(SOURCES.x)
$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)
$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)
$(CLIENT) : $(OBJECTS_CLNT)
$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)
$(SERVER) : $(OBJECTS_SVC)
$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)
clean:
$(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)
编辑: 错误是:
root@debian:/programs/c/rpc/custom file system# make -f Makefile.cfs
rpcgen -g cfs.x
usage: rpcgen infile
rpcgen [-abkCLNTM][-Dname[=value]] [-i size] [-I [-K seconds]] [-Y path] infile
rpcgen [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] [-o outfile] [infile]
rpcgen [-s nettype]* [-o outfile] [infile]
rpcgen [-n netid]* [-o outfile] [infile]
options:
-a generate all files, including samples
-b backward compatibility mode (generates code for SunOS 4.1)
-c generate XDR routines
-C ANSI C mode
-Dname[=value] define a symbol (same as #define)
-h generate header file
-i size size at which to start generating inline code
-I generate code for inetd support in server (for SunOS 4.1)
-K seconds server exits after K seconds of inactivity
-l generate client side stubs
-L server errors will be printed to syslog
-m generate server side stubs
-M generate MT-safe code
-n netid generate server code that supports named netid
-N supports multiple arguments and call-by-value
-o outfile name of the output file
-s nettype generate server code that supports named nettype
-Sc generate sample client code that uses remote procedures
-Ss generate sample server code that defines remote procedures
-Sm generate makefile template
-t generate RPC dispatch table
-T generate code to support RPC dispatch tables
-Y path directory name to find C preprocessor (cpp)
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
make: *** [cfs_clnt.c] Error 1
答案 0 :(得分:0)
我通过使用bash文件解决了我的问题。这是我可能遇到与我相同问题的人的脚本:
cc -g -c -o cfs_clnt.o cfs_clnt.c
cc -g -D_FILE_OFFSET_BITS=64 -c -o cfs_client.o cfs_client.c
cc -g -c -o cfs_xdr.o cfs_xdr.c
cc -g -o cfs_client cfs_clnt.o cfs_client.o cfs_xdr.o -lnsl -Wall `pkg-config fuse --cflags --libs`
cc -g -c -o cfs_svc.o cfs_svc.c
cc -g -c -o cfs_server.o cfs_server.c
cc -g -o cfs_server cfs_svc.o cfs_server.o cfs_xdr.o -lnsl