TESTS: add tests for symlink/readlink

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
libnfs-4.0.0-vitalif
Ronnie Sahlberg 2017-07-01 08:40:59 +10:00
parent 0e0bb3fb34
commit db6d0836f4
11 changed files with 171 additions and 43 deletions

View File

@ -1453,14 +1453,14 @@ EXTERN int nfs_access2(struct nfs_context *nfs, const char *path);
* -errno : An error occured.
* data is the error string.
*/
EXTERN int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data);
EXTERN int nfs_symlink_async(struct nfs_context *nfs, const char *target, const char *linkname, nfs_cb cb, void *private_data);
/*
* Sync symlink(<path>)
* Function returns
* 0 : The operation was successful.
* -errno : The command failed.
*/
EXTERN int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpath);
EXTERN int nfs_symlink(struct nfs_context *nfs, const char *target, const char *linkname);
/*

View File

@ -1401,7 +1401,8 @@ int nfs_access2(struct nfs_context *nfs, const char *path)
/*
* symlink()
*/
static void symlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
static void
symlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
{
struct sync_cb_data *cb_data = private_data;
@ -1409,19 +1410,23 @@ static void symlink_cb(int status, struct nfs_context *nfs, void *data, void *pr
cb_data->status = status;
if (status < 0) {
nfs_set_error(nfs, "symlink call failed with \"%s\"", (char *)data);
nfs_set_error(nfs, "symlink call failed with \"%s\"",
(char *)data);
return;
}
}
int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpath)
int
nfs_symlink(struct nfs_context *nfs, const char *target, const char *linkname)
{
struct sync_cb_data cb_data;
cb_data.is_finished = 0;
if (nfs_symlink_async(nfs, oldpath, newpath, symlink_cb, &cb_data) != 0) {
nfs_set_error(nfs, "nfs_symlink_async failed");
if (nfs_symlink_async(nfs, target, linkname, symlink_cb,
&cb_data) != 0) {
nfs_set_error(nfs, "nfs_symlink_async failed: %s",
nfs_get_error(nfs));
return -1;
}
@ -1431,7 +1436,6 @@ int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpat
}
/*
* rename()
*/

View File

@ -1482,12 +1482,12 @@ nfs_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
}
int
nfs_symlink_async(struct nfs_context *nfs, const char *oldpath,
nfs_symlink_async(struct nfs_context *nfs, const char *target,
const char *newpath, nfs_cb cb, void *private_data)
{
switch (nfs->version) {
case NFS_V3:
return nfs3_symlink_async(nfs, oldpath, newpath,
return nfs3_symlink_async(nfs, target, newpath,
cb, private_data);
default:
nfs_set_error(nfs, "%s does not support NFSv4",

View File

@ -1441,9 +1441,9 @@ nfs3_rename_async(struct nfs_context *nfs, const char *oldpath,
struct nfs_symlink_data {
char *oldpath;
char *newpathparent;
char *newpathobject;
char *target;
char *linkparent;
char *linkobject;
};
static void
@ -1451,15 +1451,9 @@ free_nfs_symlink_data(void *mem)
{
struct nfs_symlink_data *data = mem;
if (data->oldpath != NULL) {
free(data->oldpath);
}
if (data->newpathparent != NULL) {
free(data->newpathparent);
}
if (data->newpathobject != NULL) {
free(data->newpathobject);
}
free(data->target);
free(data->linkparent);
free(data->linkobject);
free(data);
}
@ -1482,9 +1476,9 @@ nfs3_symlink_cb(struct rpc_context *rpc, int status, void *command_data,
res = command_data;
if (res->status != NFS3_OK) {
nfs_set_error(nfs, "NFS: SYMLINK %s/%s -> %s failed with "
"%s(%d)", symlink_data->newpathparent,
symlink_data->newpathobject,
symlink_data->oldpath,
"%s(%d)", symlink_data->linkparent,
symlink_data->linkobject,
symlink_data->target,
nfsstat3_to_str(res->status),
nfsstat3_to_errno(res->status));
data->cb(nfsstat3_to_errno(res->status), nfs,
@ -1509,10 +1503,10 @@ nfs3_symlink_continue_internal(struct nfs_context *nfs,
memset(&args, 0, sizeof(SYMLINK3args));
args.where.dir.data.data_len = data->fh.len;
args.where.dir.data.data_val = data->fh.val;
args.where.name = symlink_data->newpathobject;
args.where.name = symlink_data->linkobject;
args.symlink.symlink_attributes.mode.set_it = 1;
args.symlink.symlink_attributes.mode.set_mode3_u.mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH;
args.symlink.symlink_data = symlink_data->oldpath;
args.symlink.symlink_data = symlink_data->target;
if (rpc_nfs3_symlink_async(nfs->rpc, nfs3_symlink_cb,
&args, data) != 0) {
@ -1526,8 +1520,8 @@ nfs3_symlink_continue_internal(struct nfs_context *nfs,
}
int
nfs3_symlink_async(struct nfs_context *nfs, const char *oldpath,
const char *newpath, nfs_cb cb, void *private_data)
nfs3_symlink_async(struct nfs_context *nfs, const char *target,
const char *linkname, nfs_cb cb, void *private_data)
{
char *ptr;
struct nfs_symlink_data *symlink_data;
@ -1540,40 +1534,40 @@ nfs3_symlink_async(struct nfs_context *nfs, const char *oldpath,
}
memset(symlink_data, 0, sizeof(struct nfs_symlink_data));
symlink_data->oldpath = strdup(oldpath);
if (symlink_data->oldpath == NULL) {
symlink_data->target = strdup(target);
if (symlink_data->target == NULL) {
nfs_set_error(nfs, "Out of memory, failed to allocate "
"buffer for oldpath");
"buffer for target");
free_nfs_symlink_data(symlink_data);
return -1;
}
symlink_data->newpathparent = strdup(newpath);
if (symlink_data->newpathparent == NULL) {
symlink_data->linkparent = strdup(linkname);
if (symlink_data->linkparent == NULL) {
nfs_set_error(nfs, "Out of memory, failed to allocate "
"mode buffer for new path");
free_nfs_symlink_data(symlink_data);
return -1;
}
ptr = strrchr(symlink_data->newpathparent, '/');
ptr = strrchr(symlink_data->linkparent, '/');
if (ptr == NULL) {
nfs_set_error(nfs, "Invalid path %s", oldpath);
nfs_set_error(nfs, "Invalid path \"%s\"", linkname);
free_nfs_symlink_data(symlink_data);
return -1;
}
*ptr = 0;
ptr++;
symlink_data->newpathobject = strdup(ptr);
if (symlink_data->newpathobject == NULL) {
symlink_data->linkobject = strdup(ptr);
if (symlink_data->linkobject == NULL) {
nfs_set_error(nfs, "Out of memory, failed to allocate "
"mode buffer for new path");
free_nfs_symlink_data(symlink_data);
return -1;
}
if (nfs3_lookuppath_async(nfs, symlink_data->newpathparent, 0,
if (nfs3_lookuppath_async(nfs, symlink_data->linkparent, 0,
cb, private_data,
nfs3_symlink_continue_internal,
symlink_data, free_nfs_symlink_data, 0)

View File

@ -4,7 +4,7 @@ AM_CPPFLAGS = -I${srcdir}/../include -I${srcdir}/../include/nfsc \
AM_CFLAGS = $(WARN_CFLAGS)
LDADD = ../lib/libnfs.la
noinst_PROGRAMS = prog_fstat prog_stat prog_timeout
noinst_PROGRAMS = prog_fstat prog_stat prog_symlink prog_timeout
EXTRA_PROGRAMS = ld_timeout
CLEANFILES = ld_timeout.o ld_timeout.so

View File

@ -1,5 +1,6 @@
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
/*
Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2015
Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2017
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,6 @@
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
/*
Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2015
Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2017
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

98
tests/prog_symlink.c Normal file
View File

@ -0,0 +1,98 @@
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
/*
Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2017
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "libnfs.h"
void usage(void)
{
fprintf(stderr, "Usage: prog-symlink <url> <target> <link>\n");
exit(1);
}
int main(int argc, char *argv[])
{
struct nfs_context *nfs = NULL;
struct nfs_url *url = NULL;
int ret = 0;
char buf[1024];
if (argc != 4) {
usage();
}
nfs = nfs_init_context();
if (nfs == NULL) {
printf("failed to init context\n");
exit(1);
}
url = nfs_parse_url_full(nfs, argv[1]);
if (url == NULL) {
fprintf(stderr, "%s\n", nfs_get_error(nfs));
exit(1);
}
if (nfs_mount(nfs, url->server, url->path) != 0) {
fprintf(stderr, "Failed to mount nfs share : %s\n",
nfs_get_error(nfs));
ret = 1;
goto finished;
}
if (nfs_symlink(nfs, argv[2], argv[3])) {
fprintf(stderr, "Failed to create symlink: %s\n",
nfs_get_error(nfs));
ret = 1;
goto finished;
}
memset(buf, 0, sizeof(buf));
if (nfs_readlink(nfs, argv[3], buf, sizeof(buf))) {
fprintf(stderr, "Failed to read symlink: %s\n",
nfs_get_error(nfs));
ret = 1;
goto finished;
}
if (strcmp(argv[2], buf)) {
fprintf(stderr, "Symlink target did not read back correctly."
"Expected \"%s\" Got \"%s\"\n",
buf, argv[2]);
ret = 1;
goto finished;
}
finished:
nfs_destroy_url(url);
nfs_destroy_context(nfs);
return ret;
}

View File

@ -1,5 +1,6 @@
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
/*
Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2015
Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2017
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -0,0 +1,20 @@
#!/bin/sh
. ./functions.sh
echo "basic symlink test"
start_share
echo -n "Create a symlink from a root path (absolute) ... "
./prog_symlink "${TESTURL}/" kangabanga /symlink || failure
success
echo -n "Create a symlink from a nested path (absolute) ... "
mkdir "${TESTDIR}/subdir"
./prog_symlink "${TESTURL}/" kangabanga /subdir/symlink || failure
success
stop_share
exit 0

View File

@ -52,6 +52,15 @@ echo -n "test nfs_fstat64() for memory leaks ... "
libtool --mode=execute valgrind --leak-check=full --error-exitcode=1 ./prog_fstat "${TESTURL}/file.99" >/dev/null 2>&1 || failure
success
echo -n "test nfs_symlink()/nfs_readlink() for memory leaks ... "
libtool --mode=execute valgrind --leak-check=full --error-exitcode=1 ./prog_symlink "${TESTURL}/" kangabanga /symlink >/dev/null 2>&1 || failure
success
echo -n "test nfs_symlink()/nfs_readlink() for memory leaks (2) ... "
mkdir "${TESTDIR}/subdir"
libtool --mode=execute valgrind --leak-check=full --error-exitcode=1 ./prog_symlink "${TESTURL}/" kangabanga /subdir/symlink >/dev/null 2>&1 || failure
success
stop_share
exit 0