예제 #1
0
파일: posix.c 프로젝트: simartin/cppcheck
void bufferAccessOutOfBounds(int fd)
{
    char a[5];
    read(fd,a,5);
    // cppcheck-suppress bufferAccessOutOfBounds
    read(fd,a,6);
    write(fd,a,5);
    // cppcheck-suppress bufferAccessOutOfBounds
    write(fd,a,6);
    recv(fd,a,5,0);
    // cppcheck-suppress bufferAccessOutOfBounds
    recv(fd,a,6,0);
    recvfrom(fd,a,5,0,0x0,0x0);
    // cppcheck-suppress bufferAccessOutOfBounds
    recvfrom(fd,a,6,0,0x0,0x0);
    send(fd,a,5,0);
    // cppcheck-suppress bufferAccessOutOfBounds
    send(fd,a,6,0);
    sendto(fd,a,5,0,0x0,0x0);
    // cppcheck-suppress bufferAccessOutOfBounds
    sendto(fd,a,6,0,0x0,0x0);
    // cppcheck-suppress constStatement
    0;
    readlink("path", a, 5);
    // cppcheck-suppress bufferAccessOutOfBounds
    readlink("path", a, 6);
    readlinkat(1, "path", a, 5);
    // cppcheck-suppress bufferAccessOutOfBounds
    readlinkat(1, "path", a, 6);
    // This is valid
    gethostname(a, 5);
    // cppcheck-suppress bufferAccessOutOfBounds
    gethostname(a, 6);
}
예제 #2
0
int
main (void)
{
  char buf[80];
  int result;

  /* Remove any leftovers from a previous partial run.  */
  ignore_value (system ("rm -rf " BASE "*"));

  /* Perform same checks as counterpart functions.  */
  result = test_readlink (do_readlink, false);
  ASSERT (test_symlink (do_symlink, false) == result);
  dfd = openat (AT_FDCWD, ".", O_RDONLY);
  ASSERT (0 <= dfd);
  ASSERT (test_readlink (do_readlink, false) == result);
  ASSERT (test_symlink (do_symlink, false) == result);

  /* Now perform some cross-directory checks.  Skip everything else on
     mingw.  */
  if (HAVE_SYMLINK)
    {
      const char *contents = "don't matter!";
      ssize_t exp = strlen (contents);

      /* Create link while cwd is '.', then read it in '..'.  */
      ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == 0);
      errno = 0;
      ASSERT (symlinkat (contents, dfd, BASE "link") == -1);
      ASSERT (errno == EEXIST);
      ASSERT (chdir ("..") == 0);
      errno = 0;
      ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == -1);
      ASSERT (errno == ENOENT);
      ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp);
      ASSERT (strncmp (contents, buf, exp) == 0);
      ASSERT (unlinkat (dfd, BASE "link", 0) == 0);

      /* Create link while cwd is '..', then read it in '.'.  */
      ASSERT (symlinkat (contents, dfd, BASE "link") == 0);
      ASSERT (fchdir (dfd) == 0);
      errno = 0;
      ASSERT (symlinkat (contents, AT_FDCWD, BASE "link") == -1);
      ASSERT (errno == EEXIST);
      buf[0] = '\0';
      ASSERT (readlinkat (AT_FDCWD, BASE "link", buf, sizeof buf) == exp);
      ASSERT (strncmp (contents, buf, exp) == 0);
      buf[0] = '\0';
      ASSERT (readlinkat (dfd, BASE "link", buf, sizeof buf) == exp);
      ASSERT (strncmp (contents, buf, exp) == 0);
      ASSERT (unlink (BASE "link") == 0);
    }

  ASSERT (close (dfd) == 0);
  if (result == 77)
    fputs ("skipping test: symlinks not supported on this file system\n",
           stderr);
  return result;
}
예제 #3
0
void sc_reassociate_with_pid1_mount_ns(void)
{
	int init_mnt_fd SC_CLEANUP(sc_cleanup_close) = -1;
	int self_mnt_fd SC_CLEANUP(sc_cleanup_close) = -1;

	debug("checking if the current process shares mount namespace"
	      " with the init process");

	init_mnt_fd = open("/proc/1/ns/mnt",
			   O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_PATH);
	if (init_mnt_fd < 0) {
		die("cannot open mount namespace of the init process (O_PATH)");
	}
	self_mnt_fd = open("/proc/self/ns/mnt",
			   O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_PATH);
	if (self_mnt_fd < 0) {
		die("cannot open mount namespace of the current process (O_PATH)");
	}
	char init_buf[128] = { 0 };
	char self_buf[128] = { 0 };
	memset(init_buf, 0, sizeof init_buf);
	if (readlinkat(init_mnt_fd, "", init_buf, sizeof init_buf) < 0) {
		if (errno == ENOENT) {
			// According to namespaces(7) on a pre 3.8 kernel the namespace
			// files are hardlinks, not sylinks. If that happens readlinkat
			// fails with ENOENT. As a quick workaround for this special-case
			// functionality, just bail out and do nothing without raising an
			// error.
			return;
		}
		die("cannot perform readlinkat() on the mount namespace file "
		    "descriptor of the init process");
	}
	memset(self_buf, 0, sizeof self_buf);
	if (readlinkat(self_mnt_fd, "", self_buf, sizeof self_buf) < 0) {
		die("cannot perform readlinkat() on the mount namespace file "
		    "descriptor of the current process");
	}
	if (memcmp(init_buf, self_buf, sizeof init_buf) != 0) {
		debug("the current process does not share mount namespace with "
		      "the init process, re-association required");
		// NOTE: we cannot use O_NOFOLLOW here because that file will always be a
		// symbolic link. We actually want to open it this way.
		int init_mnt_fd_real SC_CLEANUP(sc_cleanup_close) = -1;
		init_mnt_fd_real = open("/proc/1/ns/mnt", O_RDONLY | O_CLOEXEC);
		if (init_mnt_fd_real < 0) {
			die("cannot open mount namespace of the init process");
		}
		if (setns(init_mnt_fd_real, CLONE_NEWNS) < 0) {
			die("cannot re-associate the mount namespace with the init process");
		}
	} else {
		debug("re-associating is not required");
	}
}
예제 #4
0
파일: atfile.c 프로젝트: bobot/extunix
char *readlinkat_malloc (int dirfd, const char *filename)
{
  int size = 100;
  int nchars;
  char *buffer = NULL;
  char *tmp;

  while (1)
    {
      tmp = (char *) realloc (buffer, size);
      if (tmp == NULL)
      {
        free(buffer); /* if failed, dealloc is not performed */
        return NULL;
      }
      buffer = tmp;
      nchars = readlinkat (dirfd, filename, buffer, size);
      if (nchars < 0)
      {
          free (buffer);
          return NULL;
      }
      if (nchars < size)
      {
        buffer[nchars] = '\0';
        return buffer;
      }
      size *= 2;
    }
}
예제 #5
0
/*
 * For debugging: show open file descriptors
 */
void list_fd(const pid_t pid)
{
    struct dirent *dr;
    char *fds;
    DIR *dir;
    int ret;

    ret = asprintf(&fds, "/proc/%lu/fd", (unsigned long)pid);
    if (ret < 0)
	error("can not allocate string for /proc/%lu/fd", (unsigned long)pid);

    dir = opendir(fds);
    if (!dir) {
	warn("can not open %s", fds);
	return;
    }
    free(fds);

    while ((dr = readdir(dir))) {
	char tmp[LINE_MAX+1];
	ssize_t len;
	if (dr->d_name[0] == '.')
	    continue;
	len = readlinkat(dirfd(dir), dr->d_name, &tmp[0], LINE_MAX);
	tmp[len] = '\0';
	fprintf(stderr, "/proc/%d/fd/%s %s\n", (int)pid, dr->d_name, tmp);
    }
    closedir(dir);
}
예제 #6
0
파일: ut.c 프로젝트: Neuvenen/nvml
/*
 * record_open_files -- make a list of open files (used at START() time)
 */
static void
record_open_files()
{
	int dirfd;
	DIR *dirp = NULL;
	struct dirent *dp;

	if ((dirfd = open("/proc/self/fd", O_RDONLY)) < 0 ||
	    (dirp = fdopendir(dirfd)) == NULL)
		FATAL("!/proc/self/fd");
	while ((dp = readdir(dirp)) != NULL) {
		int fdnum;
		char fdfile[PATH_MAX];
		ssize_t cc;

		if (*dp->d_name == '.')
			continue;
		if ((cc = readlinkat(dirfd, dp->d_name, fdfile, PATH_MAX)) < 0)
		    FATAL("!readlinkat: /proc/self/fd/%s", dp->d_name);
		fdfile[cc] = '\0';
		fdnum = atoi(dp->d_name);
		if (dirfd == fdnum)
			continue;
		Fd_lut = open_file_add(Fd_lut, fdnum, fdfile);
	}
	closedir(dirp);
}
예제 #7
0
// Parse a symlink in /proc/pid/fd/$x and return the inode number of the
// socket.
//   inode_out: (output) set to the inode number on success
//   path: e.g. /proc/1234/fd/5 (must be a UNIX domain socket descriptor)
static bool ProcPathGetInodeAt(ino_t* inode_out,
                               int base_dir_fd,
                               const char* path) {
  // We also check that the path is relative.
  if (!inode_out || !path || *path == '/')
    return false;
  char buf[256];
  const ssize_t n = readlinkat(base_dir_fd, path, buf, sizeof(buf) - 1);
  if (n < 0)
    return false;
  buf[n] = 0;

  if (memcmp(kSocketLinkPrefix, buf, sizeof(kSocketLinkPrefix) - 1))
    return false;

  char* endptr = NULL;
  errno = 0;
  const unsigned long long int inode_ull =
      strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10);
  if (inode_ull == ULLONG_MAX || !endptr || *endptr != ']' || errno != 0)
    return false;

  *inode_out = inode_ull;
  return true;
}
예제 #8
0
파일: ut.c 프로젝트: Neuvenen/nvml
/*
 * check_open_files -- verify open files match recorded open files
 */
static void
check_open_files()
{
	int dirfd;
	DIR *dirp = NULL;
	struct dirent *dp;

	if ((dirfd = open("/proc/self/fd", O_RDONLY)) < 0 ||
	    (dirp = fdopendir(dirfd)) == NULL)
		FATAL("!/proc/self/fd");
	while ((dp = readdir(dirp)) != NULL) {
		int fdnum;
		char fdfile[PATH_MAX];
		ssize_t cc;

		if (*dp->d_name == '.')
			continue;
		if ((cc = readlinkat(dirfd, dp->d_name, fdfile, PATH_MAX)) < 0)
		    FATAL("!readlinkat: /proc/self/fd/%s", dp->d_name);
		fdfile[cc] = '\0';
		fdnum = atoi(dp->d_name);
		if (dirfd == fdnum)
			continue;
		open_file_remove(Fd_lut, fdnum, fdfile);
	}
	closedir(dirp);
	open_file_walk(Fd_lut);
	if (Fd_errcount)
		FATAL("open file list changed between START() and DONE()");
	open_file_free(Fd_lut);
}
예제 #9
0
ssize_t readlink(const char *path, char *buf, size_t bufsize) {
  int fd = -1;
  if (path[0] != VFS_SEPARATOR_CHAR) {
    fd = AT_FDCWD;
  }
  return readlinkat(fd, path, buf, bufsize);
}
예제 #10
0
파일: eval.c 프로젝트: dkazantzas/bfs
/**
 * -i?lname test.
 */
bool eval_lname(const struct expr *expr, struct eval_state *state) {
	struct BFTW *ftwbuf = state->ftwbuf;
	if (ftwbuf->typeflag != BFTW_LNK) {
		return false;
	}

	const struct stat *statbuf = fill_statbuf(state);
	if (!statbuf) {
		return false;
	}

	size_t size = statbuf->st_size + 1;
	char *name = malloc(size);
	if (!name) {
		eval_error(state);
		return false;
	}

	ssize_t ret = readlinkat(ftwbuf->at_fd, ftwbuf->at_path, name, size);
	if (ret < 0) {
		eval_error(state);
		return false;
	} else if (ret >= size) {
		return false;
	}

	name[ret] = '\0';

	bool match = fnmatch(expr->sdata, name, expr->idata) == 0;
	free(name);
	return match;
}
예제 #11
0
gboolean
ot_readlinkat_gfile_info (int             dfd,
                          const char     *path,
                          GFileInfo      *target_info,
                          GCancellable   *cancellable,
                          GError        **error)
{
  gboolean ret = FALSE;
  char targetbuf[PATH_MAX+1];
  ssize_t len;

  do
    len = readlinkat (dfd, path, targetbuf, sizeof (targetbuf) - 1);
  while (G_UNLIKELY (len == -1 && errno == EINTR));
  if (len == -1)
    {
      glnx_set_error_from_errno (error);
      goto out;
    }
  targetbuf[len] = '\0';
  g_file_info_set_symlink_target (target_info, targetbuf);

  ret = TRUE;
 out:
  return ret;
}
예제 #12
0
ATF_TC_BODY(readlinkat_failure, tc)
{
	memset(buff, 0, sizeof(buff));
	FILE *pipefd = setup(fds, "fr");
	/* Failure reason: symbolic link does not exist */
	ATF_REQUIRE_EQ(-1, readlinkat(AT_FDCWD, path, buff, sizeof(buff)-1));
	check_audit(fds, failurereg, pipefd);
}
예제 #13
0
ATF_TC_BODY(readlinkat_success, tc)
{
	memset(buff, 0, sizeof(buff));
	ATF_REQUIRE_EQ(0, symlink("symlink", path));
	FILE *pipefd = setup(fds, "fr");
	ATF_REQUIRE(readlinkat(AT_FDCWD, path, buff, sizeof(buff)-1) != -1);
	check_audit(fds, successreg, pipefd);
}
예제 #14
0
/* move any old watches directory out of the way, and then restore
 * the watches
 */
void udev_watch_restore(struct udev *udev)
{
    char filename[UTIL_PATH_SIZE], oldname[UTIL_PATH_SIZE];

    if (inotify_fd < 0)
        return;

    util_strscpyl(oldname, sizeof(oldname), udev_get_dev_path(udev), "/.udev/watch.old", NULL);
    util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/watch", NULL);
    if (rename(filename, oldname) == 0) {
        DIR *dir;
        struct dirent *ent;

        dir = opendir(oldname);
        if (dir == NULL) {
            err(udev, "unable to open old watches dir '%s', old watches will not be restored: %m", oldname);
            return;
        }

        for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
            char device[UTIL_PATH_SIZE];
            char *s;
            size_t l;
            ssize_t len;
            struct udev_device *dev;
            int maj, min;
            char type;

            if (ent->d_name[0] == '.')
                continue;

            s = device;
            l = util_strpcpy(&s, sizeof(device), udev_get_sys_path(udev));
            len = readlinkat(dirfd(dir), ent->d_name, s, l);
            if (len <= 0 || len == (ssize_t)l)
                goto unlink;
            s[len] = '\0';

            if (sscanf(s, "%c%i:%i", &type, &maj, &min) != 3)
                goto unlink;
            dev = udev_device_new_from_devnum(udev, type, makedev(maj, min));
            if (dev == NULL)
                goto unlink;

            info(udev, "restoring old watch on '%s'\n", udev_device_get_devnode(dev));
            udev_watch_begin(udev, dev);
            udev_device_unref(dev);
unlink:
            unlinkat(dirfd(dir), ent->d_name, 0);
        }

        closedir(dir);
        rmdir(oldname);

    } else if (errno != ENOENT) {
        err(udev, "unable to move watches dir '%s', old watches will not be restored: %m", filename);
    }
}
예제 #15
0
ssize_t
__readlinkat_chk (int fd, const char *path, void *buf, size_t len,
                  size_t buflen)
{
    if (len > buflen)
        __chk_fail ();

    return readlinkat (fd, path, buf, len);
}
예제 #16
0
ATF_TC_BODY(readlinkat_fderr1, tc)
{
	int dfd;

	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
	ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
	ATF_REQUIRE(readlinkat(dfd, FILEERR, F_OK, 0) == -1);
	ATF_REQUIRE(close(dfd) == 0);
}
예제 #17
0
int main(int argc, char *argv[])
{
    char linkname[NCHAR + 1] = { 0 };
    ssize_t r;

    r = (argc < 2) ? -1
        : readlinkat(1, argv[1], linkname, NCHAR);

    return (r > 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
예제 #18
0
char *
areadlinkat_with_size (int fd, char const *file, size_t size)
{
  /* Some buggy file systems report garbage in st_size.  Defend
     against them by ignoring outlandish st_size values in the initial
     memory allocation.  */
  size_t symlink_max = SYMLINK_MAX;
  size_t INITIAL_LIMIT_BOUND = 8 * 1024;
  size_t initial_limit = (symlink_max < INITIAL_LIMIT_BOUND
                          ? symlink_max + 1
                          : INITIAL_LIMIT_BOUND);

  /* The initial buffer size for the link value.  */
  size_t buf_size = size < initial_limit ? size + 1 : initial_limit;

  while (1)
    {
      ssize_t r;
      size_t link_length;
      char *buffer = malloc (buf_size);

      if (buffer == NULL)
        return NULL;
      r = readlinkat (fd, file, buffer, buf_size);
      link_length = r;

      /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1
         with errno == ERANGE if the buffer is too small.  */
      if (r < 0 && errno != ERANGE)
        {
          int saved_errno = errno;
          free (buffer);
          errno = saved_errno;
          return NULL;
        }

      if (link_length < buf_size)
        {
          buffer[link_length] = 0;
          return buffer;
        }

      free (buffer);
      if (buf_size <= MAXSIZE / 2)
        buf_size *= 2;
      else if (buf_size < MAXSIZE)
        buf_size = MAXSIZE;
      else
        {
          errno = ENOMEM;
          return NULL;
        }
    }
}
예제 #19
0
ssize_t
ast_readlinkat(int cwd, const char* path, char* buf, size_t size)
{
	ssize_t	r = -1;

	PATHIFY(cwd, path, 1, 1);
	RESTART(r, readlinkat(cwd, path, buf, size));
	PATHEND();

	return r;
}
예제 #20
0
ATF_TC_BODY(readlinkat_fderr2, tc)
{
	int fd;
	char buf[MAXPATHLEN];

	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
	ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
	ATF_REQUIRE(close(fd) == 0);
	ATF_REQUIRE(symlink(FILE, LINK) == 0);

	ATF_REQUIRE(readlinkat(-1, LINK, buf, sizeof(buf)) == -1);
}
예제 #21
0
파일: files2.c 프로젝트: SkyLandTW/JXTN
static int copyat(int olddirfd, const char* oldpath, int newdirfd, const char* newpath) {
    int err;
    int oldfd = openat(olddirfd, oldpath, O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NOATIME);
    if (oldfd == -1 && errno == EPERM) {
        oldfd = openat(olddirfd, oldpath, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
    }
    if (oldfd == -1 && errno == ELOOP) {
        char oldtarget[PATH_MAX];
        ssize_t oldlen = readlinkat(olddirfd, oldpath, oldtarget, sizeof(oldtarget));
        if (oldlen == -1) {
            return -1;
        }
        oldtarget[oldlen] = '\0';
        return symlinkat(oldtarget, newdirfd, newpath);
    }
    if (oldfd == -1) {
        return -1;
    }
    struct stat oldstat;
    if (fstat(oldfd, &oldstat) == -1) {
        err = errno;
        close(oldfd);
        errno = err;
        return -1;
    }
    int newfd = openat(newdirfd, newpath, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC | O_NOATIME, oldstat.st_mode);
    if (newfd == -1 && errno == EPERM) {
        newfd = openat(newdirfd, newpath, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, oldstat.st_mode);
    }
    if (newfd == -1) {
        err = errno;
        close(oldfd);
        errno = err;
        return -1;
    }
    if (fchown(newfd, oldstat.st_uid, oldstat.st_gid) == -1) {
        // ignore error
    }
    if (copyfile_sparse(oldfd, newfd) == -1) {
        err = errno;
        close(newfd);
        close(oldfd);
        errno = err;
        return -1;
    }
    close(newfd);
    close(oldfd);
    struct timespec times[2];
    times[0] = oldstat.st_atim;
    times[1] = oldstat.st_mtim;
    utimensat(newdirfd, newpath, times, 0); // ignore error
    return 0;
}
예제 #22
0
CAMLprim value netsys_readlinkat(value dirfd, value path)
{
#ifdef HAVE_AT
  char buffer[PATH_MAX];
  int len;
  len = readlinkat(Int_val(dirfd), String_val(path), buffer, sizeof(buffer)-1);
  if (len == -1) uerror("readlinkat", path);
  buffer[len] = '\0';
  return copy_string(buffer);
#else
    invalid_argument("Netsys_posix.readlinkat not available");
#endif
}
예제 #23
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;
}
예제 #24
0
파일: utils.c 프로젝트: dpl0/pkg
int
pkg_symlink_cksumat(int fd, const char *path, const char *root, char *cksum)
{
	char linkbuf[MAXPATHLEN];
	int linklen;

	if ((linklen = readlinkat(fd, path, linkbuf, sizeof(linkbuf) - 1)) ==
	    -1) {
		pkg_emit_errno("pkg_symlink_cksum", "readlink failed");
		return (EPKG_FATAL);
	}
	linkbuf[linklen] = '\0';

	return (pkg_symlink_cksum_readlink(linkbuf, linklen, root, cksum));
}
예제 #25
0
파일: main.c 프로젝트: 14rcole/ostree
static int
callback_readlink (const char *path, char *buf, size_t size)
{
  int r;

  path = ENSURE_RELPATH (path);

  /* Note FUSE wants the string to be always nul-terminated, even if
   * truncated.
   */
  r = readlinkat (basefd, path, buf, size - 1);
  if (r == -1)
    return -errno;
  buf[r] = '\0';
  return 0;
}
예제 #26
0
static void lo_readlink(fuse_req_t req, fuse_ino_t ino)
{
	char buf[PATH_MAX + 1];
	int res;

	res = readlinkat(lo_fd(req, ino), "", buf, sizeof(buf));
	if (res == -1)
		return (void) fuse_reply_err(req, errno);

	if (res == sizeof(buf))
		return (void) fuse_reply_err(req, ENAMETOOLONG);

	buf[res] = '\0';

	fuse_reply_readlink(req, buf);
}
예제 #27
0
/* move any old watches directory out of the way, and then restore
 * the watches
 */
void udev_watch_restore(struct udev *udev)
{
        if (inotify_fd < 0)
                return;

        if (rename("/run/udev/watch", "/run/udev/watch.old") == 0) {
                DIR *dir;
                struct dirent *ent;

                dir = opendir("/run/udev/watch.old");
                if (dir == NULL) {
                        log_error("unable to open old watches dir /run/udev/watch.old; old watches will not be restored: %m");
                        return;
                }

                for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
                        char device[UTIL_PATH_SIZE];
                        ssize_t len;
                        struct udev_device *dev;

                        if (ent->d_name[0] == '.')
                                continue;

                        len = readlinkat(dirfd(dir), ent->d_name, device, sizeof(device));
                        if (len <= 0 || len == (ssize_t)sizeof(device))
                                goto unlink;
                        device[len] = '\0';

                        dev = udev_device_new_from_device_id(udev, device);
                        if (dev == NULL)
                                goto unlink;

                        log_debug("restoring old watch on '%s'", udev_device_get_devnode(dev));
                        udev_watch_begin(udev, dev);
                        udev_device_unref(dev);
unlink:
                        unlinkat(dirfd(dir), ent->d_name, 0);
                }

                closedir(dir);
                rmdir("/run/udev/watch.old");

        } else if (errno != ENOENT) {
                log_error("unable to move watches dir /run/udev/watch; old watches will not be restored: %m");
        }
}
예제 #28
0
ATF_TC_BODY(readlinkat_fdcwd, tc)
{
	int fd;
	ssize_t len;
	char buf[MAXPATHLEN];

	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
	ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
	ATF_REQUIRE(close(fd) == 0);
	ATF_REQUIRE(symlink(FILE, LINK) == 0);

	len = readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)-1);
	ATF_REQUIRE(len != -1);
	buf[len] = 0;

	ATF_REQUIRE(strcmp(buf, FILE) == 0);
}
예제 #29
0
void test_create_symlink_at()
{
  char *symlink_filename = alloc_filename("symlink");
  int dir_fd = get_dir_fd(".");
  const char *dest_path = "dest_path";
  t_check_zero(symlinkat(dest_path, dir_fd, symlink_filename));

  char buf[100];
  int got;
  got = readlinkat(dir_fd, symlink_filename, buf, sizeof(buf));
  t_check(got >= 0);
  assert(got == strlen(dest_path));
  buf[got] = 0;
  assert(strcmp(buf, dest_path) == 0);

  t_check_zero(unlinkat(dir_fd, symlink_filename, 0));
  close(dir_fd);
  free(symlink_filename);
}
예제 #30
0
파일: dirtree.c 프로젝트: TELE-TWIN/toybox
struct dirtree *dirtree_add_node(struct dirtree *parent, char *name,
                                 int symfollow)
{
    struct dirtree *dt = NULL;
    struct stat st;
    char buf[4096];
    int len = 0, linklen = 0;

    if (name) {
        // open code this because haven't got node to call dirtree_parentfd() on yet
        int fd = parent ? parent->data : AT_FDCWD;

        if (fstatat(fd, name, &st, symfollow ? 0 : AT_SYMLINK_NOFOLLOW)) goto error;
        if (S_ISLNK(st.st_mode)) {
            if (0>(linklen = readlinkat(fd, name, buf, 4095))) goto error;
            buf[linklen++]=0;
        }
        len = strlen(name);
    }
    dt = xzalloc((len = sizeof(struct dirtree)+len+1)+linklen);
    dt->parent = parent;
    if (name) {
        memcpy(&(dt->st), &st, sizeof(struct stat));
        strcpy(dt->name, name);

        if (linklen) {
            dt->symlink = memcpy(len+(char *)dt, buf, linklen);
            dt->data = --linklen;
        }
    }

    return dt;

error:
    if (notdotdot(name)) {
        char *path = parent ? dirtree_path(parent, 0) : "";
        perror_msg("%s%s%s",path, parent ? "/" : "", name);
    }
    if (parent) parent->symlink = (char *)1;
    free(dt);
    return 0;
}