Net-LibNFS
view release on metacpan or search on metacpan
#define MAX_BUFFER_SIZE_ARRAY_SIZE 2
#define READDIR_BUFFER_SETTING "readdir_buffer"
static void _set_readdir_max_buffer_size(pTHX_ struct nfs_context* nfs, SV* value_sv) {
uint32_t dircount, maxcount;
if (SvROK(value_sv) && (SvTYPE(SvRV(value_sv)) == SVt_PVAV)) {
AV* av = (AV*) SvRV(value_sv);
uint32_t nums_count = 1 + av_len(av);
if (nums_count != MAX_BUFFER_SIZE_ARRAY_SIZE) croak("â%sâ must contain exactly %d numbers", READDIR_BUFFER_SETTING, MAX_BUFFER_SIZE_ARRAY_SIZE);
uint32_t nums[MAX_BUFFER_SIZE_ARRAY_SIZE];
for (unsigned n=0; n<nums_count; n++) {
SV** svp = av_fetch(av, n, 0);
assert(svp);
UV value = exs_SvUV(*svp);
_croak_if_uv_exceeds_u32(READDIR_BUFFER_SETTING, value);
nums[n] = value;
}
dircount = nums[0];
maxcount = nums[1];
} else if (SvROK(value_sv)) {
croak("â%sâ must be an array reference or scalar, not %" SVf, READDIR_BUFFER_SETTING, value_sv);
} else {
UV value = exs_SvUV(value_sv);
_croak_if_uv_exceeds_u32(READDIR_BUFFER_SETTING, value);
dircount = value;
maxcount = value;
}
nfs_set_readdir_max_buffer_size(nfs, dircount, maxcount);
}
#endif
// ----------------------------------------------------------------------
MODULE = Net::LibNFS PACKAGE = Net::LibNFS
PROTOTYPES: DISABLE
BOOT:
newCONSTSUB(gv_stashpv(PERL_NS, 0), "_POLLIN", newSVuv(POLLIN));
newCONSTSUB(gv_stashpv(PERL_NS, 0), "_POLLOUT", newSVuv(POLLOUT));
newCONSTSUB(gv_stashpv(PERL_NS, 0), "NFS4_F_SETLK", newSVuv(NFS4_F_SETLK));
newCONSTSUB(gv_stashpv(PERL_NS, 0), "NFS4_F_SETLKW", newSVuv(NFS4_F_SETLKW));
newCONSTSUB(gv_stashpv(PERL_NS, 0), "F_RDLCK", newSVuv(F_RDLCK));
newCONSTSUB(gv_stashpv(PERL_NS, 0), "F_WRLCK", newSVuv(F_WRLCK));
newCONSTSUB(gv_stashpv(PERL_NS, 0), "F_UNLCK", newSVuv(F_UNLCK));
# ----------------------------------------------------------------------
# Static functions
void
find_local_servers ()
PPCODE:
struct nfs_server_list *servers = nfs_find_local_servers();
if (!servers) {
XSRETURN_EMPTY;
}
struct nfs_server_list *srvlist = servers;
struct nfs_server_list *cur_srv = srvlist;
unsigned srvcount = 0;
while (cur_srv) {
srvcount++;
cur_srv = cur_srv->next;
}
cur_srv = srvlist;
if (srvcount) {
EXTEND(SP, srvcount);
while (cur_srv) {
mPUSHs( newSVpv(cur_srv->addr, 0) );
cur_srv = cur_srv->next;
}
}
free_nfs_srvr_list(srvlist);
void
mount_getexports (SV* server_sv, SV* timeout_sv=&PL_sv_undef)
PPCODE:
const char* server = exs_SvPVbyte_nolen(server_sv);
struct exportnode* nodes;
if (SvOK(timeout_sv)) {
int timeout = SvIV(timeout_sv); // TODO
nodes = mount_getexports_timeout(server, timeout);
}
else {
nodes = mount_getexports(server);
}
if (!nodes) {
XSRETURN_EMPTY;
}
unsigned exports_count = _count_exports(nodes);
SV* export_hrs[exports_count];
_parse_exports_to_hrs( aTHX_ nodes, export_hrs );
mount_free_export_list(nodes);
# ----------------------------------------------------------------------
SV*
new (const char* classname)
CODE:
struct nfs_context *nfs = nfs_init_context();
if (NULL == nfs) {
croak("Failed to init libnfs context");
}
RETVAL = exs_new_structref(nlnfs_s, classname);
nlnfs_s* perl_nfs = exs_structref_ptr(RETVAL);
*perl_nfs = (nlnfs_s) {
.nfs = nfs,
.pid = getpid(),
};
OUTPUT:
RETVAL
void
DESTROY (SV* self_sv)
CODE:
nlnfs_s* perl_nfs = exs_structref_ptr(self_sv);
if (perl_nfs->pid == getpid() && PL_dirty) {
warn("%" SVf ": DESTROY at global destruction; memory leak likely!\n", self_sv);
}
assert(perl_nfs);
assert(perl_nfs->nfs);
nfs_destroy_context(perl_nfs->nfs);
SV*
set (SV* self_sv, ...)
const char* server = exs_SvPVbyte_nolen(server_sv);
const char* funcname = "mount_getexports";
perl_cb_s* cb_sp = _create_callback_struct(aTHX_ funcname, cb, _parse_mount_getexports, NULL);
int err = mount_getexports_async(rpc, server, _do_perl_rpc_callback, cb_sp);
if (err) {
const char* str = rpc_get_error(rpc);
croak_sv( _create_rpc_errno(aTHX_ rpc, funcname, err, str) );
}
int
_get_fd (SV* self_sv)
ALIAS:
_which_events = 1
CODE:
nlnfs_rpc_s* perl_rpc = exs_structref_ptr(self_sv);
struct rpc_context *rpc = perl_rpc->rpc;
RETVAL = ix ? rpc_which_events(rpc) : rpc_get_fd(rpc);
OUTPUT:
RETVAL
int
_service (SV* self_sv, int revents)
CODE:
nlnfs_rpc_s* perl_rpc = exs_structref_ptr(self_sv);
struct rpc_context *rpc = perl_rpc->rpc;
RETVAL = rpc_service(rpc, revents);
OUTPUT:
RETVAL
# ----------------------------------------------------------------------
MODULE = Net::LibNFS PACKAGE = Net::LibNFS::Dirhandle
PROTOTYPES: DISABLE
void
DESTROY (SV* self_sv)
CODE:
nlnfs_dh_s* nfs_dh = exs_structref_ptr(self_sv);
if (!nfs_dh->closed) {
SV* nfs_sv = nfs_dh->perl_nfs;
nlnfs_s* perl_nfs = exs_structref_ptr(nfs_sv);
nfs_closedir( perl_nfs->nfs, nfs_dh->nfsdh );
}
SvREFCNT_dec(nfs_dh->perl_nfs);
void
read (SV* self_sv)
PPCODE:
_FORBID_VOID_CONTEXT;
nlnfs_dh_s* nfs_dh = exs_structref_ptr(self_sv);
SV* nfs_sv = nfs_dh->perl_nfs;
nlnfs_s* perl_nfs = exs_structref_ptr(nfs_sv);
unsigned retcount = 0;
struct nfsdirent* dent = nfs_readdir( perl_nfs->nfs, nfs_dh->nfsdh );
struct nfsdirent* cur_dent = dent;
while (cur_dent) {
retcount++;
if (GIMME_V != G_ARRAY) break;
cur_dent = cur_dent->next;
}
if (retcount) {
EXTEND(SP, retcount);
unsigned retcount_copy = retcount;
while (1) {
mPUSHs(_ptr_to_perl_dirent_obj(aTHX_ dent));
retcount_copy--;
if (!retcount_copy) break;
dent = nfs_readdir( perl_nfs->nfs, nfs_dh->nfsdh );
}
}
XSRETURN(retcount);
SV*
seek (SV* self_sv, SV* loc_sv)
CODE:
nlnfs_dh_s* nfs_dh = exs_structref_ptr(self_sv);
SV* nfs_sv = nfs_dh->perl_nfs;
nlnfs_s* perl_nfs = exs_structref_ptr(nfs_sv);
long loc = SvIV(loc_sv); // TODO
nfs_seekdir( perl_nfs->nfs, nfs_dh->nfsdh, loc );
RETVAL = SvREFCNT_inc(self_sv);
OUTPUT:
RETVAL
long
tell (SV* self_sv)
CODE:
nlnfs_dh_s* nfs_dh = exs_structref_ptr(self_sv);
SV* nfs_sv = nfs_dh->perl_nfs;
nlnfs_s* perl_nfs = exs_structref_ptr(nfs_sv);
RETVAL = nfs_telldir( perl_nfs->nfs, nfs_dh->nfsdh );
if (RETVAL < 0) {
_croak_nfs_errno(aTHX_ perl_nfs->nfs, "telldir", RETVAL, NULL);
}
OUTPUT:
RETVAL
SV*
rewind (SV* self_sv)
ALIAS:
close = 1
CODE:
nlnfs_dh_s* nfs_dh = exs_structref_ptr(self_sv);
SV* nfs_sv = nfs_dh->perl_nfs;
nlnfs_s* perl_nfs = exs_structref_ptr(nfs_sv);
if (ix) {
if (!nfs_dh->closed) {
nfs_closedir( perl_nfs->nfs, nfs_dh->nfsdh );
nfs_dh->closed = true;
}
}
else {
nfs_rewinddir( perl_nfs->nfs, nfs_dh->nfsdh );
}
RETVAL = SvREFCNT_inc(self_sv);
OUTPUT:
RETVAL
# ----------------------------------------------------------------------
MODULE = Net::LibNFS PACKAGE = Net::LibNFS::Filehandle
PROTOTYPES: DISABLE
void
DESTROY (SV* self_sv)
CODE:
nlnfs_fh_s* nfs_fh = exs_structref_ptr(self_sv);
SvREFCNT_dec(nfs_fh->perl_nfs);
void
close (SV* self_sv)
PPCODE:
nlnfs_fh_s* nfs_fh = exs_structref_ptr(self_sv);
SV* nfs_sv = nfs_fh->perl_nfs;
nlnfs_s* perl_nfs = exs_structref_ptr(nfs_sv);
int err = nfs_close(perl_nfs->nfs, nfs_fh->nfsfh);
if (err) {
_croak_nfs_errno(aTHX_ perl_nfs->nfs, "close", err, NULL);
}
XSRETURN_EMPTY;
void
_async_close (SV* self_sv, SV* cb)
ALIAS:
_async_sync = 1
CODE:
nlnfs_fh_s* nfs_fh = exs_structref_ptr(self_sv);
SV* nfs_sv = nfs_fh->perl_nfs;
nlnfs_s* perl_nfs = exs_structref_ptr(nfs_sv);
const char* funcname = ix ? "sync" : "close";
perl_cb_s* cb_sp = _create_callback_struct(aTHX_ funcname, cb, _parse_fallible_empty_return, NULL);
int err;
if (ix) {
err = nfs_fsync_async(perl_nfs->nfs, nfs_fh->nfsfh, _do_perl_callback, cb_sp);
}
else {
err = nfs_close_async(perl_nfs->nfs, nfs_fh->nfsfh, _do_perl_callback, cb_sp);
}
if (err) {
_croak_nfs_errno(aTHX_ perl_nfs->nfs, funcname, err, NULL);
}
SV*
read (SV* self_sv, SV* count_sv)
CODE:
RETVAL = _read_or_pread(aTHX_ self_sv, NULL, count_sv, NULL);
OUTPUT:
RETVAL
void
_async_read (SV* self_sv, SV* count_sv, SV* cb)
CODE:
_read_or_pread(aTHX_ self_sv, NULL, count_sv, cb);
SV*
pread (SV* self_sv, SV* offset_sv, SV* count_sv)
CODE:
RETVAL = _read_or_pread(aTHX_ self_sv, offset_sv, count_sv, NULL);
OUTPUT:
RETVAL
( run in 1.054 second using v1.01-cache-2.11-cpan-5511b514fd6 )