int __fchdir(int filedes) { GFS_File gf; const char *e; char *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __fchdir(%d)\n", filedes)); if ((gf = gfs_hook_is_open(filedes)) == NULL) return syscall(SYS_fchdir, filedes); if (gfs_hook_gfs_file_type(filedes) != GFS_DT_DIR) { e = GFARM_ERR_NOT_A_DIRECTORY; goto error; } _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchdir(%d)\n", filedes)); e = gfarm_path_canonical_to_url( gfs_hook_get_gfs_canonical_path(filedes), &url); if (e != NULL) goto error; e = gfs_chdir(url); free(url); if (e == NULL) return (0); error: _gfs_hook_debug(fprintf(stderr, "GFS: __fchdir: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
char * __getcwd(char *buf, size_t size) { const char *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking __getcwd(%p, %d)\n", buf, size)); if (!gfs_hook_cwd_is_gfarm) return (gfs_hook_syscall_getcwd(buf, size)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __getcwd(%p, %d)\n" ,buf, size)); e = gfs_hook_get_prefix(buf, size); if (e != NULL) goto error; e = gfs_getcwd(buf + strlen(buf), size - strlen(buf)); if (e == NULL) return (buf); error: _gfs_hook_debug(fprintf(stderr, "GFS: __getcwd: %s\n", e)); errno = gfarm_error_to_errno(e); return (NULL); }
/* * lgetxattr */ int lgetxattr(const char *path, const char *name, void *value, size_t size) { char *e, *gfarm_file; char *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking lgetxattr(%s, %s, %p, %lu)\n", path, name, value, (unsigned long)size)); if (!gfs_hook_is_url(path, &url)) #ifdef SYS_lgetxattr return syscall(SYS_lgetxattr, path, name, value, size); #else { errno = ENODATA; return (-1); } #endif _gfs_hook_debug(fprintf(stderr, "GFS: Hooking lgetxattr(%s, %s, %p, %lu)\n", path, name, value, (unsigned long)size)); e = gfarm_url_make_path(url, &gfarm_file); free(url); if (e == NULL) { e = GFARM_ERR_OPERATION_NOT_SUPPORTED; free(gfarm_file); } _gfs_hook_debug(fprintf(stderr, "GFS: lgetxattr: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __chdir(const char *path) { const char *e; char *url, *sec; _gfs_hook_debug_v(fprintf(stderr, "Hooking __chdir(%s)\n", path)); gfs_hook_cwd_is_gfarm = gfs_hook_is_url(path, &url, &sec); if (!gfs_hook_cwd_is_gfarm) return syscall(SYS_chdir, path); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __chdir(%s)\n", path)); e = gfs_chdir(url); free(url); if (sec != NULL) free(sec); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __chdir: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __dup2(int oldfd, int newfd) { struct _gfs_file_descriptor *d; _gfs_hook_debug_v(fprintf(stderr, "Hooking __dup2(%d, %d)\n", oldfd, newfd)); if (gfs_hook_is_open(oldfd) == NULL && gfs_hook_is_open(newfd) == NULL) return syscall(SYS_dup2, oldfd, newfd); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __dup2(%d, %d)\n", oldfd, newfd)); d = gfs_hook_dup_descriptor(oldfd); gfs_hook_set_descriptor(newfd, d); /* * dup2() should be called after gfs_hook_set_descriptor() * because newfd may be a descriptor reserved for a hooking point * of a Gfarm file. */ if (syscall(SYS_dup2, oldfd, newfd) == -1) return (-1); return (newfd); }
int __dup(int oldfd) { struct _gfs_file_descriptor *d; int newfd; GFS_File gf; _gfs_hook_debug_v(fprintf(stderr, "Hooking __dup(%d)\n", oldfd)); if ((gf = gfs_hook_is_open(oldfd)) == NULL) return syscall(SYS_dup, oldfd); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __dup(%d)\n", oldfd)); /* flush the buffer */ (void)gfs_pio_flush(gf); /* this file may be accessed by the child process */ gfs_hook_mode_calc_digest(gf); newfd = syscall(SYS_dup, oldfd); if (newfd == -1) return (-1); d = gfs_hook_dup_descriptor(oldfd); gfs_hook_set_descriptor(newfd, d); return (newfd); }
int __fchown(int fd, uid_t owner, gid_t group) { GFS_File gf; const char *e; struct gfs_stat s; _gfs_hook_debug_v(fprintf(stderr, "Hooking __fchown(%d, %d, %d)\n", fd, uid, group)); if ((gf = gfs_hook_is_open(fd)) == NULL) return (__syscall_fchown(fd, owner, group)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchown(%d, %d, %d)\n", fd, owner, group)); e = gfs_fstat(gf, &s); if (e == NULL) { if (strcmp(s.st_user, gfarm_get_global_username()) != 0) e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */ /* XXX - do nothing */ gfs_stat_free(&s); } if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __fchown: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __utime(const char *path, const struct utimbuf *buf) { char *e, *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __utime(%s, %p)\n", path, buf)); if (!gfs_hook_is_url(path, &url)) return syscall(SYS_utime, path, buf); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __utime(%s)\n", url)); if (buf == NULL) e = gfs_utimes(url, NULL); else { struct gfarm_timespec gt[2]; gt[0].tv_sec = buf->actime; gt[0].tv_nsec= 0; gt[1].tv_sec = buf->modtime; gt[1].tv_nsec= 0; e = gfs_utimes(url, gt); } free(url); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __utime: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __lchown(const char *path, uid_t owner, gid_t group) { const char *e; char *url; struct gfs_stat s; _gfs_hook_debug_v(fprintf(stderr, "Hooking __lchown(%s, %d, %d)\n", path, uid, group)); if (!gfs_hook_is_url(path, &url)) return (__syscall_lchown(path, owner, group)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __lchown(%s, %d, %d)\n", path, owner, group)); /* XXX - gfs_lstat is not supported */ e = gfs_stat(url, &s); free(url); if (e == NULL) { if (strcmp(s.st_user, gfarm_get_global_username()) != 0) e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */ /* XXX - do nothing */ gfs_stat_free(&s); } if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __lchown: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int FUNC__XSTAT(int ver, const char *path, STRUCT_STAT *buf) { _gfs_hook_debug_v( gflog_info(GFARM_MSG_UNFIXED, "Hooking " S(FUNC__XSTAT) ": %s", path)); return (FUNC___XSTAT(ver, path, buf)); }
int __chdir(const char *path) { const char *e; char *url; int r; _gfs_hook_debug_v(fprintf(stderr, "Hooking __chdir(%s)\n", path)); if (!gfs_hook_is_url(path, &url)) { if ((r = syscall(SYS_chdir, path)) == 0) gfs_hook_set_cwd_is_gfarm(0); return (r); } _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __chdir(%s)\n", path)); e = gfs_chdir(url); free(url); if (e == NULL) { gfs_hook_set_cwd_is_gfarm(1); return (0); } _gfs_hook_debug(fprintf(stderr, "GFS: __chdir: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
pid_t __vfork(void) { _gfs_hook_debug_v(fprintf(stderr, "Hooking __vfork()\n")); /* SYS_fork is called instead of SYS_vfork. */ return syscall(SYS_fork); }
/* * fsetxattr */ int fsetxattr(int filedes, const char *name, void *value, size_t size, int flags) { char *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking fsetxattr(%d, %s, %p, %lu, %d)\n", filedes, name, value, (unsigned long)size, flags)); if (!gfs_hook_is_open(filedes)) #ifdef SYS_fsetxattr return syscall(SYS_fsetxattr, filedes, name, value, size, flags); #else { errno = ENOTSUP; return (-1); } #endif _gfs_hook_debug(fprintf(stderr, "GFS: Hooking fsetxattr(%d, %s, %p, %lu, %d)\n", filedes, name, value, (unsigned long)size, flags)); e = GFARM_ERR_OPERATION_NOT_SUPPORTED; _gfs_hook_debug(fprintf(stderr, "GFS: fsetxattr: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __link(const char *oldpath, const char *newpath) { const char *e; char *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __link(%s, %s)\n", oldpath, newpath)); if (!gfs_hook_is_url(newpath, &url)) return (syscall(SYS_link, oldpath, newpath)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __link(%s, %s)\n", oldpath, newpath)); /* * Gfarm file system does not support the creation of * hard link yet. */ e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */ free(url); _gfs_hook_debug(fprintf(stderr, "GFS: __link: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
char * __getcwd(char *buf, size_t size) { const char *e; char *p; int alloced = 0; int prefix_size; _gfs_hook_debug_v(fprintf(stderr, "Hooking __getcwd(%p, %lu)\n", buf, (unsigned long)size)); if (!gfs_hook_get_cwd_is_gfarm()) return (gfs_hook_syscall_getcwd(buf, size)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __getcwd(%p, %lu)\n" ,buf, (unsigned long)size)); if (buf == NULL) { size = 2048; buf = malloc(size); if (buf == NULL) { e = GFARM_ERR_NO_MEMORY; goto error; } alloced = 1; } e = gfs_hook_get_prefix(buf, size); if (e != NULL) goto error; prefix_size = strlen(buf); e = gfs_getcwd(buf + prefix_size, size - prefix_size); if (e == NULL) { /* root in Gfarm FS is a special case. '/gfarm/' -> '/gfarm' */ if (buf[0] == '/' && buf[prefix_size] == '/' && buf[prefix_size + 1] == '\0') buf[prefix_size] = '\0'; if (alloced) { p = realloc(buf, strlen(buf) + 1); if (p != NULL) return (p); } return (buf); } error: if (alloced) free(buf); _gfs_hook_debug(fprintf(stderr, "GFS: __getcwd: %s\n", e)); errno = gfarm_error_to_errno(e); return (NULL); }
ssize_t __read(int filedes, void *buf, size_t nbyte) { GFS_File gf; char *e; int n; _gfs_hook_debug_v(fprintf(stderr, "Hooking __read(%d, , %d)\n", filedes, nbyte)); if ((gf = gfs_hook_is_open(filedes)) == NULL) return syscall(SYS_read, filedes, buf, nbyte); if (gfs_hook_gfs_file_type(filedes) == GFS_DT_DIR) { _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __read(%d, , %d)\n", filedes, nbyte)); e = GFARM_ERR_IS_A_DIRECTORY; goto error; } _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __read(%d(%d), , %d)\n", filedes, gfs_pio_fileno(gf), nbyte)); e = gfs_pio_read(gf, buf, nbyte, &n); if (e == NULL) { _gfs_hook_debug_v(fprintf(stderr, "GFS: Hooking __read --> %d\n", n)); return (n); } error: _gfs_hook_debug(fprintf(stderr, "GFS: __read: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
/* fprintf and fputs should not be put into the following function. */ ssize_t __write(int filedes, const void *buf, size_t nbyte) { GFS_File gf; char *e; int n; /* * DO NOT put the following line here. This causes infinite loop! * * _gfs_hook_debug_v(fprintf(stderr, "Hooking __write(%d, , %lu)\n", * filedes, (unsigned long)nbyte)); */ if ((gf = gfs_hook_is_open(filedes)) == NULL) return (syscall(SYS_write, filedes, buf, nbyte)); if (gfs_hook_gfs_file_type(filedes) == GFS_DT_DIR) { /* * DO NOT put the following line here, which results * in infinite loop. * * _gfs_hook_debug(fprintf(stderr, * "GFS: Hooking __write(%d, , %d)\n", * filedes, nbyte)); */ e = GFARM_ERR_IS_A_DIRECTORY; goto error; } _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __write(%d(%d), , %lu)\n", filedes, gfs_pio_fileno(gf), (unsigned long)nbyte)); e = gfs_pio_write(gf, buf, nbyte, &n); if (e == NULL) { _gfs_hook_debug_v(fprintf(stderr, "GFS: Hooking __write --> %d\n", n)); return (n); } error: /* * DO NOT put the following line here. * * _gfs_hook_debug(fprintf(stderr, "GFS: __write: %s\n", e)); */ errno = gfarm_error_to_errno(e); return (-1); }
int __utimes(const char *path, const struct timeval *tvp) { char *e, *url, *sec; _gfs_hook_debug_v(fprintf(stderr, "Hooking __utimes(%s, %p)\n", path, tvp)); if (!gfs_hook_is_url(path, &url, &sec)) { #ifdef __linux__ if (tvp == NULL) { return syscall(SYS_utime, path, NULL); } else { struct utimbuf ut; ut.actime = tvp[0].tv_sec; ut.modtime = tvp[1].tv_sec; return syscall(SYS_utime, path, &ut); } #else return syscall(SYS_utimes, path, tvp); #endif } _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __utimes(%s)\n", url)); if (tvp == NULL) e = gfs_utimes(url, NULL); else { struct gfarm_timespec gt[2]; gt[0].tv_sec = tvp[0].tv_sec; gt[0].tv_nsec= tvp[0].tv_usec * 1000; gt[1].tv_sec = tvp[1].tv_sec; gt[1].tv_nsec= tvp[1].tv_usec * 1000; e = gfs_utimes(url, gt); } free(url); if (sec != NULL) free(sec); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __utimes: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __execve(const char *filename, char *const argv [], char *const envp[]) { char *url, *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking __execve(%s)\n", filename)); if (!gfs_hook_is_url(filename, &url)) return syscall(SYS_execve, filename, argv, envp); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __execve(%s)\n", url)); e = gfs_execve(url, argv, envp); free(url); _gfs_hook_debug(fprintf(stderr, "GFS: __execve: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
char * __getcwd(char *buf, size_t size) { const char *e; char *p; int alloced = 0; _gfs_hook_debug_v(fprintf(stderr, "Hooking __getcwd(%p, %lu)\n", buf, (unsigned long)size)); if (!gfs_hook_get_cwd_is_gfarm()) return (gfs_hook_syscall_getcwd(buf, size)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __getcwd(%p, %lu)\n" ,buf, (unsigned long)size)); if (buf == NULL) { size = 2048; buf = malloc(size); if (buf == NULL) { e = GFARM_ERR_NO_MEMORY; goto error; } alloced = 1; } e = gfs_hook_get_prefix(buf, size); if (e != NULL) goto error; e = gfs_getcwd(buf + strlen(buf), size - strlen(buf)); if (e == NULL) { if (alloced) { p = realloc(buf, strlen(buf) + 1); if (p != NULL) return (p); } return (buf); } error: if (alloced) free(buf); _gfs_hook_debug(fprintf(stderr, "GFS: __getcwd: %s\n", e)); errno = gfarm_error_to_errno(e); return (NULL); }
int __fchmod(int filedes, mode_t mode) { GFS_File gf; char *e, *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __fchmod(%d, 0%o)\n", filedes, mode)); if ((gf = gfs_hook_is_open(filedes)) == NULL) return syscall(SYS_fchmod, filedes, mode); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchmod(%d, 0%o)\n", filedes, mode)); switch (gfs_hook_gfs_file_type(filedes)) { case GFS_DT_REG: e = gfs_fchmod(gf, mode); break; case GFS_DT_DIR: url = gfarm_url_prefix_add(gfs_dirname((GFS_Dir)gf)); if (url == NULL) { e = GFARM_ERR_NO_MEMORY; break; } e = gfs_chmod(url, mode); free(url); break; default: _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchmod: couldn't get gf or dir\n")); errno = EBADF; /* XXX - something broken */ return (-1); } if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __fchmod: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __dup(int oldfd) { struct _gfs_file_descriptor *d; int newfd; _gfs_hook_debug_v(fprintf(stderr, "Hooking __dup(%d)\n", oldfd)); if (gfs_hook_is_open(oldfd) == NULL) return syscall(SYS_dup, oldfd); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __dup(%d)\n", oldfd)); newfd = syscall(SYS_dup, oldfd); if (newfd == -1) return (-1); d = gfs_hook_dup_descriptor(oldfd); gfs_hook_set_descriptor(newfd, d); return (newfd); }
int __unlink(const char *path) { const char *e; char *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __unlink(%s)\n", path)); if (!gfs_hook_is_url(path, &url)) return syscall(SYS_unlink, path); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __unlink(%s)\n", path)); e = gfs_unlink(url); free(url); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __unlink: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
/* * mmap * * XXX - just print out the information. */ #if 0 /* XXX - Linux causes a segfault while loading a shared library. Should we call old_map() instead of syscall(SYS_mmap)??? */ void * __mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { GFS_File gf; int gfs_fd; _gfs_hook_debug_v(fprintf(stderr, "Hooking __mmap(%p, %d, %d, %d, %d, %d)\n", addr, len, prot, flags, fildes, (int)off)); if ((gf = gfs_hook_is_open(fildes)) == NULL) return (void *)syscall( SYS_mmap, addr, len, prot, flags, fildes, off); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __mmap(%p, %d, %d, %d, %d, %d)\n", addr, len, prot, flags, fildes, (int)off)); gfs_fd = gfs_pio_fileno(gf); return (void *)syscall(SYS_mmap, addr, len, prot, flags, gfs_fd, off); }
int fgetxattr(int filedes, const char *name, void *value, size_t size) { char *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking fgetxattr(%d, %s, %p, %lu)\n", filedes, name, value, (unsigned long)size)); if (!gfs_hook_is_open(filedes)) return syscall(SYS_fgetxattr, filedes, name, value, size); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking fgetxattr(%d, %s, %p, %lu)\n", filedes, name, value, (unsigned long)size)); e = GFARM_ERR_OPERATION_NOT_SUPPORTED; _gfs_hook_debug(fprintf(stderr, "GFS: fgetxattr: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __access(const char *path, int type) { char *e, *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __access(%s, %d)\n", path, type)); if (!gfs_hook_is_url(path, &url)) return syscall(SYS_access, path, type); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __access(%s, %d)\n", path, type)); e = gfs_access(url, type); free(url); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __access: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __chmod(const char *path, mode_t mode) { const char *e; char *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __chmod(%s, 0%o)\n", path, mode)); if (!gfs_hook_is_url(path, &url)) return syscall(SYS_chmod, path, mode); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __chmod(%s, 0%o)\n", path, mode)); e = gfs_chmod(url, mode); free(url); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __chmod: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __rename(const char *oldpath, const char *newpath) { const char *e; char *oldurl, *newurl; int old_is_url, new_is_url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __rename(%s, %s)\n", oldpath, newpath)); old_is_url = gfs_hook_is_url(oldpath, &oldurl); new_is_url = gfs_hook_is_url(newpath, &newurl); if (!old_is_url || !new_is_url) { if (old_is_url) free(oldurl); if (new_is_url) free(newurl); if (old_is_url != new_is_url) { errno = EXDEV; return (-1); } return (syscall(SYS_rename, oldpath, newpath)); } _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __rename(%s, %s)\n", oldpath, newpath)); e = gfs_rename(oldurl, newurl); free(oldurl); free(newurl); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __rename: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __dup2(int oldfd, int newfd) { struct _gfs_file_descriptor *d; GFS_File gf1, gf2; _gfs_hook_debug_v(fprintf(stderr, "Hooking __dup2(%d, %d)\n", oldfd, newfd)); gf1 = gfs_hook_is_open(oldfd); gf2 = gfs_hook_is_open(newfd); if (gf1 == NULL && gf2 == NULL) return syscall(SYS_dup2, oldfd, newfd); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __dup2(%d, %d)\n", oldfd, newfd)); if (gf1 != NULL) { /* flush the buffer */ (void)gfs_pio_flush(gf1); if (gf2 == NULL) /* this file may be accessed by the child process */ gfs_hook_mode_calc_digest(gf1); } d = gfs_hook_dup_descriptor(oldfd); gfs_hook_set_descriptor(newfd, d); /* * dup2() should be called after gfs_hook_set_descriptor() * because newfd may be a descriptor reserved for a hooking point * of a Gfarm file. */ if (syscall(SYS_dup2, oldfd, newfd) == -1) return (-1); return (newfd); }
int __close(int filedes) { GFS_File gf; char *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking __close(%d)\n", filedes)); if ((gf = gfs_hook_is_open(filedes)) == NULL) return (__syscall_close(filedes)); switch (gfs_hook_gfs_file_type(filedes)) { case GFS_DT_REG: _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __close(%d(%d))\n", filedes, gfs_pio_fileno(gf))); break; case GFS_DT_DIR: _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __close(%d)\n", filedes)); break; default: _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __close: couldn't get gf or dir\n")); errno = EBADF; /* XXX - something broken */ return (-1); } e = gfs_hook_clear_gfs_file(filedes); if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __close: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }