[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH v3 2/4] util: Create virFileAccessibleAs function



On Wed, Oct 19, 2011 at 04:42:57PM +0200, Michal Privoznik wrote:
> This function checks if a given path is accessible under
> given uid and gid.
> ---
>  src/util/util.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/util.h |    3 ++
>  2 files changed, 79 insertions(+), 0 deletions(-)
> 
> diff --git a/src/util/util.c b/src/util/util.c
> index dac616b..09d6281 100644
> --- a/src/util/util.c
> +++ b/src/util/util.c
> @@ -671,6 +671,70 @@ virFileIsExecutable(const char *file)
>  }
>  
>  #ifndef WIN32
> +/* Check that a file is accessible under certain
> + * user & gid.
> + * @mode can be R_OK, W_OK, X_OK or F_OK.
> + * see 'man accesss' for more details.
> + * Returns 0 on success, -errno on fail,
> + * >0 on signaled child.
> + */
> +int
> +virFileAccessibleAs(const char *path, int mode,
> +                    uid_t uid, gid_t gid)
> +{
> +    pid_t pid;
> +    int waitret, status, ret = 0;
> +    int forkRet;
> +
> +    forkRet = virFork(&pid);
> +
> +    if (pid < 0) {
> +        return -errno;
> +    }

virFork() already raises a proper libvirt error on failure,
so returning 'errno' too is a little misleading / redundant.
Just return '-1' on error here & throughout the function

> +
> +    if (pid) { /* parent */
> +        do {
> +            if ((waitret = waitpid(pid, &status, 0)) < 0) {
> +                ret = -errno;
> +                virKillProcess(pid, SIGKILL);
> +                return ret;
> +            }
> +        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
> +
> +        /* child actually returns positive value
> +         * anded by 0xFF (see man waitpid @ WEXITSTATUS)
> +         */
> +
> +        if (WIFSIGNALED(status))
> +            return WTERMSIG(status);
> +
> +        return -WEXITSTATUS(status);
> +    }
> +
> +    /* child */
> +
> +    if (forkRet < 0) {
> +        ret = errno;
> +        goto childerror;
> +    }
> +
> +    if (virSetUIDGID(uid, gid) < 0) {
> +        ret = errno;
> +        goto childerror;
> +    }
> +
> +    if (access(path, mode) < 0)
> +        ret = errno;
> +
> +childerror:
> +    if ((ret & 0xFF) != ret) {
> +        VIR_WARN("unable to pass desired return value %d", ret);
> +        ret = 0xFF;
> +    }
> +
> +    _exit(ret);
> +}
> +
>  /* return -errno on failure, or 0 on success */
>  static int
>  virFileOpenAsNoFork(const char *path, int openflags, mode_t mode,
> @@ -993,6 +1057,18 @@ childerror:
>  
>  #else /* WIN32 */
>  
> +int
> +virFileAccessibleAs(const char *path ATTRIBUTE_UNUSED,
> +                    int mode ATTRIBUTE_UNUSED,
> +                    uid_t uid ATTRIBUTE_UNUSED,
> +                    git_t gid ATTRIBUTE_UNUSED)
> +{
> +    virUtilError(VIR_ERR_INTERNAL_ERROR,
> +                 "%s", _("virFileAccessibleAs is not implemented for WIN32"));
> +
> +    return -ENOSYS;
> +}



Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]