github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/cmd/libsnap-confine-private/feature.c (about) 1 /* 2 * Copyright (C) 2018 Canonical Ltd 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 3 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 */ 17 18 #define _GNU_SOURCE 19 20 #include "feature.h" 21 22 #include <errno.h> 23 #include <fcntl.h> 24 #include <sys/stat.h> 25 #include <sys/types.h> 26 #include <unistd.h> 27 28 #include "cleanup-funcs.h" 29 #include "utils.h" 30 31 static const char *feature_flag_dir = "/var/lib/snapd/features"; 32 33 bool sc_feature_enabled(sc_feature_flag flag) 34 { 35 const char *file_name; 36 switch (flag) { 37 case SC_FEATURE_PER_USER_MOUNT_NAMESPACE: 38 file_name = "per-user-mount-namespace"; 39 break; 40 case SC_FEATURE_REFRESH_APP_AWARENESS: 41 file_name = "refresh-app-awareness"; 42 break; 43 case SC_FEATURE_PARALLEL_INSTANCES: 44 file_name = "parallel-instances"; 45 break; 46 case SC_FEATURE_HIDDEN_SNAP_FOLDER: 47 file_name = "hidden-snap-folder"; 48 break; 49 default: 50 die("unknown feature flag code %d", flag); 51 } 52 53 int dirfd SC_CLEANUP(sc_cleanup_close) = -1; 54 dirfd = 55 open(feature_flag_dir, 56 O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW | O_PATH); 57 if (dirfd < 0 && errno == ENOENT) { 58 return false; 59 } 60 if (dirfd < 0) { 61 die("cannot open path %s", feature_flag_dir); 62 } 63 64 struct stat file_info; 65 if (fstatat(dirfd, file_name, &file_info, AT_SYMLINK_NOFOLLOW) < 0) { 66 if (errno == ENOENT) { 67 return false; 68 } 69 die("cannot inspect file %s/%s", feature_flag_dir, file_name); 70 } 71 72 return S_ISREG(file_info.st_mode); 73 }