Exemple #1
0
static void uv__fs_work(struct uv__work* w) {
  int retry_on_eintr;
  uv_fs_t* req;
  ssize_t r;

  req = container_of(w, uv_fs_t, work_req);
  retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);

  do {
    errno = 0;

#define X(type, action)                                                       \
  case UV_FS_ ## type:                                                        \
    r = action;                                                               \
    break;

    switch (req->fs_type) {
    X(ACCESS, access(req->path, req->flags));
    X(CHMOD, chmod(req->path, req->mode));
    X(CHOWN, chown(req->path, req->uid, req->gid));
    X(CLOSE, close(req->file));
    X(FCHMOD, fchmod(req->file, req->mode));
    X(FCHOWN, fchown(req->file, req->uid, req->gid));
    X(FDATASYNC, uv__fs_fdatasync(req));
    X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
    X(FSYNC, fsync(req->file));
    X(FTRUNCATE, ftruncate(req->file, req->off));
    X(FUTIME, uv__fs_futime(req));
    X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
    X(LINK, link(req->path, req->new_path));
    X(MKDIR, mkdir(req->path, req->mode));
    X(MKDTEMP, uv__fs_mkdtemp(req));
    X(OPEN, uv__fs_open(req));
    X(READ, uv__fs_buf_iter(req, uv__fs_read));
    X(SCANDIR, uv__fs_scandir(req));
    X(READLINK, uv__fs_readlink(req));
    X(RENAME, rename(req->path, req->new_path));
    X(RMDIR, rmdir(req->path));
    X(SENDFILE, uv__fs_sendfile(req));
    X(STAT, uv__fs_stat(req->path, &req->statbuf));
    X(SYMLINK, symlink(req->path, req->new_path));
    X(UNLINK, unlink(req->path));
    X(UTIME, uv__fs_utime(req));
    X(WRITE, uv__fs_buf_iter(req, uv__fs_write));
    default: abort();
    }
#undef X
  } while (r == -1 && errno == EINTR && retry_on_eintr);

  if (r == -1)
    req->result = -errno;
  else
    req->result = r;

  if (r == 0 && (req->fs_type == UV_FS_STAT ||
                 req->fs_type == UV_FS_FSTAT ||
                 req->fs_type == UV_FS_LSTAT)) {
    req->ptr = &req->statbuf;
  }
}
Exemple #2
0
static void uv__fs_work(struct uv__work* w) {
    int retry_on_eintr;
    uv_fs_t* req;
    ssize_t r;
#ifdef O_CLOEXEC
    static int no_cloexec_support;
#endif  /* O_CLOEXEC */

    req = container_of(w, uv_fs_t, work_req);
    retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);

    do {
        errno = 0;

#define X(type, action)                                                       \
  case UV_FS_ ## type:                                                        \
    r = action;                                                               \
    break;

        switch (req->fs_type) {
            X(CHMOD, chmod(req->path, req->mode));
            X(CHOWN, chown(req->path, req->uid, req->gid));
            X(CLOSE, close(req->file));
            X(FCHMOD, fchmod(req->file, req->mode));
            X(FCHOWN, fchown(req->file, req->uid, req->gid));
            X(FDATASYNC, uv__fs_fdatasync(req));
            X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
            X(FSYNC, fsync(req->file));
            X(FTRUNCATE, ftruncate(req->file, req->off));
            X(FUTIME, uv__fs_futime(req));
            X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
            X(LINK, link(req->path, req->new_path));
            X(MKDIR, mkdir(req->path, req->mode));
            X(MKDTEMP, uv__fs_mkdtemp(req));
            X(READ, uv__fs_read(req));
            X(READDIR, uv__fs_readdir(req));
            X(READLINK, uv__fs_readlink(req));
            X(RENAME, rename(req->path, req->new_path));
            X(RMDIR, rmdir(req->path));
            X(SENDFILE, uv__fs_sendfile(req));
            X(STAT, uv__fs_stat(req->path, &req->statbuf));
            X(SYMLINK, symlink(req->path, req->new_path));
            X(UNLINK, unlink(req->path));
            X(UTIME, uv__fs_utime(req));
            X(WRITE, uv__fs_write(req));
        case UV_FS_OPEN:
#ifdef O_CLOEXEC
            /* Try O_CLOEXEC before entering locks */
            if (!no_cloexec_support) {
                r = open(req->path, req->flags | O_CLOEXEC, req->mode);
                if (r >= 0)
                    break;
                if (errno != EINVAL)
                    break;
                no_cloexec_support = 1;
            }
#endif  /* O_CLOEXEC */
            if (req->cb != NULL)
                uv_rwlock_rdlock(&req->loop->cloexec_lock);
            r = open(req->path, req->flags, req->mode);

            /*
             * In case of failure `uv__cloexec` will leave error in `errno`,
             * so it is enough to just set `r` to `-1`.
             */
            if (r >= 0 && uv__cloexec(r, 1) != 0) {
                r = uv__close(r);
                if (r != 0 && r != -EINPROGRESS)
                    abort();
                r = -1;
            }
            if (req->cb != NULL)
                uv_rwlock_rdunlock(&req->loop->cloexec_lock);
            break;
        default:
            abort();
        }

#undef X
    }
    while (r == -1 && errno == EINTR && retry_on_eintr);

    if (r == -1)
        req->result = -errno;
    else
        req->result = r;

    if (r == 0 && (req->fs_type == UV_FS_STAT ||
                   req->fs_type == UV_FS_FSTAT ||
                   req->fs_type == UV_FS_LSTAT)) {
        req->ptr = &req->statbuf;
    }
}