1e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich/* 2e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * Copyright (C) 2015 The Android Open Source Project 3e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * All rights reserved. 4e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * 5e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * Redistribution and use in source and binary forms, with or without 6e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * modification, are permitted provided that the following conditions 7e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * are met: 8e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * * Redistributions of source code must retain the above copyright 9e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * notice, this list of conditions and the following disclaimer. 10e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * * Redistributions in binary form must reproduce the above copyright 11e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * notice, this list of conditions and the following disclaimer in 12e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * the documentation and/or other materials provided with the 13e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * distribution. 14e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * 15e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich * SUCH DAMAGE. 27e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich */ 28e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich 29e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich#include <sys/stat.h> 30e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich#include <sys/types.h> 31e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich#include <sys/xattr.h> 32e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich#include <errno.h> 33e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich#include <fcntl.h> 34e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich#include <stdio.h> 35e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich 36e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevichextern "C" ssize_t ___flistxattr(int, char*, size_t); 37e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich 38e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevichssize_t flistxattr(int fd, char *list, size_t size) { 39e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich int saved_errno = errno; 40e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich ssize_t result = ___flistxattr(fd, list, size); 41e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich 42e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich if ((result != -1) || (errno != EBADF)) { 43e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich return result; 44e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich } 45e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich 46e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich // fd could be an O_PATH file descriptor, and the kernel 47e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich // may not directly support fgetxattr() on such a file descriptor. 48e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich // Use /proc/self/fd instead to emulate this support. 49e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich int fd_flag = fcntl(fd, F_GETFL); 50e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) { 51e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich errno = EBADF; 52e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich return -1; 53e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich } 54e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich 55e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich char buf[40]; 56e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd); 57e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich errno = saved_errno; 58e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich return listxattr(buf, list, size); 59e1d0810cd7e2aa045d5cc1e7d2b8697acd8467beNick Kralevich} 60