int rpl_dup2 (int oldfd, int newfd) #undef dup2 { int retval = dup2 (oldfd, newfd); if (retval >= 0 && oldfd >= 0 && newfd >= 0 && newfd != oldfd) { ensure_dirs_slot (newfd); if (newfd < dirs_allocated) { if (oldfd < dirs_allocated) { if (dirs[oldfd].name != NULL) { dirs[newfd].name = strdup (dirs[oldfd].name); if (dirs[newfd].name == NULL) dirs[newfd].saved_errno = ENOMEM; } else { dirs[newfd].name = NULL; dirs[newfd].saved_errno = dirs[oldfd].saved_errno; } } else { dirs[newfd].name = NULL; dirs[newfd].saved_errno = ENOMEM; } } } return retval; }
int rpl_dup (int oldfd) #undef dup { int newfd = dup (oldfd); if (oldfd >= 0 && newfd >= 0) { ensure_dirs_slot (newfd); if (newfd < dirs_allocated) { if (oldfd < dirs_allocated) { if (dirs[oldfd].name != NULL) { dirs[newfd].name = strdup (dirs[oldfd].name); if (dirs[newfd].name == NULL) dirs[newfd].saved_errno = ENOMEM; } else { dirs[newfd].name = NULL; dirs[newfd].saved_errno = dirs[oldfd].saved_errno; } } else { dirs[newfd].name = NULL; dirs[newfd].saved_errno = ENOMEM; } } } return newfd; }
void _gl_register_fd (int fd, const char *filename) { struct stat statbuf; ensure_dirs_slot (fd); if (fd < dirs_allocated && fstat (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) { dirs[fd].name = canonicalize_file_name (filename); if (dirs[fd].name == NULL) dirs[fd].saved_errno = errno; } }
/* Mark FD as visiting FILENAME. FD must be non-negative, and refer to an open file descriptor. If REPLACE_OPEN_DIRECTORY is non-zero, this should only be called if FD is visiting a directory. Close FD and return -1 if there is insufficient memory to track the directory name; otherwise return FD. */ int _gl_register_fd (int fd, const char *filename) { struct stat statbuf; assert (0 <= fd); if (REPLACE_OPEN_DIRECTORY || (fstat (fd, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))) { if (!ensure_dirs_slot (fd) || (dirs[fd].name = get_name (filename)) == NULL) { int saved_errno = errno; close (fd); errno = saved_errno; return -1; } } return fd; }
/* Mark NEWFD as a duplicate of OLDFD; useful from dup, dup2, dup3, and fcntl. Both arguments must be valid and distinct file descriptors. Close NEWFD and return -1 if OLDFD is tracking a directory, but there is insufficient memory to track the same directory in NEWFD; otherwise return NEWFD. */ int _gl_register_dup (int oldfd, int newfd) { assert (0 <= oldfd && 0 <= newfd && oldfd != newfd); if (oldfd < dirs_allocated && dirs[oldfd].name) { /* Duplicated a directory; must ensure newfd is allocated. */ if (!ensure_dirs_slot (newfd) || (dirs[newfd].name = strdup (dirs[oldfd].name)) == NULL) { int saved_errno = errno; close (newfd); errno = saved_errno; newfd = -1; } } else if (newfd < dirs_allocated) { /* Duplicated a non-directory; ensure newfd is cleared. */ free (dirs[newfd].name); dirs[newfd].name = NULL; } return newfd; }