int zrt_zcall_ftruncate(int fd, off_t length){ CHECK_EXIT_IF_ZRT_NOT_READY; LOG_SYSCALL_START("fd=%d,length=%lld", fd, length); struct MountsPublicInterface* transpar_mount = transparent_mount(); assert(transpar_mount); errno=0; int ret; off_t saved_pos; struct stat st; /*save file position*/ saved_pos = lseek( fd, 0, SEEK_CUR); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(saved_pos); /*get end pos of file*/ ret = fstat(fd, &st); assert(ret==0); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(st.st_size); /*if filesize should be increased then just write null bytes '\0' into*/ if ( length > st.st_size ){ /*set cursor to the end of file, and check assertion*/ off_t endpos = lseek( fd, st.st_size, SEEK_SET); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(st.st_size); assert(endpos==st.st_size); /*just write amount of bytes starting from end of file*/ int res = write_file_padding(fd, length-st.st_size); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(res); } else{ /*truncate data if user wants to reduce filesize *set new file size*/ int res = transpar_mount->ftruncate_size(transpar_mount, fd, length); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(res); } /*restore file position, it's should stay unchanged*/ if ( saved_pos < length ){ LSEEK_SET_ASSERT_IF_FAIL(fd, saved_pos); } else if (saved_pos > length){ /*it is impossible to restore oldpos because it's not valid anymore *it's pointing beyond of the file*/ } /*final check of real file size and expected size*/ ret = fstat(fd, &st); assert(ret==0); ZRT_LOG(L_INFO, "real truncated file size is %lld", st.st_size ); assert(st.st_size==length); LOG_SHORT_SYSCALL_FINISH( 0, "fd=%d, old_length=%lld,new_length=%lld", fd, st.st_size, length); return 0; }
int zrt_zcall_stat_realpath(const char* abspathname, struct stat *stat){ CHECK_EXIT_IF_ZRT_NOT_READY; LOG_SYSCALL_START("abspathname=%p, stat=%p", abspathname, stat); struct MountsPublicInterface* transpar_mount = transparent_mount(); assert(transpar_mount); errno=0; VALIDATE_SUBSTITUTED_SYSCALL_PTR(abspathname); int ret = transpar_mount->stat(transpar_mount, abspathname, stat); LOG_SHORT_SYSCALL_FINISH(ret, "abspathname=%s", abspathname); return ret; }
int zrt_zcall_rmdir(const char *pathname){ CHECK_EXIT_IF_ZRT_NOT_READY; char* absolute_path; char temp_path[PATH_MAX]; int ret=-1; LOG_SYSCALL_START("pathname=%s", pathname); VALIDATE_SUBSTITUTED_SYSCALL_PTR(pathname); errno=0; struct MountsPublicInterface* transpar_mount = transparent_mount(); assert(transpar_mount); if ( (absolute_path = realpath(pathname, temp_path)) != NULL ){ ret = transpar_mount->rmdir( transpar_mount, absolute_path ); } LOG_SHORT_SYSCALL_FINISH(ret, "pathname=%s", pathname); return ret; }
/*override system glibc implementation */ int fcntl(int fd, int cmd, ... /* arg */ ){ int ret=0; LOG_SYSCALL_START("fd=%d cmd=%d", fd, cmd); errno=0; struct MountsInterface* transpar_mount = transparent_mount(); assert(transpar_mount); va_list args; va_start(args, cmd); if ( cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK ){ struct flock* input_lock = va_arg(args, struct flock*); ZRT_LOG(L_SHORT, "flock=%p", input_lock ); ret = transpar_mount->fcntl(fd, cmd, input_lock); } va_end(args); LOG_SYSCALL_FINISH(ret, "fd=%d, cmd=%s", fd, STR_FCNTL_CMD(cmd)); return ret; }
int zrt_zcall_rename (const char *oldpath, const char *newpath){ CHECK_EXIT_IF_ZRT_NOT_READY; char* absolute_path1; char* absolute_path2; char temp_path1[PATH_MAX]; char temp_path2[PATH_MAX]; int ret=-1; errno=0; LOG_SYSCALL_START("old=%p, new=%p", oldpath, newpath); struct MountsPublicInterface* transpar_mount = transparent_mount(); assert(transpar_mount); VALIDATE_SUBSTITUTED_SYSCALL_PTR(oldpath); VALIDATE_SUBSTITUTED_SYSCALL_PTR(newpath); if ( (absolute_path1 = realpath(oldpath, temp_path1)) != NULL && (absolute_path2 = zrealpath(newpath, temp_path2)) != NULL){ ret = transpar_mount->rename(transpar_mount, absolute_path1, absolute_path2); } LOG_SHORT_SYSCALL_FINISH(ret, "old=%s, new=%s", oldpath, newpath); return ret; }