/* store metadata from the curl request alongside the downloaded * file using extended attributes */ int fwrite_xattr(CURL *curl, int fd) { int i = 0; int err = 0; /* loop through all xattr-curlinfo pairs and abort on a set error */ while(err == 0 && mappings[i].attr != NULL) { char *value = NULL; CURLcode result = curl_easy_getinfo(curl, mappings[i].info, &value); if(!result && value) { #ifdef HAVE_FSETXATTR_6 err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0, 0); #elif defined(HAVE_FSETXATTR_5) err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0); #elif defined(__FreeBSD_version) err = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, mappings[i].attr, value, strlen(value)); /* FreeBSD's extattr_set_fd returns the length of the extended attribute */ err = err < 0 ? err : 0; #endif } i++; } return err; }
virtual int setup() override { //Create file foo const int fd_foo = open(foo_path.c_str(), O_RDWR | O_CREAT, TEST_FILE_PERMS); if (fd_foo < 0) { return -1; } //add xattrs to the file foo int res = fsetxattr(fd_foo, "user.xattr1", "val1", 4, 0); if (res < 0) { return -1; } res = fsetxattr(fd_foo, "user.xattr2", "val2", 4, 0); if (res < 0) { return -1; } res = fsetxattr(fd_foo, "user.xattr3", "val3", 4, 0); if (res < 0) { return -1; } //Sync everything sync(); close(fd_foo); sleep(2); return 0; }
static INT64_T chirp_fs_local_fsetxattr(int fd, const char *name, const void *data, size_t size, int flags) { #ifdef CCTOOLS_OPSYS_DARWIN return fsetxattr(fd, name, data, size, 0, flags); #else return fsetxattr(fd, name, data, size, flags); #endif }
static INT64_T chirp_fs_local_fsetxattr(int fd, const char *name, const void *data, size_t size, int flags) { PREAMBLE("fsetxattr(%d, `%s', %p, %zu, %d)", fd, name, data, size, flags); SETUP_FILE #ifdef CCTOOLS_OPSYS_DARWIN rc = fsetxattr(lfd, name, data, size, 0, flags); #else rc = fsetxattr(lfd, name, data, size, flags); #endif PROLOGUE }
/** * Write out metadata to file's extended attributes */ int writexa(FILE *f, xa_t xa) { int fd=fileno(f); int flags=0,err=0; char buf [100]; snprintf(buf,sizeof(buf),"%llu.%09lu",xa.s,xa.ns); err=fsetxattr(fd, "user.shatag.ts", buf, strlen(buf), flags); err|=fsetxattr(fd, "user.shatag.sha256", &xa.sha256, sizeof(xa.sha256), flags); return err; }
int mslnk_set_xattr(mslnk_t *mslnk, const char *name, const void *value, size_t size, int flags) { int status; status = fsetxattr(mslnk->fdattrs, name, value, size, flags); return status; }
int cap_set_fd(int fildes, cap_t cap_d) { struct vfs_cap_data rawvfscap; int sizeofcaps; struct stat buf; if (fstat(fildes, &buf) != 0) { _cap_debug("unable to stat file descriptor %d", fildes); return -1; } if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) { _cap_debug("file descriptor %d for non-regular file", fildes); errno = EINVAL; return -1; } if (cap_d == NULL) { _cap_debug("deleting fildes capabilities"); return fremovexattr(fildes, XATTR_NAME_CAPS); } else if (_fcaps_save(&rawvfscap, cap_d, &sizeofcaps) != 0) { return -1; } _cap_debug("setting fildes capabilities"); return fsetxattr(fildes, XATTR_NAME_CAPS, &rawvfscap, sizeofcaps, 0); }
static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) { static const char * const xattrs[_CONTEXT_MAX] = { [CONTEXT_PID] = "user.coredump.pid", [CONTEXT_UID] = "user.coredump.uid", [CONTEXT_GID] = "user.coredump.gid", [CONTEXT_SIGNAL] = "user.coredump.signal", [CONTEXT_TIMESTAMP] = "user.coredump.timestamp", [CONTEXT_RLIMIT] = "user.coredump.rlimit", [CONTEXT_HOSTNAME] = "user.coredump.hostname", [CONTEXT_COMM] = "user.coredump.comm", [CONTEXT_EXE] = "user.coredump.exe", }; int r = 0; unsigned i; assert(fd >= 0); /* Attach some metadata to coredumps via extended * attributes. Just because we can. */ for (i = 0; i < _CONTEXT_MAX; i++) { int k; if (isempty(context[i]) || !xattrs[i]) continue; k = fsetxattr(fd, xattrs[i], context[i], strlen(context[i]), XATTR_CREATE); if (k < 0 && r == 0) r = -errno; } return r; }
static int fix_xattr(int fd, const char *info[_INFO_LEN]) { static const char * const xattrs[_INFO_LEN] = { [INFO_PID] = "user.coredump.pid", [INFO_UID] = "user.coredump.uid", [INFO_GID] = "user.coredump.gid", [INFO_SIGNAL] = "user.coredump.signal", [INFO_TIMESTAMP] = "user.coredump.timestamp", [INFO_COMM] = "user.coredump.comm", [INFO_EXE] = "user.coredump.exe", }; int r = 0; unsigned i; assert(fd >= 0); /* Attach some metadata to coredumps via extended * attributes. Just because we can. */ for (i = 0; i < _INFO_LEN; i++) { int k; if (isempty(info[i]) || !xattrs[i]) continue; k = fsetxattr(fd, xattrs[i], info[i], strlen(info[i]), XATTR_CREATE); if (k < 0 && r == 0) r = -errno; } return r; }
void FileRememberXattrs::write(int fd_dest) { for (std::map<std::string, std::string>::const_iterator it = m_xattrs.begin(); it != m_xattrs.end(); ++it) { fsetxattr(fd_dest, it->first.c_str(), it->second.c_str(), it->second.size(), 0); } }
int main( int argc, char *argv[] ) { int fd = -1; char *data = "testing data"; int ret = 0; if (argc != 2) { fprintf(stderr, "Usage: %s <filename>\n", argv[0]); exit(1); } if ((fd = open(argv[1], O_RDWR, 0)) == -1) { int err = errno; fprintf(stderr, "open(): %s\n", strerror(err)); exit(err); } ret = fsetxattr(fd, "user.test0", (const void*)data, strlen(data) + 1, 0); if (ret == -1) { int err = errno; fprintf(stderr, "fsetxattr(): %s\n", strerror(err)); exit(err); } return 0; }
static int xmp_create(const char* path, mode_t mode, struct fuse_file_info* fi) { (void) fi; (void) mode; char buf[BUFSIZE]; FILE *res; res = fopen(_xmp_fullpath(buf, path, BUFSIZE), "w"); if(res == NULL) return -errno; FILE *tmp = tmpfile(); xmp_state *state = (xmp_state *)(fuse_get_context()->private_data); do_crypt(tmp, res, AES_ENCRYPT, state->key); fclose(tmp); if(fsetxattr(fileno(res), ENCRYPTED_ATTR, "true", 4, 0)){ return -errno; } fclose(res); return 0; }
Boolean XAAttributeSaveFileDescriptor(XAAttributeRef attributeRef, int fd) { Boolean bRet = 0x01; if(attributeRef->edited) { const UInt8 *bytes = CFDataGetBytePtr(attributeRef->data); size_t size = CFDataGetLength(attributeRef->data); CFIndex bSize = CFStringGetLength(attributeRef->name) + 0x01; char *key = calloc(bSize, sizeof(*key)); UInt32 position = 0x00; int options = 0x00; if(CFStringGetCString(attributeRef->name, key, bSize, kCFStringEncodingUTF8)) { size = fsetxattr(fd, key, (void *)bytes, size, position, options); } free(key); } return(bRet); }
static void test_xattr_races (void) { /* If for some reason we're built in a VM which only has one vcpu, let's still * at least make the test do something. */ /* FIXME - this deadlocks for me on 4.9.4-201.fc25.x86_64, whether * using overlayfs or xfs as source/dest. */ const guint nprocs = MAX (4, g_get_num_processors ()); struct XattrWorker wdata[nprocs]; GThread *threads[nprocs]; g_autoptr(GError) local_error = NULL; GError **error = &local_error; g_auto(GLnxTmpDir) tmpdir = { 0, }; g_autofree char *tmpdir_path = g_strdup_printf ("%s/libglnx-xattrs-XXXXXX", getenv ("TMPDIR") ?: "/var/tmp"); guint nread = 0; if (!glnx_mkdtempat (AT_FDCWD, tmpdir_path, 0700, &tmpdir, error)) goto out; /* Support people building/testing on tmpfs https://github.com/flatpak/flatpak/issues/686 */ if (fsetxattr (tmpdir.fd, "user.test", "novalue", strlen ("novalue"), 0) < 0) { if (errno == EOPNOTSUPP) { g_test_skip ("no xattr support"); return; } else { glnx_set_error_from_errno (error); goto out; } } for (guint i = 0; i < nprocs; i++) { struct XattrWorker *worker = &wdata[i]; worker->dfd = tmpdir.fd; worker->is_writer = i % 2 == 0; threads[i] = g_thread_new (NULL, xattr_thread, worker); } for (guint i = 0; i < nprocs; i++) { if (wdata[i].is_writer) (void) g_thread_join (threads[i]); else nread += GPOINTER_TO_UINT (g_thread_join (threads[i])); } g_print ("Read %u xattrs race free!\n", nread); out: g_assert_no_error (local_error); }
static prop_area* map_prop_area_rw(const char* filename, const char* context, bool* fsetxattr_failed) { /* dev is a tmpfs that we can use to carve a shared workspace * out of, so let's do that... */ const int fd = open(filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444); if (fd < 0) { if (errno == EACCES) { /* for consistency with the case where the process has already * mapped the page in and segfaults when trying to write to it */ abort(); } return nullptr; } if (context) { #if 0 // NOTE: Not wanted for DualBootPatcher since the properties service // initializes before SELinux if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) { LOGE("fsetxattr failed to set context (%s) for \"%s\"", context, filename); /* * fsetxattr() will fail during system properties tests due to selinux policy. * We do not want to create a custom policy for the tester, so we will continue in * this function but set a flag that an error has occurred. * Init, which is the only daemon that should ever call this function will abort * when this error occurs. * Otherwise, the tester will ignore it and continue, albeit without any selinux * property separation. */ if (fsetxattr_failed) { *fsetxattr_failed = true; } } #endif } if (ftruncate(fd, PA_SIZE) < 0) { close(fd); return nullptr; } pa_size = PA_SIZE; pa_data_size = pa_size - sizeof(prop_area); compat_mode = false; void *const memory_area = mmap(NULL, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (memory_area == MAP_FAILED) { close(fd); return nullptr; } prop_area *pa = new(memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION); close(fd); return pa; }
int mdir_set_xattr(mdir_t *mdir, const char *name, const void *value, size_t size, int flags) { int status; status = fsetxattr(mdir->fdp, name, value, size, flags); return status; }
bool real_check_xattr_trusted(const char *tmp_path, int tmp_file) { int ret = fsetxattr(tmp_file, "trusted.overlay.test", "naive", 5, 0); close(tmp_file); if (ret) { return false; } char verify_buffer[10]; if (getxattr(tmp_path, "trusted.overlay.test", verify_buffer, 10) != 5) { return false; } return !strncmp(verify_buffer, "naive", 5); }
bool ExtAttribSet(char *FileName, char *AttrName, byte *Data, int DataLen) { TRACEENTER(); char FullAttrName[128]; char AbsFileName[FBLIB_DIR_SIZE]; int f; if(!FileName || !*FileName || !AttrName || !*AttrName) { TRACEEXIT(); return FALSE; } ConvertPathType(FileName, AbsFileName, PF_FullLinuxPath); if(*AbsFileName) { f = open(AbsFileName, O_RDWR, 0600); if(f >= 0) { TAP_SPrint(FullAttrName, "user.%s", AttrName); if(fsetxattr(f, FullAttrName, Data, DataLen, XATTR_CREATE) == 0) { close(f); TRACEEXIT(); return TRUE; } else { //As the attribute may already exist, retry with the replace flag if(fsetxattr(f, FullAttrName, Data, DataLen, XATTR_REPLACE) == 0) { close(f); TRACEEXIT(); return TRUE; } } close(f); } } TRACEEXIT(); return FALSE; }
/** * @brief is_local_file Check a location of file by file descriptor * (local or remote). * * @note Operation is atomic according to * http://man7.org/linux/man-pages/man7/xattr.7.html. * * @param[in] fd File descriptor to check location. * @param[in] flags Flags with which file descriptor was opened. * * @return 1: if file is in local storage * 0: if file is in remote storage * -1: error happen during an attempt to get extended attribute's value */ int is_local_file( int fd, int flags ) { /* if file was opened in write-only mode, use fsetxattr with XATTR_REPLACE which will produce result equivalent to fgetxattr */ int ret = ( ( flags & O_WRONLY ) == O_WRONLY ) ? fsetxattr( fd, xattr_str[e_stub], NULL, 0, XATTR_REPLACE ) : fgetxattr( fd, xattr_str[e_stub], NULL, 0 ); if ( ret == -1 ) { if ( IS_LOCAL_PREDICATE ) { /* if ENOTSUP then the file not in our target filesystem and we not manage lifecycle of this file, if ERANGE then e_stub attribute should have a value which is not possible according to then logic of this program and if ENOATTR then the file is definitely local by our convention which means that we can safetly report that file is local */ return 1; } else if ( errno == EPERM ) { /* only fsetxattr can produce this errno; we are here only in case linux-specific feature inode flags-attributes plays its role; more specifically either FS_APPEND_FL or FS_IMMUTABLE_FL flags are set (see setxattr(2) and ioctl_iflags(2)); in many cases the current process can read the file either, so we want to get extended attribute using /proc/self/fd/<fd> file path and, if not works, give up and return error */ char path[PROC_SELF_FD_FD_PATH_MAX_LEN]; snprintf(path, PROC_SELF_FD_FD_PATH_MAX_LEN, PROC_SELF_FD_FD_PATH_TEMPLATE, (unsigned long long int)fd); if ( getxattr( path, xattr_str[e_stub], NULL, 0) == -1 ) { if ( IS_LOCAL_PREDICATE ) { /* as before, this conditional branch indicates that file is local */ return 1; } /* we can do nothing here, return a error produced by inner stat call */ return -1; } /* e_stub atribute is set which means that file is remote */ return 0; } else { /* errors from stat(2) which should be handled separately in each public libc wrapper function so we return the error here */ return -1; } } /* e_stub atribute is set which means that file is remote */ return 0; }
int ceph_os_fsetxattr(int fd, const char *name, const void *value, size_t size) { int error = -1; #if defined(__FreeBSD__) error = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size); if (error > 0) error = 0; #elif defined(__linux__) error = fsetxattr(fd, name, value, size, 0); #elif defined(DARWIN) error = fsetxattr(fd, name, value, size, 0, 0 /* no options should be indentical to Linux */ ); #endif return (error); }
oc::result<void> selinux_fset_context(int fd, const std::string &context) { if (fsetxattr(fd, SELINUX_XATTR, context.c_str(), context.size() + 1, 0) < 0) { return ec_from_errno(); } return oc::success(); }
int main(int argc, char *argv[]) { char message[256]; char *anin = "security.SMACK64IPIN"; char *anout = "security.SMACK64IPOUT"; char *annot = "security.SMACK64IPNOT"; char *avin = "TheOne"; char *avout = "TheOther"; char *avnot = "TheBadValue"; int sock; int rc; if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { sprintf(message, "%s Socket creation failure", argv[0]); perror(message); exit(1); } rc = fsetxattr(sock, anin, avin, strlen(avin) + 1, 0); if (rc < 0) { sprintf(message, "%s fsetxattr of %s to %s failure", argv[0], anin, avin); perror(message); exit(1); } rc = fsetxattr(sock, anout, avout, strlen(avout) + 1, 0); if (rc < 0) { sprintf(message, "%s fsetxattr of %s to %s failure", argv[0], anout, avout); perror(message); exit(1); } rc = fsetxattr(sock, annot, avnot, strlen(avnot) + 1, 0); if (rc >= 0) { sprintf(message, "%s fsetxattr of %s to %s succeeded in error", argv[0], anout, avout); perror(message); exit(1); } exit(0); }
fsal_status_t vfs_setextattr_value(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, const char *xattr_name, caddr_t buffer_addr, size_t buffer_size, int create) { struct vfs_fsal_obj_handle *obj_handle = NULL; int fd = -1; fsal_errors_t fe; int rc = 0; /* int flags = 0; */ obj_handle = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle); /* /!\ ACL HOOK. If name is "system.posix_acl_access", * flags must remain unset */ /* if (strncmp(xattr_name, "system.posix_acl_access", MAXNAMLEN)) */ /* flags = create ? XATTR_CREATE : XATTR_REPLACE; */ /* else */ /* flags = 0; */ fd = (obj_hdl->type == DIRECTORY) ? vfs_fsal_open(obj_handle, O_DIRECTORY, &fe) : vfs_fsal_open(obj_handle, O_RDWR, &fe); if (fd < 0) return fsalstat(fe, -fd); if (buffer_size == 0) rc = fsetxattr(fd, xattr_name, "", 1, create ? XATTR_CREATE : XATTR_REPLACE); else rc = fsetxattr(fd, xattr_name, (char *)buffer_addr, buffer_size, create ? XATTR_CREATE : XATTR_REPLACE); close(fd); if (rc != 0) return fsalstat(posix2fsal_error(errno), errno); else return fsalstat(ERR_FSAL_NO_ERROR, 0); }
int smack_label_ip_in_fd(int fd, const char *label) { #ifdef HAVE_SMACK if (!use_smack()) return 0; return fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0); #else return 0; #endif }
/* store metadata from the curl request alongside the downloaded * file using extended attributes */ int fwrite_xattr(CURL *curl, int fd) { int i = 0; int err = 0; /* loop through all xattr-curlinfo pairs and abort on a set error */ while(err == 0 && mappings[i].attr != NULL) { char *value = NULL; CURLcode rc = curl_easy_getinfo(curl, mappings[i].info, &value); if(rc == CURLE_OK && value) { #ifdef HAVE_FSETXATTR_6 err = fsetxattr( fd, mappings[i].attr, value, strlen(value), 0, 0 ); #elif defined(HAVE_FSETXATTR_5) err = fsetxattr( fd, mappings[i].attr, value, strlen(value), 0 ); #endif } i++; } return err; }
int add_or_update_ea(enum FILE_TYPE ft, int fd, int ea_flags, const char *prt_str) { int ret = 0; switch (ft) { case NORMAL: ret = fsetxattr(fd, xattr_name, xattr_value, xattr_value_sz, ea_flags); if (ret < 0) { ret = errno; fprintf(stderr, "Failed at fsetxattr(%s,errno:%d,%s) " "on %s:xattr_name=%s,xattr_value_sz=%ld," "xattr_value=%s\n", prt_str, ret, strerror(ret), filename, xattr_name, strlen(xattr_value) + 1, xattr_value); ret = -1; } break; case SYMLINK: ret = lsetxattr(filename, xattr_name, xattr_value, xattr_value_sz, ea_flags); if (ret < 0) { ret = errno; fprintf(stderr, "Failed at lsetxattr(%s,errno:%d,%s) " "on %s:xattr_name=%s,xattr_value_sz=%ld," "xattr_value=%s\n", prt_str, ret, strerror(ret), filename, xattr_name, strlen(xattr_value) + 1, xattr_value); ret = -1; } break; case DIRECTORY: ret = setxattr(filename, xattr_name, xattr_value, xattr_value_sz, ea_flags); if (ret < 0) { ret = errno; fprintf(stderr, "Failed at setxattr(%s,errno:%d,%s) " "on %s:xattr_name=%s,xattr_value_sz=%ld," "xattr_value=%s\n", prt_str, ret, strerror(ret), filename, xattr_name, strlen(xattr_value) + 1, xattr_value); ret = -1; } break; default: break; } return ret; }
JNIEXPORT void JNICALL Java_sun_nio_fs_LinuxNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz, jint fd, jlong nameAddress, jlong valueAddress, jint valueLen) { int res = -1; const char* name = jlong_to_ptr(nameAddress); void* value = jlong_to_ptr(valueAddress); res = fsetxattr (fd, name, value, valueLen, 0); if (res == -1) throwUnixException(env, errno); }
int main(int argc, char* argv[]) { char path[PATH_MAX]; const char* home = getenv("HOME"); int fd; int ret; snprintf(path, sizeof(path), "%s/rr-xattr-XXXXXX", home ? home : "/tmp"); path[sizeof(path) - 1] = 0; fd = mkstemp(path); test_assert(0 <= fd); ret = setxattr(path, attr_name, attr_value, sizeof(attr_value), XATTR_CREATE); if (ret < 0 && errno == EOPNOTSUPP) { atomic_printf("Extended attributes not supported on file %s, " "skipping test\n", path); } else { char buf[sizeof(attr_value) + 1]; test_assert(ret == 0); memset(buf, '-', sizeof(buf)); ret = fgetxattr(fd, attr_name, buf, sizeof(buf) - 5); test_assert(ret == -1); test_assert(errno == ERANGE); test_assert(buf[0] == '-'); ret = fsetxattr(fd, attr_name, attr_value, sizeof(attr_value), XATTR_REPLACE); test_assert(ret == 0); ret = getxattr(path, attr_name, buf, sizeof(buf)); test_assert(ret == sizeof(attr_value)); test_assert(0 == memcmp(attr_value, buf, sizeof(attr_value))); test_assert(buf[sizeof(attr_value)] == '-'); ret = fremovexattr(fd, attr_name); test_assert(ret == 0); memset(buf, '-', sizeof(buf)); ret = getxattr(path, attr_name, buf, sizeof(buf)); test_assert(ret == -1); test_assert(errno == ENODATA); test_assert(buf[0] == '-'); } test_assert(0 == unlink(path)); atomic_puts("EXIT-SUCCESS"); return 0; }
virtual int run( int checkpoint ) override { test_path = mnt_dir_ ; A_path = mnt_dir_ + "/A"; AC_path = mnt_dir_ + "/A/C"; B_path = mnt_dir_ + "/B"; foo_path = mnt_dir_ + "/foo"; bar_path = mnt_dir_ + "/bar"; Afoo_path = mnt_dir_ + "/A/foo"; Abar_path = mnt_dir_ + "/A/bar"; Bfoo_path = mnt_dir_ + "/B/foo"; Bbar_path = mnt_dir_ + "/B/bar"; ACfoo_path = mnt_dir_ + "/A/C/foo"; ACbar_path = mnt_dir_ + "/A/C/bar"; int local_checkpoint = 0 ; int fd_foo = cm_->CmOpen(foo_path.c_str() , O_RDWR|O_CREAT , 0777); if ( fd_foo < 0 ) { cm_->CmClose( fd_foo); return errno; } if ( fsetxattr( fd_foo, "user.xattr1", "val1 ", 4, 0 ) < 0){ return errno; } if ( removexattr(foo_path.c_str() , "user.xattr1") < 0){ return errno; } if ( cm_->CmFsync( fd_foo) < 0){ return errno; } if ( cm_->CmCheckpoint() < 0){ return -1; } local_checkpoint += 1; if (local_checkpoint == checkpoint) { return 1; } if ( cm_->CmClose ( fd_foo) < 0){ return errno; } return 0; }
int main (int argc, char *argv[]) { char *file; int fd; punyopt(argc, argv, NULL, NULL); file = Option.file; fd = openq(file, O_RDWR | O_CREAT); mystat(fd, "after open/create"); sleep(2); writeq(fd, Write, sizeof(Write)); mystat(fd, "after write"); closeq(fd); sleep(2); fd = openq(file, O_RDWR | O_NOATIME); sleep(2); mystat(fd, "after open noatime"); sleep(2); mystat(fd, "before read noatime"); readq(fd, Read, sizeof(Read)); mystat(fd, "after read noatime"); closeq(fd); sleep(2); fd = openq(file, O_RDWR); mystat(fd, "after open rdwr"); sleep(2); mystat(fd, "before read"); readq(fd, Read, sizeof(Read)); mystat(fd, "after read"); closeq(fd); sleep(2); fd = openq(file, O_RDWR); mystat(fd, "after open"); sleep(2); fsetxattr(fd, "noatime", Test, sizeof(Test), 0); mystat(fd, "after setxattr"); sleep(2); mystat(fd, "before read"); readq(fd, Read, sizeof(Read)); mystat(fd, "after read"); sleep(2); fgetxattr(fd, "noatime", Read, sizeof(Read)); mystat(fd, "after getxattr"); closeq(fd); return 0; }