12825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich/* 22825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * Copyright (C) 2015 The Android Open Source Project 32825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * All rights reserved. 42825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * 52825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * Redistribution and use in source and binary forms, with or without 62825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * modification, are permitted provided that the following conditions 72825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * are met: 82825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * * Redistributions of source code must retain the above copyright 92825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * notice, this list of conditions and the following disclaimer. 102825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * * Redistributions in binary form must reproduce the above copyright 112825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * notice, this list of conditions and the following disclaimer in 122825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * the documentation and/or other materials provided with the 132825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * distribution. 142825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * 152825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 182825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 192825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 202825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 212825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 222825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 232825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 242825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 252825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 262825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich * SUCH DAMAGE. 272825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich */ 282825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich 292825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich#include <sys/stat.h> 302825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich#include <sys/types.h> 312825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich#include <sys/xattr.h> 322825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich#include <errno.h> 332825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich#include <fcntl.h> 342825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich#include <stdio.h> 352825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich 362825f10b7f61558c264231a536cf3affc0d84204Nick Kralevichextern "C" int ___fsetxattr(int, const char*, const void*, size_t, int); 372825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich 382825f10b7f61558c264231a536cf3affc0d84204Nick Kralevichint fsetxattr(int fd, const char* name, const void* value, size_t size, int flags) { 392825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich int saved_errno = errno; 402825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich int result = ___fsetxattr(fd, name, value, size, flags); 412825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich 422825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich if ((result == 0) || (errno != EBADF)) { 432825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich return result; 442825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich } 452825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich 462825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich // fd could be an O_PATH file descriptor, and the kernel 472825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich // may not directly support fsetxattr() on such a file descriptor. 482825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich // Use /proc/self/fd instead to emulate this support. 492825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich int fd_flag = fcntl(fd, F_GETFL); 502825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich if ((fd_flag == -1) || ((fd_flag & O_PATH) == 0)) { 512825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich errno = EBADF; 522825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich return -1; 532825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich } 542825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich 552825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich char buf[40]; 562825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd); 572825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich errno = saved_errno; 582825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich return setxattr(buf, name, value, size, flags); 592825f10b7f61558c264231a536cf3affc0d84204Nick Kralevich} 60