File-ExtAttr

 view release on metacpan or  search on metacpan

ExtAttr.xs  view on Meta::CPAN

            //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 )