Exemplo n.º 1
1
Arquivo: 4.16.c Projeto: vg0x00/apue
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;
}
Exemplo n.º 2
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);

}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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);
	}
}
Exemplo n.º 8
0
/**
 * 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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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());
}
Exemplo n.º 11
0
/* 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;
    }
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
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;
	}
}
Exemplo n.º 14
0
/* 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);
    }
}
Exemplo n.º 15
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);
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
0
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
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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);
	}
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
0
Arquivo: unix.c Projeto: hajuuk/R7000
/*
 * @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;
}
Exemplo n.º 23
0
/* 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);
    }
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
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);

}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
/*
 * 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;
}
Exemplo n.º 28
0
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;
}
Exemplo n.º 29
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);
}
Exemplo n.º 30
0
int rename(const char* old_path, const char* new_path) {
  return renameat(AT_FDCWD, old_path, AT_FDCWD, new_path);
}