int main(int argc, char *argv[]) { int dd; if (argc != 3) { printf("useage: ./a.out oldfilename newfilename\n"); return -1; } if ((dd = open("/home/vg0x00/Development/c/chapter_4_file_and_path", O_RDONLY)) < 0) { printf("can not open the file: %s\n", argv[1]); return -1; } // rename if (rename(argv[1], argv[2]) < 0) { printf("can not rename the file: %s to %s\n", argv[1], argv[2]); return -1; } // renameat if (renameat(dd, "file1", dd, "file2") < 0) { printf("can not renameat\n"); return -1; } return 0; }
void savebookmarks() { // Backups renameat(g->profilefd, BOOKMARKFILE ".bak2", g->profilefd, BOOKMARKFILE ".bak3"); renameat(g->profilefd, BOOKMARKFILE ".bak", g->profilefd, BOOKMARKFILE ".bak2"); renameat(g->profilefd, BOOKMARKFILE, g->profilefd, BOOKMARKFILE ".bak"); const int fd = openat(g->profilefd, BOOKMARKFILE, O_WRONLY | O_CREAT, 0600); if (fd < 0) die("Failed saving bookmarks\n"); FILE * const f = fdopen(fd, "w"); if (!f) die("Failed saving bookmarks\n"); u32 i; const u32 max = g->bookmarks.size(); for (i = 0; i < max; i++) { fprintf(f, "name %s\n", g->bookmarks[i].name ? g->bookmarks[i].name : ""); fprintf(f, "url %s\n\n", g->bookmarks[i].url ? g->bookmarks[i].url : ""); } fflush(f); fsync(fd); fclose(f); }
static int rotate(const char *name) { int fd; int i; char buf[PATH_MAX]; char buf2[PATH_MAX]; fd = open(LOG_DIR, O_RDONLY); if(fd < 0) { /* No log directory, so there's nothing to rotate. */ return 0; } if(get_log(name, buf, PATH_MAX, NUM_LOGS-1) < 0) return -1; if(unlinkat(fd, buf, 0) < 0) { if(errno != ENOENT) { perror(buf); fprintf(stderr, "tup error: Unable to unlink log file: %s\n", buf); return -1; } } for(i=NUM_LOGS-1; i>0; i--) { get_log(name, buf, PATH_MAX, i); get_log(name, buf2, PATH_MAX, i-1); if(renameat(fd, buf2, fd, buf) < 0) { if(errno != ENOENT) { perror("renameat"); fprintf(stderr, "tup error: Unable to rotate logs.\n"); return -1; } } } return 0; }
CAMLprim value caml_extunix_renameat(value v_oldfd, value v_oldname, value v_newfd, value v_newname) { CAMLparam4(v_oldfd, v_oldname, v_newfd, v_newname); int ret = renameat(Int_val(v_oldfd), String_val(v_oldname), Int_val(v_newfd), String_val(v_newname)); if (ret != 0) uerror("renameat", v_oldname); CAMLreturn(Val_unit); }
void test_create_file_at() { char *file = alloc_filename("file"); char *hardlink = alloc_filename("hardlink"); char *hardlink2 = alloc_filename("hardlink2"); int dir_fd = get_dir_fd("."); struct stat st; int fd = openat(dir_fd, file, O_CREAT | O_WRONLY | O_EXCL, 0777); t_check(fd >= 0); t_check_zero(fstat(fd, &st)); t_check_zero(close(fd)); t_check_zero(fstatat(dir_fd, file, &st, 0)); t_check_zero(faccessat(dir_fd, file, R_OK | W_OK, 0)); t_check_zero(fchmodat(dir_fd, file, 0777, 0)); t_check_zero(fchownat(dir_fd, file, -1, -1, 0)); struct timeval times[2] = { { 123, 321 }, { 456, 654 } }; t_check_zero(futimesat(dir_fd, file, times)); t_check_zero(linkat(dir_fd, file, dir_fd, hardlink, 0)); t_check_zero(renameat(dir_fd, hardlink, dir_fd, hardlink2)); t_check_zero(unlinkat(dir_fd, hardlink2, 0)); t_check_zero(unlinkat(dir_fd, file, 0)); close(dir_fd); free(file); free(hardlink); free(hardlink2); }
int dir_renameat(struct dir *dir, const char *old_filename, const char *new_filename, int keep_backup) { if (keep_backup && dir_file_exists(dir, new_filename)) { /* Try to preserve the target file, create a hardlink * before overwriting it. Ignore the return value, * it's fine not to have backup. */ int x; char *backup = _backup_filename(new_filename); if (dir_file_exists(dir, backup)) { x = dir_unlink(dir, backup); } x = linkat(dirfd(dir->dir), new_filename, dirfd(dir->dir), backup, 0); x = x; } int r = renameat(dirfd(dir->dir), old_filename, dirfd(dir->dir), new_filename); DIRTRACE(dir, r, "renameat(\"%s\", \"%s\")", old_filename, new_filename); /* Sync directory. */ fsync(dirfd(dir->dir)); return r; }
static void vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx) { char *t = NULL; ssize_t s; int fd; CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC); CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC); VTAILQ_REMOVE(&vsmw->segs, seg, list); REPLACE(seg->class, NULL); REPLACE(seg->id, NULL); FREE_OBJ(seg); if (fixidx) { vsmw_mkent(vsmw, vsmw->idx); REPLACE(t, VSB_data(vsmw->vsb)); AN(t); fd = openat(vsmw->vdirfd, t, O_WRONLY|O_CREAT|O_EXCL, vsmw->mode); assert(fd >= 0); vsmw_idx_head(vsmw, fd); VSB_clear(vsmw->vsb); VTAILQ_FOREACH(seg, &vsmw->segs, list) vsmw_fmt_index(vsmw, seg); AZ(VSB_finish(vsmw->vsb)); s = write(fd, VSB_data(vsmw->vsb), VSB_len(vsmw->vsb)); assert(s == VSB_len(vsmw->vsb)); AZ(close(fd)); AZ(renameat(vsmw->vdirfd, t, vsmw->vdirfd, vsmw->idx)); REPLACE(t, NULL); } }
/** * rpmostree_prepare_rootfs_for_commit: * * Walk over the root filesystem and perform some core conversions * from RPM conventions to OSTree conventions. For example: * * * Move /etc to /usr/etc * * Checksum the kernel in /boot * * Migrate content in /var to systemd-tmpfiles */ gboolean rpmostree_prepare_rootfs_for_commit (GFile *rootfs, JsonObject *treefile, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gs_free char *dest_rootfs_path = NULL; dest_rootfs_path = g_strconcat (gs_file_get_path_cached (rootfs), ".post", NULL); if (!glnx_shutil_rm_rf_at (AT_FDCWD, dest_rootfs_path, cancellable, error)) goto out; { gs_unref_object GFile *dest_rootfs = g_file_new_for_path (dest_rootfs_path); if (!create_rootfs_from_yumroot_content (dest_rootfs, rootfs, treefile, cancellable, error)) goto out; } if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (rootfs), cancellable, error)) goto out; if (TEMP_FAILURE_RETRY (renameat (AT_FDCWD, dest_rootfs_path, AT_FDCWD, gs_file_get_path_cached (rootfs))) != 0) { glnx_set_error_from_errno (error); goto out; } ret = TRUE; out: return ret; }
int main(void) { fopen("", "r"); fopen64("", "r"); freopen("", "r", NULL); freopen64("", "r", NULL); open("", O_RDONLY); open64("", O_RDONLY); creat("", S_IRWXU); creat64("", S_IRWXU); unlink(""); rename("", ""); #ifdef AT_FUNCTIONS unlinkat(0, "", 0); renameat(0, "", 0, ""); openat(0, "", 0); openat64(0, "", 0); #endif return 0; }
void project_t::diff_save() const { if(unlikely(!osm)) return; if(osm->is_clean(true)) { printf("data set is clean, removing diff if present\n"); diff_remove_file(); return; } const std::string &diff_name = diff_filename(this); printf("data set is dirty, generating diff\n"); /* write the diff to a new file so the original one needs intact until * saving is completed */ const std::string ndiff = path + "save.diff"; xmlDocGuard doc(xmlNewDoc(BAD_CAST "1.0")); xmlNodePtr root_node = xmlNewNode(nullptr, BAD_CAST "diff"); xmlNewProp(root_node, BAD_CAST "name", BAD_CAST name.c_str()); xmlDocSetRootElement(doc.get(), root_node); std::for_each(osm->nodes.begin(), osm->nodes.end(), diff_save_objects<node_t>(root_node)); std::for_each(osm->ways.begin(), osm->ways.end(), diff_save_ways(root_node, osm)); std::for_each(osm->relations.begin(), osm->relations.end(), diff_save_objects<relation_t>(root_node)); xmlSaveFormatFileEnc(ndiff.c_str(), doc.get(), "UTF-8", 1); /* if we reach this point writing the new file worked and we */ /* can move it over the real file */ if(renameat(-1, ndiff.c_str(), dirfd, diff_name.c_str()) != 0) fprintf(stderr, "error %i when moving '%s' to '%s'\n", errno, ndiff.c_str(), diff_name.c_str()); }
/* Check if FILE_NAME already exists and make a backup of it right now. Return success (nonzero) only if the backup is either unneeded, or successful. For now, directories are considered to never need backup. If THIS_IS_THE_ARCHIVE is nonzero, this is the archive and so, we do not have to backup block or character devices, nor remote entities. */ bool maybe_backup_file (const char *file_name, bool this_is_the_archive) { struct stat file_stat; assign_string (&before_backup_name, file_name); /* A run situation may exist between Emacs or other GNU programs trying to make a backup for the same file simultaneously. If theoretically possible, real problems are unlikely. Doing any better would require a convention, GNU-wide, for all programs doing backups. */ assign_string (&after_backup_name, 0); /* Check if we really need to backup the file. */ if (this_is_the_archive && _remdev (file_name)) return true; if (deref_stat (file_name, &file_stat) != 0) { if (errno == ENOENT) return true; stat_error (file_name); return false; } if (S_ISDIR (file_stat.st_mode)) return true; if (this_is_the_archive && (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode))) return true; after_backup_name = find_backup_file_name (file_name, backup_type); if (! after_backup_name) xalloc_die (); if (renameat (chdir_fd, before_backup_name, chdir_fd, after_backup_name) == 0) { if (verbose_option) fprintf (stdlis, _("Renaming %s to %s\n"), quote_n (0, before_backup_name), quote_n (1, after_backup_name)); return true; } else { /* The backup operation failed. */ int e = errno; ERROR ((0, e, _("%s: Cannot rename to %s"), quotearg_colon (before_backup_name), quote_n (1, after_backup_name))); assign_string (&after_backup_name, 0); return false; } }
static int callback_rename (const char *from, const char *to) { from = ENSURE_RELPATH (from); to = ENSURE_RELPATH (to); if (renameat (basefd, from, basefd, to) == -1) return -errno; return 0; }
static int cache_open(struct fuse_root *root, const char *path, int flags) { unsigned retries = 0; char cachepath[PATH_MAX]; struct grow_dirent *e = grow_lookup(path, root->metadata, 1); if (!e) return -errno; if (flags&O_WRONLY || flags&O_RDWR) return -EROFS; if (!cache_data) { stats_inc("grow.fuse.direct_open", 1); while (path[0] == '/') ++path; return openat(root->fd, path, flags); } retry: if (retries > 10) return -ELOOP; snprintf(cachepath, sizeof(cachepath), "%c%c/%s", e->checksum[0], e->checksum[1], &e->checksum[2]); int fd = openat(root->cache, cachepath, flags); if (fd < 0 && errno == ENOENT) { stats_inc("grow.fuse.cache.miss", 1); while (path[0] == '/') ++path; fd = openat(root->fd, path, flags); if (fd < 0) return -errno; char tmppath[] = "/tmp/.growcache.XXXXXX"; int tmpfd = mkstemp(tmppath); if (tmpfd < 0) { int saved_errno = errno; close(fd); return -saved_errno; } if (copy_fd_to_fd(fd, tmpfd) < 0) { int saved_errno = errno; close(fd); close(tmpfd); unlink(tmppath); return -saved_errno; } close(fd); close(tmpfd); if (renameat(AT_FDCWD, tmppath, root->cache, cachepath) < 0) { int saved_errno = errno; unlink(tmppath); return -saved_errno; } stats_inc("grow.fuse.cache.commit", 1); ++retries; goto retry; } else if (fd < 0) { stats_inc("grow.fuse.cache.error", 1); return -errno; } else { if (retries == 0) stats_inc("grow.fuse.cache.hit", 1); return fd; } }
/* Try to restore the recently backed up file to its original name. This is usually only needed after a failed extraction. */ void undo_last_backup (void) { if (after_backup_name) { if (renameat (chdir_fd, after_backup_name, chdir_fd, before_backup_name) != 0) { } assign_string (&after_backup_name, 0); } }
static void test_fini(void) { char path[PATH_MAX]; if (getpid() != master_pid) return; snprintf(path, sizeof(path), "%s%s", outfile, INPROGRESS); renameat(cwd, path, cwd, outfile); unlinkat(cwd, pidfile, 0); }
int main(void) { DIR *dot = opendir("."); if (NULL == dot) return EXIT_FAILURE; int dfd = dirfd(dot); if (-1 == dfd) return EXIT_FAILURE; if (0 > renameat(AT_FDCWD, "see.emily.play/gnome", dfd, "lucifer.sam")) return EXIT_FAILURE; else return EXIT_SUCCESS; }
CAMLprim value netsys_renameat(value olddirfd, value oldpath, value newdirfd, value newpath) { #ifdef HAVE_AT if (renameat(Int_val(olddirfd), String_val(oldpath), Int_val(newdirfd), String_val(newpath)) == -1) uerror("renameat", oldpath); return Val_unit; #else invalid_argument("Netsys_posix.renameat not available"); #endif }
int ast_renameat(int owd, const char* opath, int nwd, const char* npath) { int r = -1; PATHIFY(owd, opath, 1, 1); LINKIFY(nwd, npath, 1, 1); RESTART(r, renameat(owd, opath, nwd, npath)); LINKEND(); PATHEND(); return r; }
static void renameat_verify(const struct test_case_t *tc) { if (tc->exp_errno == EMLINK && max_subdirs == 0) { tst_resm(TCONF, "EMLINK test is not appropriate"); return; } TEST(renameat(*(tc->oldfdptr), tc->oldpath, *(tc->newfdptr), tc->newpath)); if (tc->exp_errno && TEST_RETURN != -1) { tst_resm(TFAIL, "renameat() succeeded unexpectedly"); return; } if (tc->exp_errno == 0 && TEST_RETURN != 0) { tst_resm(TFAIL | TTERRNO, "renameat() failed unexpectedly"); return; } if (TEST_ERRNO == tc->exp_errno) { tst_resm(TPASS | TTERRNO, "renameat() returned the expected value"); } else { tst_resm(TFAIL | TTERRNO, "renameat() got unexpected return value; expected: " "%d - %s", tc->exp_errno, strerror(tc->exp_errno)); } if (TEST_ERRNO == 0 && renameat(*(tc->newfdptr), tc->newpath, *(tc->oldfdptr), tc->oldpath) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "renameat(%d, %s, " "%d, %s) failed.", *(tc->newfdptr), tc->newpath, *(tc->oldfdptr), tc->oldpath); } }
int main() { struct stat st; struct stat st2; openat(AT_FDCWD, PWD "openat.txt", O_CREAT | O_WRONLY, 0644); assert(stat("openat.txt", &st) == 0); // relative path assert(faccessat(AT_FDCWD, PWD "openat.txt", F_OK, 0) == 0); assert(fstatat(AT_FDCWD, PWD "openat.txt", &st2, 0) == 0); assert(fchmodat(AT_FDCWD, PWD "openat.txt", 0777, 0) == 0); struct timeval my_times[2]; my_times[0].tv_sec = 0; my_times[0].tv_usec = 0; my_times[1].tv_sec = 0; my_times[1].tv_usec = 0; assert(futimesat(AT_FDCWD, PWD "openat.txt", my_times, 0) == 0); // see /etc/passwd, user 'pgbovine' is 508:100 assert(fchownat(AT_FDCWD, PWD "openat.txt", 508, 100, 0) == 0); assert(linkat(AT_FDCWD, PWD "openat.txt", AT_FDCWD, PWD "openat_hardlink.txt", 0) == 0); assert(stat("openat_hardlink.txt", &st) == 0); // relative path assert(symlinkat(PWD "openat.txt", AT_FDCWD, PWD "openat_symlink.txt") == 0); assert(lstat("openat_symlink.txt", &st) == 0); // relative path char res[300]; assert(readlinkat(AT_FDCWD, PWD "openat_symlink.txt", res, sizeof(res)) > 0); assert(renameat(AT_FDCWD, PWD "openat.txt", AT_FDCWD, PWD "openat_newname.txt", 0) == 0); assert(stat("openat.txt", &st) != 0); // should not exist anymore assert(stat("openat_newname.txt", &st) == 0); // relative path unlinkat(AT_FDCWD, PWD "openat_newname.txt", 0); unlinkat(AT_FDCWD, PWD "openat_hardlink.txt", 0); unlinkat(AT_FDCWD, PWD "openat_symlink.txt", 0); mknodat(AT_FDCWD, PWD "mknodat.fifo", S_IFIFO); assert(stat("mknodat.fifo", &st) == 0); // relative path unlinkat(AT_FDCWD, PWD "mknodat.fifo", 0); mkdirat(AT_FDCWD, PWD "mkdirat_dir", 0); assert(stat("mkdirat_dir", &st) == 0); // relative path unlinkat(AT_FDCWD, PWD "mkdirat_dir", AT_REMOVEDIR); // like 'rmdir' return 0; }
/* * @brief This is equivalent of unix rename() * * unix_rename mulitplexes rename and renameat. If we dont HAVE_ATFUNCS, sfd and dfd * are ignored. * * @param sfd (r) if we HAVE_ATFUNCS, -1 gives AT_FDCWD * @param oldpath (r) guess what * @param dfd (r) same as sfd * @param newpath (r) guess what */ int unix_rename(int sfd, const char *oldpath, int dfd, const char *newpath) { #ifdef HAVE_ATFUNCS if (sfd == -1) sfd = AT_FDCWD; if (dfd == -1) dfd = AT_FDCWD; if (renameat(sfd, oldpath, dfd, newpath) < 0) return -1; #else if (rename(oldpath, newpath) < 0) return -1; #endif /* HAVE_ATFUNCS */ return 0; }
/* * Like symlinkat() but overwrites (atomically) an existing * symlink. */ static gboolean symlink_at_replace (const char *oldpath, int parent_dfd, const char *newpath, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int res; /* Possibly in the future generate a temporary random name here, * would need to move "generate a temporary name" code into * libglnx or glib? */ const char *temppath = glnx_strjoina (newpath, ".tmp"); /* Clean up any stale temporary links */ (void) unlinkat (parent_dfd, temppath, 0); /* Create the temp link */ do res = symlinkat (oldpath, parent_dfd, temppath); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (res == -1) { glnx_set_error_from_errno (error); goto out; } /* Rename it into place */ do res = renameat (parent_dfd, temppath, parent_dfd, newpath); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (res == -1) { glnx_set_error_from_errno (error); goto out; } ret = TRUE; out: return ret; }
/* Try to restore the recently backed up file to its original name. This is usually only needed after a failed extraction. */ void undo_last_backup (void) { if (after_backup_name) { if (renameat (chdir_fd, after_backup_name, chdir_fd, before_backup_name) != 0) { int e = errno; ERROR ((0, e, _("%s: Cannot rename to %s"), quotearg_colon (after_backup_name), quote_n (1, before_backup_name))); } if (verbose_option) fprintf (stdlis, _("Renaming %s back to %s\n"), quote_n (0, after_backup_name), quote_n (1, before_backup_name)); assign_string (&after_backup_name, 0); } }
int journal::commit() { commit_record cr; if(erasure) return -EINVAL; if(commits > playbacks) /* must play back previous commit first */ return -EINVAL; assert(playbacks == commits); if(!records) return 0; /* initialize crfd or if it is almost full add more empty records to it */ if(crfd < 0 || !(commits % (J_ADD_N_COMMITS * 1000))) if(init_crfd(istr::null) < 0) return -1; cr.offset = prev_cr.offset + prev_cr.length; cr.length = data_file.end() - cr.offset; if(checksum(cr.offset, cr.offset + cr.length, cr.checksum) < 0) return -1; #if HAVE_FSTITCH /* {{{ */ patchgroup_id_t commit; commit = patchgroup_create(0); if(commit <= 0) return -1; patchgroup_label(commit, "commit"); /* add the external dependency, if any */ assert(!ext_count); if(external > 0) { if(ext_success && patchgroup_add_depend(commit, external) < 0) goto fail; patchgroup_abandon(external); external = 0; } if(patchgroup_add_depend(commit, records) < 0) { fail: patchgroup_release(commit); patchgroup_abandon(commit); return -1; } if(last_commit > 0 && patchgroup_add_depend(commit, last_commit) < 0) goto fail; if(prev && prev->last_commit && !commits && patchgroup_add_depend(commit, prev->last_commit) < 0) goto fail; patchgroup_release(commit); if(patchgroup_engage(commit) < 0) { /* this basically can't happen */ patchgroup_abandon(commit); return -1; } #endif /* }}} */ data_file.flush(); if(pwrite(crfd, &cr, sizeof(cr), commits * sizeof(cr)) != sizeof(cr)) { #if HAVE_FSTITCH /* {{{ */ int save = errno; patchgroup_disengage(commit); /* the truncate() really should be part of records, but * since commit depends on records, we'll substitute it */ patchgroup_abandon(records); /* make sure the pointer is not past the end of the file */ errno = save; #endif /* }}} */ return -1; } #if HAVE_FSTITCH /* {{{ */ patchgroup_disengage(commit); patchgroup_abandon(records); if(last_commit) patchgroup_abandon(last_commit); last_commit = commit; #else /* }}} */ char commit_number[16]; istr old_commit, new_commit; last_commit = commits; snprintf(commit_number, sizeof(commit_number), "%d", last_commit); old_commit = path + J_COMMIT_EXT + commit_number; snprintf(commit_number, sizeof(commit_number), "%d", commits + 1); new_commit = path + J_COMMIT_EXT + commit_number; int r = renameat(dfd, old_commit, dfd, new_commit); if(r < 0) return r; #endif records = 0; ++commits; prev_cr = cr; return 0; }
fsal_status_t GPFSFSAL_rename(fsal_handle_t * p_old_parentdir_handle, /* IN */ fsal_name_t * p_old_name, /* IN */ fsal_handle_t * p_new_parentdir_handle, /* IN */ fsal_name_t * p_new_name, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_attrib_list_t * p_src_dir_attributes, /* [ IN/OUT ] */ fsal_attrib_list_t * p_tgt_dir_attributes /* [ IN/OUT ] */ ) { int rc, errsv; fsal_status_t status; struct stat buffstat; int old_parent_fd, new_parent_fd; int src_equal_tgt = FALSE; fsal_accessflags_t access_mask = 0; fsal_attrib_list_t src_dir_attrs, tgt_dir_attrs; /* sanity checks. * note : src/tgt_dir_attributes are optional. */ if(!p_old_parentdir_handle || !p_new_parentdir_handle || !p_old_name || !p_new_name || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename); /* Get directory access path by fid */ TakeTokenFSCall(); status = fsal_internal_handle2fd(p_context, p_old_parentdir_handle, &old_parent_fd, O_RDONLY | O_DIRECTORY); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_rename); /* retrieve directory metadata for checking access rights */ src_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; status = GPFSFSAL_getattrs(p_old_parentdir_handle, p_context, &src_dir_attrs); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_rename); /* optimisation : don't do the job twice if source dir = dest dir */ if(!FSAL_handlecmp(p_old_parentdir_handle, p_new_parentdir_handle, &status)) { new_parent_fd = old_parent_fd; src_equal_tgt = TRUE; tgt_dir_attrs = src_dir_attrs; } else { TakeTokenFSCall(); status = fsal_internal_handle2fd(p_context, p_new_parentdir_handle, &new_parent_fd, O_RDONLY | O_DIRECTORY); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(status)) { close(old_parent_fd); ReturnStatus(status, INDEX_FSAL_rename); } /* retrieve destination attrs */ tgt_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; status = GPFSFSAL_getattrs(p_new_parentdir_handle, p_context, &tgt_dir_attrs); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_rename); } /* check access rights */ /* Set both mode and ace4 mask */ access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) | FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_DELETE_CHILD); if(!p_context->export_context->fe_static_fs_info->accesscheck_support) status = fsal_internal_testAccess(p_context, access_mask, NULL, &src_dir_attrs); else status = fsal_internal_access(p_context, p_old_parentdir_handle, access_mask, &src_dir_attrs); if(FSAL_IS_ERROR(status)) { close(old_parent_fd); if (!src_equal_tgt) close(new_parent_fd); ReturnStatus(status, INDEX_FSAL_rename); } if(!src_equal_tgt) { access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) | FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE | FSAL_ACE_PERM_ADD_SUBDIRECTORY); if(!p_context->export_context->fe_static_fs_info->accesscheck_support) status = fsal_internal_testAccess(p_context, access_mask, NULL, &tgt_dir_attrs); else status = fsal_internal_access(p_context, p_new_parentdir_handle, access_mask, &tgt_dir_attrs); if(FSAL_IS_ERROR(status)) { close(old_parent_fd); close(new_parent_fd); ReturnStatus(status, INDEX_FSAL_rename); } } /* build file paths */ TakeTokenFSCall(); rc = fstatat(old_parent_fd, p_old_name->name, &buffstat, AT_SYMLINK_NOFOLLOW); errsv = errno; ReleaseTokenFSCall(); if(rc) { close(old_parent_fd); if (!src_equal_tgt) close(new_parent_fd); Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_rename); } /* Check sticky bits */ /* Sticky bit on the source directory => the user who wants to delete the file must own it or its parent dir */ if((fsal2unix_mode(src_dir_attrs.mode) & S_ISVTX) && src_dir_attrs.owner != p_context->credential.user && buffstat.st_uid != p_context->credential.user && p_context->credential.user != 0) { close(old_parent_fd); if (!src_equal_tgt) close(new_parent_fd); Return(ERR_FSAL_ACCESS, 0, INDEX_FSAL_rename); } /* Sticky bit on the target directory => the user who wants to create the file must own it or its parent dir */ if(fsal2unix_mode(tgt_dir_attrs.mode) & S_ISVTX) { TakeTokenFSCall(); rc = fstatat(new_parent_fd, p_new_name->name, &buffstat, AT_SYMLINK_NOFOLLOW); errsv = errno; ReleaseTokenFSCall(); if(rc < 0) { if(errsv != ENOENT) { close(old_parent_fd); if (!src_equal_tgt) close(new_parent_fd); Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_rename); } } else { if(tgt_dir_attrs.owner != p_context->credential.user && buffstat.st_uid != p_context->credential.user && p_context->credential.user != 0) { close(old_parent_fd); if (!src_equal_tgt) close(new_parent_fd); Return(ERR_FSAL_ACCESS, 0, INDEX_FSAL_rename); } } } /************************************* * Rename the file on the filesystem * *************************************/ TakeTokenFSCall(); rc = renameat(old_parent_fd, p_old_name->name, new_parent_fd, p_new_name->name); errsv = errno; ReleaseTokenFSCall(); close(old_parent_fd); if (!src_equal_tgt) close(new_parent_fd); if(rc) Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_rename); /*********************** * Fill the attributes * ***********************/ if(p_src_dir_attributes) { status = GPFSFSAL_getattrs(p_old_parentdir_handle, p_context, p_src_dir_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_src_dir_attributes->asked_attributes); FSAL_SET_MASK(p_src_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } if(p_tgt_dir_attributes) { status = GPFSFSAL_getattrs(p_new_parentdir_handle, p_context, p_tgt_dir_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_tgt_dir_attributes->asked_attributes); FSAL_SET_MASK(p_tgt_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } /* OK */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_rename); }
static gboolean checkout_object_for_uncompressed_cache (OstreeRepo *self, const char *loose_path, GFileInfo *src_info, GInputStream *content, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *temp_filename = NULL; g_autoptr(GOutputStream) temp_out = NULL; int fd; int res; guint32 file_mode; /* Don't make setuid files in uncompressed cache */ file_mode = g_file_info_get_attribute_uint32 (src_info, "unix::mode"); file_mode &= ~(S_ISUID|S_ISGID); if (!gs_file_open_in_tmpdir_at (self->tmp_dir_fd, file_mode, &temp_filename, &temp_out, cancellable, error)) goto out; if (g_output_stream_splice (temp_out, content, 0, cancellable, error) < 0) goto out; if (!g_output_stream_flush (temp_out, cancellable, error)) goto out; fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)temp_out); if (!self->disable_fsync) { do res = fsync (fd); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } } if (!g_output_stream_close (temp_out, cancellable, error)) goto out; if (!_ostree_repo_ensure_loose_objdir_at (self->uncompressed_objects_dir_fd, loose_path, cancellable, error)) goto out; if (G_UNLIKELY (renameat (self->tmp_dir_fd, temp_filename, self->uncompressed_objects_dir_fd, loose_path) == -1)) { if (errno != EEXIST) { glnx_set_error_from_errno (error); g_prefix_error (error, "Storing file '%s': ", temp_filename); goto out; } else (void) unlinkat (self->tmp_dir_fd, temp_filename, 0); } ret = TRUE; out: return ret; }
/* * This function creates a file under a temporary name, then rename()s * it into place. This implements union-like behavior. */ static gboolean checkout_file_unioning_from_input_at (OstreeRepo *repo, OstreeRepoCheckoutOptions *options, GFileInfo *file_info, GVariant *xattrs, GInputStream *input, int destination_dfd, const char *destination_name, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *temp_filename = NULL; if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK) { if (!_ostree_make_temporary_symlink_at (destination_dfd, g_file_info_get_symlink_target (file_info), &temp_filename, cancellable, error)) goto out; if (xattrs) { if (!glnx_dfd_name_set_all_xattrs (destination_dfd, temp_filename, xattrs, cancellable, error)) goto out; } } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { g_autoptr(GOutputStream) temp_out = NULL; guint32 file_mode; file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); /* Don't make setuid files on checkout when we're doing --user */ if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER) file_mode &= ~(S_ISUID|S_ISGID); if (!gs_file_open_in_tmpdir_at (destination_dfd, file_mode, &temp_filename, &temp_out, cancellable, error)) goto out; if (!write_regular_file_content (repo, options, temp_out, file_info, xattrs, input, cancellable, error)) goto out; } else g_assert_not_reached (); if (G_UNLIKELY (renameat (destination_dfd, temp_filename, destination_dfd, destination_name) == -1)) { glnx_set_error_from_errno (error); goto out; } ret = TRUE; out: return ret; }
int main() { int fd1; fd1 = creat("file1", S_IREAD|S_IWRITE); close (fd1); fd1 = creat("file3", S_IREAD|S_IWRITE); close (fd1); mkdir("dir1", S_IREAD|S_IWRITE|S_IEXEC); mkdir("dir3", S_IREAD|S_IWRITE|S_IEXEC); mkdir("dir5", S_IREAD|S_IWRITE|S_IEXEC); fd1 = creat("dir3/file", S_IREAD|S_IWRITE); close (fd1); rename("file1", "file2"); //staptest// [[[[rename ("file1", "file2"!!!!renameat (AT_FDCWD, "file1", AT_FDCWD, "file2"]]]]) = 0 rename("dir1", "dir2"); //staptest// [[[[rename ("dir1", "dir2"!!!!renameat (AT_FDCWD, "dir1", AT_FDCWD, "dir2"]]]]) = 0 // This will fail since the target isn't empty. rename("dir2", "dir3"); //staptest// [[[[rename ("dir2", "dir3"!!!!renameat (AT_FDCWD, "dir2", AT_FDCWD, "dir3"]]]]) = -NNNN (ENOTEMPTY!!!!EEXIST) // This will fail since you can't rename a file to a directory. rename("file2", "dir2"); //staptest// [[[[rename ("file2", "dir2"!!!!renameat (AT_FDCWD, "file2", AT_FDCWD, "dir2"]]]]) = -NNNN (EISDIR) // You can't rename a directory to a subdirectory of itself. rename("dir2", "dir2/dir4"); //staptest// [[[[rename ("dir2", "dir2/dir4"!!!!renameat (AT_FDCWD, "dir2", AT_FDCWD, "dir2/dir4"]]]]) = -NNNN (EINVAL) // You can't rename a directory to a file. rename("dir2", "file2"); //staptest// [[[[rename ("dir2", "file2"!!!!renameat (AT_FDCWD, "dir2", AT_FDCWD, "file2"]]]]) = -NNNN (ENOTDIR) rename("file2", (char *)-1); #ifdef __s390__ //staptest// rename ("file2", 0x[7]?[f]+) = -NNNN (EFAULT) #else //staptest// [[[[rename ("file2", 0x[f]+!!!!renameat (AT_FDCWD, "file2", AT_FDCWD, 0x[f]+]]]]) = -NNNN (EFAULT) #endif rename((char *)-1, "file2"); #ifdef __s390__ //staptest// rename (0x[7]?[f]+, "file2") = -NNNN (EFAULT) #else //staptest// [[[[rename (0x[f]+, "file2"!!!!renameat (AT_FDCWD, 0x[f]+, AT_FDCWD, "file2"]]]]) = -NNNN (EFAULT) #endif #if GLIBC_SUPPORT renameat(AT_FDCWD, "file2", AT_FDCWD, "file1"); //staptest// renameat (AT_FDCWD, "file2", AT_FDCWD, "file1") = 0 renameat(AT_FDCWD, "dir2", AT_FDCWD, "dir1"); //staptest// renameat (AT_FDCWD, "dir2", AT_FDCWD, "dir1") = 0 // This will fail since the target isn't empty. renameat(AT_FDCWD, "dir1", AT_FDCWD, "dir3"); //staptest// renameat (AT_FDCWD, "dir1", AT_FDCWD, "dir3") = -NNNN (ENOTEMPTY!!!!EEXIST) // This will fail since you can't rename a file to a directory. renameat(AT_FDCWD, "file1", AT_FDCWD, "dir1"); //staptest// renameat (AT_FDCWD, "file1", AT_FDCWD, "dir1") = -NNNN (EISDIR) // You can't rename a directory to a subdirectory of itself. renameat(AT_FDCWD, "dir1", AT_FDCWD, "dir1/dir4"); //staptest// renameat (AT_FDCWD, "dir1", AT_FDCWD, "dir1/dir4") = -NNNN (EINVAL) // You can't rename a directory to a file. renameat(AT_FDCWD, "dir1", AT_FDCWD, "file1"); //staptest// renameat (AT_FDCWD, "dir1", AT_FDCWD, "file1") = -NNNN (ENOTDIR) renameat(-1, "dir1", AT_FDCWD, "file1"); //staptest// renameat (-1, "dir1", AT_FDCWD, "file1") = -NNNN renameat(AT_FDCWD, (char *)-1, AT_FDCWD, "file1"); #ifdef __s390__ //staptest// renameat (AT_FDCWD, 0x[7]?[f]+, AT_FDCWD, "file1") = -NNNN #else //staptest// renameat (AT_FDCWD, 0x[f]+, AT_FDCWD, "file1") = -NNNN #endif renameat(AT_FDCWD, "dir1", -1, "file1"); //staptest// renameat (AT_FDCWD, "dir1", -1, "file1") = -NNNN renameat(AT_FDCWD, "file1", AT_FDCWD, (char *)-1); #ifdef __s390__ //staptest// renameat (AT_FDCWD, "file1", AT_FDCWD, 0x[7]?[f]+) = -NNNN (EFAULT) #else //staptest// renameat (AT_FDCWD, "file1", AT_FDCWD, 0x[f]+) = -NNNN (EFAULT) #endif #endif #if defined(SYS_renameat2) // the renameat2 syscall is not implemented on ppc64le (kernel-3.10.0-294). // arch/powerpc/include/asm/systbl.h has 'SYSCALL(ni_syscall) /* sys_renameat2 */' __renameat2(AT_FDCWD, "file3", AT_FDCWD, "file4", 0); //staptest// [[[[renameat2 (AT_FDCWD, "file3", AT_FDCWD, "file4", 0x0) = 0!!!!ni_syscall () = -NNNN]]]] __renameat2(AT_FDCWD, "dir5", AT_FDCWD, "dir6", 0); //staptest// [[[[renameat2 (AT_FDCWD, "dir5", AT_FDCWD, "dir6", 0x0) = 0!!!!ni_syscall () = -NNNN]]]] // This should fail since the target exists (when using RENAME_NOREPLACE). #ifdef RENAME_NOREPLACE __renameat2(AT_FDCWD, "file4", AT_FDCWD, "file2", RENAME_NOREPLACE); //staptest// [[[[renameat2 (AT_FDCWD, "file4", AT_FDCWD, "file2", RENAME_NOREPLACE)!!!!ni_syscall ()]]]] = NNNN #endif // This will fail since the target isn't empty. __renameat2(AT_FDCWD, "dir6", AT_FDCWD, "dir3", 0); //staptest// [[[[renameat2 (AT_FDCWD, "dir6", AT_FDCWD, "dir3", 0x0)!!!!ni_syscall ()]]]] = -NNNN (ENOTEMPTY!!!!EEXIST!!!!ENOSYS) // This will fail since you can't rename a file to a directory. __renameat2(AT_FDCWD, "file4", AT_FDCWD, "dir6", 0); //staptest// [[[[renameat2 (AT_FDCWD, "file4", AT_FDCWD, "dir6", 0x0)!!!!ni_syscall ()]]]] = -NNNN (EISDIR!!!!ENOENT!!!!ENOSYS) // Normally, this would fail since you can't rename a file to a // directory. But with RENAME_EXCHANGE, the kernel will atomically // exchange them. Note that since NFS filesystem's don't support // RENAME_EXCHANGE, this call can fail. #ifdef RENAME_EXCHANGE __renameat2(AT_FDCWD, "file2", AT_FDCWD, "dir1", RENAME_EXCHANGE); //staptest// [[[[renameat2 (AT_FDCWD, "file2", AT_FDCWD, "dir1", RENAME_EXCHANGE) = NNNN!!!!ni_syscall () = -NNNN]]]] #endif // You can't rename a directory to a subdirectory of itself. __renameat2(AT_FDCWD, "dir6", AT_FDCWD, "dir6/dir4", 0); //staptest// [[[[renameat2 (AT_FDCWD, "dir6", AT_FDCWD, "dir6/dir4", 0x0)!!!!ni_syscall ()]]]] = -NNNN (EINVAL!!!!ENOSYS) // You can't rename a directory to a file without RENAME_EXCHANGE. __renameat2(AT_FDCWD, "dir6", AT_FDCWD, "file4", 0); #ifdef RENAME_EXCHANGE //staptest// [[[[renameat2 (AT_FDCWD, "dir6", AT_FDCWD, "file4", 0x0)!!!!ni_syscall ()]]]] = NNNN #else //staptest// [[[[renameat2 (AT_FDCWD, "dir6", AT_FDCWD, "file4", 0x0)!!!!ni_syscall ()]]]] = -NNNN (ENOTDIR!!!!ENOSYS) #endif __renameat2(-1, "dir6", AT_FDCWD, "file4", 0); //staptest// [[[[renameat2 (-1, "dir6", AT_FDCWD, "file4", 0x0)!!!!ni_syscall ()]]]] = -NNNN __renameat2(AT_FDCWD, (char *)-1, AT_FDCWD, "file4", 0); #ifdef __s390__ //staptest// renameat2 (AT_FDCWD, 0x[7]?[f]+, AT_FDCWD, "file4", 0x0) = -NNNN #else //staptest// [[[[renameat2 (AT_FDCWD, 0x[f]+, AT_FDCWD, "file4", 0x0)!!!!ni_syscall ()]]]] = -NNNN #endif __renameat2(AT_FDCWD, "dir6", -1, "file4", 0); //staptest// [[[[renameat2 (AT_FDCWD, "dir6", -1, "file4", 0x0)!!!!ni_syscall ()]]]] = -NNNN __renameat2(AT_FDCWD, "file4", AT_FDCWD, (char *)-1, 0); #ifdef __s390__ //staptest// renameat2 (AT_FDCWD, "file4", AT_FDCWD, 0x[7]?[f]+, 0x0) = -NNNN (EFAULT) #else //staptest// [[[[renameat2 (AT_FDCWD, "file4", AT_FDCWD, 0x[f]+, 0x0)!!!!ni_syscall ()]]]] = -NNNN (EFAULT!!!!ENOSYS) #endif __renameat2(AT_FDCWD, "dir6", AT_FDCWD, "file4", -1); //staptest// [[[[renameat2 (AT_FDCWD, "dir6", AT_FDCWD, "file4", RENAME_[^ ]+|XXXX)!!!!ni_syscall ()]]]] = -NNNN #endif return 0; }
static unsigned int call_syscall(struct syscall_desc *scall, char *argv[]) { struct stat64 sb; long long flags; unsigned int i; char *endp; int name, rval; union { char *str; long long num; } args[MAX_ARGS]; #ifdef HAS_FREEBSD_ACL int entry_id = ACL_FIRST_ENTRY; acl_t acl, newacl; acl_entry_t entry, newentry; #endif /* * Verify correctness of the arguments. */ for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) { if (scall->sd_args[i] == TYPE_NONE) { if (argv[i] == NULL || strcmp(argv[i], ":") == 0) break; fprintf(stderr, "too many arguments [%s]\n", argv[i]); exit(1); } else { if (argv[i] == NULL || strcmp(argv[i], ":") == 0) { if (scall->sd_args[i] & TYPE_OPTIONAL) break; fprintf(stderr, "too few arguments\n"); exit(1); } if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) { if (strcmp(argv[i], "NULL") == 0) args[i].str = NULL; else if (strcmp(argv[i], "DEADCODE") == 0) args[i].str = (void *)0xdeadc0de; else args[i].str = argv[i]; } else if ((scall->sd_args[i] & TYPE_MASK) == TYPE_NUMBER) { args[i].num = strtoll(argv[i], &endp, 0); if (*endp != '\0' && !isspace((unsigned char)*endp)) { fprintf(stderr, "invalid argument %u, number expected [%s]\n", i, endp); exit(1); } } else if ((scall->sd_args[i] & TYPE_MASK) == TYPE_DESCRIPTOR) { if (strcmp(argv[i], "AT_FDCWD") == 0) { args[i].num = AT_FDCWD; } else if (strcmp(argv[i], "BADFD") == 0) { /* In case AT_FDCWD is -1 on some systems... */ if (AT_FDCWD == -1) args[i].num = -2; else args[i].num = -1; } else { int pos; pos = strtoll(argv[i], &endp, 0); if (*endp != '\0' && !isspace((unsigned char)*endp)) { fprintf(stderr, "invalid argument %u, number expected [%s]\n", i, endp); exit(1); } args[i].num = descriptor_get(pos); } } } } /* * Call the given syscall. */ #define NUM(n) (args[(n)].num) #define STR(n) (args[(n)].str) switch (scall->sd_action) { case ACTION_OPEN: flags = str2flags(open_flags, STR(1)); if (flags & O_CREAT) { if (i == 2) { fprintf(stderr, "too few arguments\n"); exit(1); } rval = open(STR(0), (int)flags, (mode_t)NUM(2)); } else { if (i == 3) { fprintf(stderr, "too many arguments\n"); exit(1); } rval = open(STR(0), (int)flags); } if (rval >= 0) descriptor_add(rval); break; case ACTION_OPENAT: flags = str2flags(open_flags, STR(2)); if (flags & O_CREAT) { if (i == 3) { fprintf(stderr, "too few arguments\n"); exit(1); } rval = openat(NUM(0), STR(1), (int)flags, (mode_t)NUM(3)); } else { if (i == 4) { fprintf(stderr, "too many arguments\n"); exit(1); } rval = openat(NUM(0), STR(1), (int)flags); } if (rval >= 0) descriptor_add(rval); break; case ACTION_CREATE: rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1)); if (rval >= 0) close(rval); break; case ACTION_UNLINK: rval = unlink(STR(0)); break; case ACTION_UNLINKAT: rval = unlinkat(NUM(0), STR(1), (int)str2flags(unlinkat_flags, STR(2))); break; case ACTION_MKDIR: rval = mkdir(STR(0), (mode_t)NUM(1)); break; case ACTION_MKDIRAT: rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2)); break; case ACTION_RMDIR: rval = rmdir(STR(0)); break; case ACTION_LINK: rval = link(STR(0), STR(1)); break; case ACTION_LINKAT: rval = linkat(NUM(0), STR(1), NUM(2), STR(3), (int)str2flags(linkat_flags, STR(4))); break; case ACTION_SYMLINK: rval = symlink(STR(0), STR(1)); break; case ACTION_SYMLINKAT: rval = symlinkat(STR(0), NUM(1), STR(2)); break; case ACTION_RENAME: rval = rename(STR(0), STR(1)); break; case ACTION_RENAMEAT: rval = renameat(NUM(0), STR(1), NUM(2), STR(3)); break; case ACTION_MKFIFO: rval = mkfifo(STR(0), (mode_t)NUM(1)); break; case ACTION_MKFIFOAT: rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2)); break; case ACTION_MKNOD: case ACTION_MKNODAT: { mode_t ntype; dev_t dev; int fa; switch (scall->sd_action) { case ACTION_MKNOD: fa = 0; break; case ACTION_MKNODAT: fa = 1; break; default: abort(); } dev = makedev(NUM(fa + 3), NUM(fa + 4)); if (strcmp(STR(fa + 1), "c") == 0) /* character device */ ntype = S_IFCHR; else if (strcmp(STR(fa + 1), "b") == 0) /* block device */ ntype = S_IFBLK; else if (strcmp(STR(fa + 1), "f") == 0) /* fifo special */ ntype = S_IFIFO; else if (strcmp(STR(fa + 1), "d") == 0) /* directory */ ntype = S_IFDIR; else if (strcmp(STR(fa + 1), "o") == 0) /* regular file */ ntype = S_IFREG; else { fprintf(stderr, "wrong argument 1\n"); exit(1); } switch (scall->sd_action) { case ACTION_MKNOD: rval = mknod(STR(0), ntype | NUM(2), dev); break; case ACTION_MKNODAT: rval = mknodat(NUM(0), STR(1), ntype | NUM(3), dev); break; default: abort(); } break; } case ACTION_BIND: { struct sockaddr_un sunx; sunx.sun_family = AF_UNIX; strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1); sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; rval = socket(AF_UNIX, SOCK_STREAM, 0); if (rval < 0) break; rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx)); break; } #ifdef HAS_BINDAT case ACTION_BINDAT: { struct sockaddr_un sunx; sunx.sun_family = AF_UNIX; strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1); sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; rval = socket(AF_UNIX, SOCK_STREAM, 0); if (rval < 0) break; rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx, sizeof(sunx)); break; } #endif case ACTION_CONNECT: { struct sockaddr_un sunx; sunx.sun_family = AF_UNIX; strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1); sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; rval = socket(AF_UNIX, SOCK_STREAM, 0); if (rval < 0) break; rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx)); break; } #ifdef HAS_CONNECTAT case ACTION_CONNECTAT: { struct sockaddr_un sunx; sunx.sun_family = AF_UNIX; strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1); sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; rval = socket(AF_UNIX, SOCK_STREAM, 0); if (rval < 0) break; rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx, sizeof(sunx)); break; } #endif case ACTION_CHMOD: rval = chmod(STR(0), (mode_t)NUM(1)); break; case ACTION_FCHMOD: rval = fchmod(NUM(0), (mode_t)NUM(1)); break; #ifdef HAS_LCHMOD case ACTION_LCHMOD: rval = lchmod(STR(0), (mode_t)NUM(1)); break; #endif case ACTION_FCHMODAT: rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2), str2flags(fchmodat_flags, STR(3))); break; case ACTION_CHOWN: rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2)); break; case ACTION_FCHOWN: rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2)); break; case ACTION_LCHOWN: rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2)); break; case ACTION_FCHOWNAT: rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3), (int)str2flags(fchownat_flags, STR(4))); break; #ifdef HAS_CHFLAGS case ACTION_CHFLAGS: rval = chflags(STR(0), (unsigned long)str2flags(chflags_flags, STR(1))); break; #endif #ifdef HAS_FCHFLAGS case ACTION_FCHFLAGS: rval = fchflags(NUM(0), (unsigned long)str2flags(chflags_flags, STR(1))); break; #endif #ifdef HAS_CHFLAGSAT case ACTION_CHFLAGSAT: rval = chflagsat(NUM(0), STR(1), (unsigned long)str2flags(chflags_flags, STR(2)), (int)str2flags(chflagsat_flags, STR(3))); break; #endif #ifdef HAS_LCHFLAGS case ACTION_LCHFLAGS: rval = lchflags(STR(0), (unsigned long)str2flags(chflags_flags, STR(1))); break; #endif case ACTION_TRUNCATE: rval = truncate64(STR(0), NUM(1)); break; case ACTION_FTRUNCATE: rval = ftruncate64(NUM(0), NUM(1)); break; case ACTION_STAT: rval = stat64(STR(0), &sb); if (rval == 0) { show_stats(&sb, STR(1)); return (i); } break; case ACTION_FSTAT: rval = fstat64(NUM(0), &sb); if (rval == 0) { show_stats(&sb, STR(1)); return (i); } break; case ACTION_LSTAT: rval = lstat64(STR(0), &sb); if (rval == 0) { show_stats(&sb, STR(1)); return (i); } break; case ACTION_FSTATAT: rval = fstatat(NUM(0), STR(1), &sb, (int)str2flags(fstatat_flags, STR(2))); if (rval == 0) { show_stats(&sb, STR(3)); return (i); } break; case ACTION_PATHCONF: case ACTION_FPATHCONF: case ACTION_LPATHCONF: { long lrval; name = str2name(pathconf_names, STR(1)); if (name == -1) { fprintf(stderr, "unknown name %s", STR(1)); exit(1); } errno = 0; switch (scall->sd_action) { case ACTION_PATHCONF: lrval = pathconf(STR(0), name); break; case ACTION_FPATHCONF: lrval = fpathconf(NUM(0), name); break; case ACTION_LPATHCONF: lrval = lpathconf(STR(0), name); break; default: abort(); } if (lrval == -1 && errno == 0) { printf("unlimited\n"); return (i); } else if (lrval >= 0) { printf("%ld\n", lrval); return (i); } rval = -1; break; } #ifdef HAS_FREEBSD_ACL case ACTION_PREPENDACL: rval = -1; acl = acl_get_file(STR(0), ACL_TYPE_NFS4); if (acl == NULL) break; newacl = acl_from_text(STR(1)); if (acl == NULL) break; while (acl_get_entry(newacl, entry_id, &newentry) == 1) { entry_id = ACL_NEXT_ENTRY; if (acl_create_entry_np(&acl, &entry, 0)) break; if (acl_copy_entry(entry, newentry)) break; } rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl); break; case ACTION_READACL: acl = acl_get_file(STR(0), ACL_TYPE_NFS4); if (acl == NULL) rval = -1; else rval = 0; break; #endif case ACTION_WRITE: rval = write(NUM(0), STR(1), strlen(STR(1))); break; default: fprintf(stderr, "unsupported syscall\n"); exit(1); } #undef STR #undef NUM if (rval < 0) { const char *serrno; serrno = err2str(errno); fprintf(stderr, "%s returned %d\n", scall->sd_name, rval); printf("%s\n", serrno); exit(1); } printf("0\n"); return (i); }
int rename(const char* old_path, const char* new_path) { return renameat(AT_FDCWD, old_path, AT_FDCWD, new_path); }