github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/abi/linux/file.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package linux 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/metacubex/gvisor/pkg/abi" 22 ) 23 24 // Constants for open(2). 25 const ( 26 O_ACCMODE = 000000003 27 O_RDONLY = 000000000 28 O_WRONLY = 000000001 29 O_RDWR = 000000002 30 O_CREAT = 000000100 31 O_EXCL = 000000200 32 O_NOCTTY = 000000400 33 O_TRUNC = 000001000 34 O_APPEND = 000002000 35 O_NONBLOCK = 000004000 36 O_DSYNC = 000010000 37 O_ASYNC = 000020000 38 O_NOATIME = 001000000 39 O_CLOEXEC = 002000000 40 O_SYNC = 004000000 // __O_SYNC in Linux 41 O_PATH = 010000000 42 O_TMPFILE = 020000000 // __O_TMPFILE in Linux 43 ) 44 45 // Constants for fstatat(2). 46 const ( 47 AT_SYMLINK_NOFOLLOW = 0x100 48 ) 49 50 // Constants for mount(2). 51 const ( 52 MS_RDONLY = 0x1 53 MS_NOSUID = 0x2 54 MS_NODEV = 0x4 55 MS_NOEXEC = 0x8 56 MS_SYNCHRONOUS = 0x10 57 MS_REMOUNT = 0x20 58 MS_MANDLOCK = 0x40 59 MS_DIRSYNC = 0x80 60 MS_NOATIME = 0x400 61 MS_NODIRATIME = 0x800 62 MS_BIND = 0x1000 63 MS_MOVE = 0x2000 64 MS_REC = 0x4000 65 66 MS_POSIXACL = 0x10000 67 MS_UNBINDABLE = 0x20000 68 MS_PRIVATE = 0x40000 69 MS_SLAVE = 0x80000 70 MS_SHARED = 0x100000 71 MS_RELATIME = 0x200000 72 MS_KERNMOUNT = 0x400000 73 MS_I_VERSION = 0x800000 74 MS_STRICTATIME = 0x1000000 75 76 MS_MGC_VAL = 0xC0ED0000 77 MS_MGC_MSK = 0xffff0000 78 ) 79 80 // Constants for umount2(2). 81 const ( 82 MNT_FORCE = 0x1 83 MNT_DETACH = 0x2 84 MNT_EXPIRE = 0x4 85 UMOUNT_NOFOLLOW = 0x8 86 ) 87 88 // Constants for unlinkat(2). 89 const ( 90 AT_REMOVEDIR = 0x200 91 ) 92 93 // Constants for linkat(2) and fchownat(2). 94 const ( 95 AT_SYMLINK_FOLLOW = 0x400 96 AT_EMPTY_PATH = 0x1000 97 ) 98 99 // Constants for faccessat2(2). 100 const ( 101 AT_EACCESS = 0x200 102 ) 103 104 // Constants for all file-related ...at(2) syscalls. 105 const ( 106 AT_FDCWD = -100 107 ) 108 109 // Special values for the ns field in utimensat(2). 110 const ( 111 UTIME_NOW = ((1 << 30) - 1) 112 UTIME_OMIT = ((1 << 30) - 2) 113 ) 114 115 // MaxSymlinkTraversals is the maximum number of links that will be followed by 116 // the kernel to resolve a symlink. 117 const MaxSymlinkTraversals = 40 118 119 // Constants for flock(2). 120 const ( 121 LOCK_SH = 1 // shared lock 122 LOCK_EX = 2 // exclusive lock 123 LOCK_NB = 4 // or'd with one of the above to prevent blocking 124 LOCK_UN = 8 // remove lock 125 ) 126 127 // Values for mode_t. 128 const ( 129 S_IFMT = 0170000 130 S_IFSOCK = 0140000 131 S_IFLNK = 0120000 132 S_IFREG = 0100000 133 S_IFBLK = 060000 134 S_IFDIR = 040000 135 S_IFCHR = 020000 136 S_IFIFO = 010000 137 138 FileTypeMask = S_IFMT 139 ModeSocket = S_IFSOCK 140 ModeSymlink = S_IFLNK 141 ModeRegular = S_IFREG 142 ModeBlockDevice = S_IFBLK 143 ModeDirectory = S_IFDIR 144 ModeCharacterDevice = S_IFCHR 145 ModeNamedPipe = S_IFIFO 146 147 S_ISUID = 04000 148 S_ISGID = 02000 149 S_ISVTX = 01000 150 151 ModeSetUID = S_ISUID 152 ModeSetGID = S_ISGID 153 ModeSticky = S_ISVTX 154 155 ModeUserAll = 0700 156 ModeUserRead = 0400 157 ModeUserWrite = 0200 158 ModeUserExec = 0100 159 ModeGroupAll = 0070 160 ModeGroupRead = 0040 161 ModeGroupWrite = 0020 162 ModeGroupExec = 0010 163 ModeOtherAll = 0007 164 ModeOtherRead = 0004 165 ModeOtherWrite = 0002 166 ModeOtherExec = 0001 167 PermissionsMask = 0777 168 ) 169 170 // Values for linux_dirent64.d_type. 171 const ( 172 DT_UNKNOWN = 0 173 DT_FIFO = 1 174 DT_CHR = 2 175 DT_DIR = 4 176 DT_BLK = 6 177 DT_REG = 8 178 DT_LNK = 10 179 DT_SOCK = 12 180 DT_WHT = 14 181 ) 182 183 // DirentType are the friendly strings for linux_dirent64.d_type. 184 var DirentType = abi.ValueSet{ 185 DT_UNKNOWN: "DT_UNKNOWN", 186 DT_FIFO: "DT_FIFO", 187 DT_CHR: "DT_CHR", 188 DT_DIR: "DT_DIR", 189 DT_BLK: "DT_BLK", 190 DT_REG: "DT_REG", 191 DT_LNK: "DT_LNK", 192 DT_SOCK: "DT_SOCK", 193 DT_WHT: "DT_WHT", 194 } 195 196 // Values for fs on-disk file types. 197 const ( 198 FT_UNKNOWN = 0 199 FT_REG_FILE = 1 200 FT_DIR = 2 201 FT_CHRDEV = 3 202 FT_BLKDEV = 4 203 FT_FIFO = 5 204 FT_SOCK = 6 205 FT_SYMLINK = 7 206 FT_MAX = 8 207 ) 208 209 // Conversion from fs on-disk file type to dirent type. 210 var direntTypeByFileType = [FT_MAX]uint8{ 211 FT_UNKNOWN: DT_UNKNOWN, 212 FT_REG_FILE: DT_REG, 213 FT_DIR: DT_DIR, 214 FT_CHRDEV: DT_CHR, 215 FT_BLKDEV: DT_BLK, 216 FT_FIFO: DT_FIFO, 217 FT_SOCK: DT_SOCK, 218 FT_SYMLINK: DT_LNK, 219 } 220 221 // FileTypeToDirentType converts the on-disk file type (FT_*) to the directory 222 // entry type (DT_*). 223 func FileTypeToDirentType(filetype uint8) uint8 { 224 if filetype >= FT_MAX { 225 return DT_UNKNOWN 226 } 227 return direntTypeByFileType[filetype] 228 } 229 230 // Values for preadv2/pwritev2. 231 const ( 232 // NOTE(b/120162627): gVisor does not implement the RWF_HIPRI feature, but 233 // the flag is accepted as a valid flag argument for preadv2/pwritev2 and 234 // silently ignored. 235 RWF_HIPRI = 0x00000001 236 RWF_DSYNC = 0x00000002 237 RWF_SYNC = 0x00000004 238 RWF_VALID = RWF_HIPRI | RWF_DSYNC | RWF_SYNC 239 ) 240 241 // SizeOfStat is the size of a Stat struct. 242 var SizeOfStat = (*Stat)(nil).SizeBytes() 243 244 // Flags for statx. 245 const ( 246 AT_NO_AUTOMOUNT = 0x800 247 AT_STATX_SYNC_TYPE = 0x6000 248 AT_STATX_SYNC_AS_STAT = 0x0000 249 AT_STATX_FORCE_SYNC = 0x2000 250 AT_STATX_DONT_SYNC = 0x4000 251 ) 252 253 // Mask values for statx. 254 const ( 255 STATX_TYPE = 0x00000001 256 STATX_MODE = 0x00000002 257 STATX_NLINK = 0x00000004 258 STATX_UID = 0x00000008 259 STATX_GID = 0x00000010 260 STATX_ATIME = 0x00000020 261 STATX_MTIME = 0x00000040 262 STATX_CTIME = 0x00000080 263 STATX_INO = 0x00000100 264 STATX_SIZE = 0x00000200 265 STATX_BLOCKS = 0x00000400 266 STATX_BASIC_STATS = 0x000007ff 267 STATX_BTIME = 0x00000800 268 STATX_ALL = 0x00000fff 269 STATX__RESERVED = 0x80000000 270 ) 271 272 // Bitmasks for Statx.Attributes and Statx.AttributesMask, from 273 // include/uapi/linux/stat.h. 274 const ( 275 STATX_ATTR_COMPRESSED = 0x00000004 276 STATX_ATTR_IMMUTABLE = 0x00000010 277 STATX_ATTR_APPEND = 0x00000020 278 STATX_ATTR_NODUMP = 0x00000040 279 STATX_ATTR_ENCRYPTED = 0x00000800 280 STATX_ATTR_AUTOMOUNT = 0x00001000 281 ) 282 283 // Statx represents struct statx. 284 // 285 // +marshal boundCheck slice:StatxSlice 286 type Statx struct { 287 Mask uint32 288 Blksize uint32 289 Attributes uint64 290 Nlink uint32 291 UID uint32 292 GID uint32 293 Mode uint16 294 _ uint16 295 Ino uint64 296 Size uint64 297 Blocks uint64 298 AttributesMask uint64 299 Atime StatxTimestamp 300 Btime StatxTimestamp 301 Ctime StatxTimestamp 302 Mtime StatxTimestamp 303 RdevMajor uint32 304 RdevMinor uint32 305 DevMajor uint32 306 DevMinor uint32 307 } 308 309 // String implements fmt.Stringer.String. 310 func (s *Statx) String() string { 311 return fmt.Sprintf("Statx{Mask: %#x, Mode: %s, UID: %d, GID: %d, Ino: %d, DevMajor: %d, DevMinor: %d, Size: %d, Blocks: %d, Blksize: %d, Nlink: %d, Atime: %s, Btime: %s, Ctime: %s, Mtime: %s, Attributes: %d, AttributesMask: %d, RdevMajor: %d, RdevMinor: %d}", 312 s.Mask, FileMode(s.Mode), s.UID, s.GID, s.Ino, s.DevMajor, s.DevMinor, s.Size, s.Blocks, s.Blksize, s.Nlink, s.Atime.ToTime(), s.Btime.ToTime(), s.Ctime.ToTime(), s.Mtime.ToTime(), s.Attributes, s.AttributesMask, s.RdevMajor, s.RdevMinor) 313 } 314 315 // SizeOfStatx is the size of a Statx struct. 316 var SizeOfStatx = (*Statx)(nil).SizeBytes() 317 318 // FileMode represents a mode_t. 319 // 320 // +marshal 321 type FileMode uint16 322 323 // Permissions returns just the permission bits. 324 func (m FileMode) Permissions() FileMode { 325 return m & PermissionsMask 326 } 327 328 // FileType returns just the file type bits. 329 func (m FileMode) FileType() FileMode { 330 return m & FileTypeMask 331 } 332 333 // ExtraBits returns everything but the file type and permission bits. 334 func (m FileMode) ExtraBits() FileMode { 335 return m &^ (PermissionsMask | FileTypeMask) 336 } 337 338 // IsDir returns true if file type represents a directory. 339 func (m FileMode) IsDir() bool { 340 return m.FileType() == S_IFDIR 341 } 342 343 // String returns a string representation of m. 344 func (m FileMode) String() string { 345 var s []string 346 if ft := m.FileType(); ft != 0 { 347 s = append(s, fileType.Parse(uint64(ft))) 348 } 349 if eb := m.ExtraBits(); eb != 0 { 350 s = append(s, modeExtraBits.Parse(uint64(eb))) 351 } 352 s = append(s, fmt.Sprintf("0o%o", m.Permissions())) 353 return strings.Join(s, "|") 354 } 355 356 // DirentType maps file types to dirent types appropriate for (struct 357 // dirent)::d_type. 358 func (m FileMode) DirentType() uint8 { 359 switch m.FileType() { 360 case ModeSocket: 361 return DT_SOCK 362 case ModeSymlink: 363 return DT_LNK 364 case ModeRegular: 365 return DT_REG 366 case ModeBlockDevice: 367 return DT_BLK 368 case ModeDirectory: 369 return DT_DIR 370 case ModeCharacterDevice: 371 return DT_CHR 372 case ModeNamedPipe: 373 return DT_FIFO 374 default: 375 return DT_UNKNOWN 376 } 377 } 378 379 var modeExtraBits = abi.FlagSet{ 380 { 381 Flag: ModeSetUID, 382 Name: "S_ISUID", 383 }, 384 { 385 Flag: ModeSetGID, 386 Name: "S_ISGID", 387 }, 388 { 389 Flag: ModeSticky, 390 Name: "S_ISVTX", 391 }, 392 } 393 394 var fileType = abi.ValueSet{ 395 ModeSocket: "S_IFSOCK", 396 ModeSymlink: "S_IFLINK", 397 ModeRegular: "S_IFREG", 398 ModeBlockDevice: "S_IFBLK", 399 ModeDirectory: "S_IFDIR", 400 ModeCharacterDevice: "S_IFCHR", 401 ModeNamedPipe: "S_IFIFO", 402 } 403 404 // Constants for memfd_create(2). Source: include/uapi/linux/memfd.h 405 const ( 406 MFD_CLOEXEC = 0x0001 407 MFD_ALLOW_SEALING = 0x0002 408 ) 409 410 // Constants related to file seals. Source: include/uapi/{asm-generic,linux}/fcntl.h 411 const ( 412 F_LINUX_SPECIFIC_BASE = 1024 413 F_ADD_SEALS = F_LINUX_SPECIFIC_BASE + 9 414 F_GET_SEALS = F_LINUX_SPECIFIC_BASE + 10 415 416 F_SEAL_SEAL = 0x0001 // Prevent further seals from being set. 417 F_SEAL_SHRINK = 0x0002 // Prevent file from shrinking. 418 F_SEAL_GROW = 0x0004 // Prevent file from growing. 419 F_SEAL_WRITE = 0x0008 // Prevent writes. 420 ) 421 422 // Constants related to fallocate(2). Source: include/uapi/linux/falloc.h 423 const ( 424 FALLOC_FL_KEEP_SIZE = 0x01 425 FALLOC_FL_PUNCH_HOLE = 0x02 426 FALLOC_FL_NO_HIDE_STALE = 0x04 427 FALLOC_FL_COLLAPSE_RANGE = 0x08 428 FALLOC_FL_ZERO_RANGE = 0x10 429 FALLOC_FL_INSERT_RANGE = 0x20 430 FALLOC_FL_UNSHARE_RANGE = 0x40 431 ) 432 433 // Constants related to close_range(2). Source: /include/uapi/linux/close_range.h 434 const ( 435 CLOSE_RANGE_UNSHARE = uint32(1 << 1) 436 CLOSE_RANGE_CLOEXEC = uint32(1 << 2) 437 )