File-ExtAttr
view release on metacpan or search on metacpan
//return undef
}else{
Safefree(attrvalue);
errno = -attrlen;
XSRETURN_UNDEF;
}
}
RETVAL = newSVpv(attrvalue, attrlen);
Safefree(attrvalue);
OUTPUT:
RETVAL
int
_delfattr (path, attrname, flags = 0)
const char *path
const char *attrname
HV * flags
PREINIT:
int rc;
CODE:
rc = portable_removexattr(path, attrname, flags);
if (rc < 0)
errno = -rc;
RETVAL = (rc == 0);
OUTPUT:
RETVAL
int
_fdelfattr (fd, attrname, flags = 0)
int fd
const char *attrname
HV * flags
PREINIT:
int rc;
CODE:
rc = portable_fremovexattr(fd, attrname, flags);
if (rc < 0)
errno = -rc;
RETVAL = (rc == 0);
OUTPUT:
RETVAL
void
_listfattr (path, fd, flags = 0)
const char *path
int fd
HV * flags
PREINIT:
ssize_t size, ret;
char *namebuf = NULL;
char *nameptr;
PPCODE:
if(fd == -1)
size = portable_listxattr(path, NULL, 0, flags);
else
size = portable_flistxattr(fd, NULL, 0, flags);
if (size < 0)
{
errno = -(int) size;
XSRETURN_UNDEF;
} else if (size == 0)
{
XSRETURN_EMPTY;
}
namebuf = malloc(size);
if (fd == -1)
ret = portable_listxattr(path, namebuf, size, flags);
else
ret = portable_flistxattr(fd, namebuf, size, flags);
// There could be a race condition here, if someone adds a new
// attribute between the two listxattr calls. However it just means we
// might return ERANGE.
if (ret < 0)
{
free(namebuf);
errno = -ret;
XSRETURN_UNDEF;
} else if (ret == 0)
{
free(namebuf);
XSRETURN_EMPTY;
}
nameptr = namebuf;
while(nameptr < namebuf + ret)
{
char *endptr = nameptr;
while(*endptr++ != '\0');
// endptr will now point one past the end..
XPUSHs(sv_2mortal(newSVpvn(nameptr, endptr - nameptr - 1)));
// nameptr could now point past the end of namebuf
nameptr = endptr;
}
free(namebuf);
void
_listfattrns (path, fd, flags = 0)
const char *path
int fd
HV * flags
PREINIT:
ssize_t size, ret;
char *namebuf = NULL;
char *nameptr;
PPCODE:
if(fd == -1)
size = portable_listxattrns(path, NULL, 0, flags);
else
size = portable_flistxattrns(fd, NULL, 0, flags);
if (size < 0)
{
errno = -(int) size;
XSRETURN_UNDEF;
} else if (size == 0)
{
XSRETURN_EMPTY;
}
namebuf = malloc(size);
if (fd == -1)
ret = portable_listxattrns(path, namebuf, size, flags);
else
ret = portable_flistxattrns(fd, namebuf, size, flags);
// There could be a race condition here, if someone adds a new
// attribute between the two listxattr calls. However it just means we
// might return ERANGE.
if (ret < 0)
{
free(namebuf);
errno = -ret;
XSRETURN_UNDEF;
} else if (ret == 0)
{
free(namebuf);
XSRETURN_EMPTY;
}
nameptr = namebuf;
while(nameptr < namebuf + ret)
{
char *endptr = nameptr;
while(*endptr++ != '\0');
// endptr will now point one past the end..
XPUSHs(sv_2mortal(newSVpvn(nameptr, endptr - nameptr - 1)));
// nameptr could now point past the end of namebuf
nameptr = endptr;
}
free(namebuf);
( run in 0.640 second using v1.01-cache-2.11-cpan-5511b514fd6 )