int zrt_zcall_enhanced_open(const char *name, int flags, mode_t mode, int *newfd){ LOG_SYSCALL_START("name=%s flags=%d mode=%o(octal)", name, flags, mode ); char* absolute_path; char temp_path[PATH_MAX]; int ret=-1; errno=0; VALIDATE_SYSCALL_PTR(name); /*reset mode bits, that is not actual for permissions*/ mode&=(S_IRWXU|S_IRWXG|S_IRWXO); APPLY_UMASK(&mode); if ( (absolute_path = zrealpath(name, temp_path)) != NULL ){ ZRT_LOG(L_SHORT, "absolute_path=%s", absolute_path); if ( (ret = s_transparent_mount->open(s_transparent_mount, absolute_path, flags, mode )) >= 0 ){ /*get fd by pointer*/ *newfd = ret; ret =0; } } LOG_SHORT_SYSCALL_FINISH( ret, "*newfd=%d, name=%s, flags=%s, mode=%s", *newfd, name, STR_ALLOCA_COPY(STR_FILE_OPEN_FLAGS(flags)), STR_ALLOCA_COPY(STR_STAT_ST_MODE(mode))); return ret; }
int zrt_zcall_enhanced_seek(int handle, off_t offset, int whence, off_t *new_offset){ int ret=-1; LOG_SYSCALL_START("handle=%d offset=%lld whence=%d", handle, offset, whence); errno = 0; if ( whence == SEEK_SET && offset < 0 ){ SET_ERRNO(EINVAL); } else{ offset = s_transparent_mount->lseek(s_transparent_mount,handle, offset, whence); if ( offset != -1 ){ /*get new offset by pointer*/ *new_offset = offset; ret=0; } else{ /*return errno as error*/ return errno; } } LOG_SHORT_SYSCALL_FINISH( ret, "newoffset=%lld, handle=%d whence=%s", offset, handle, STR_SEEK_WHENCE(whence)); return ret; }
int zrt_zcall_enhanced_munmap(void *addr, size_t len){ LOG_SYSCALL_START("addr=%p, len=%u", addr, len); struct MemoryManagerPublicInterface* memif = memory_interface_instance(); int32_t retcode = memif->munmap(memif, addr, len); LOG_INFO_SYSCALL_FINISH( retcode, "addr=%p, len=%u", addr, len); return retcode; }
int zrt_zcall_fchdir(int fd){ CHECK_EXIT_IF_ZRT_NOT_READY; errno=0; LOG_SYSCALL_START(P_TEXT, ""); int ret = -1; const struct HandleItem* entry = get_handle_allocator()->entry(fd); if ( entry == NULL ){ SET_ERRNO(EBADF); return -1; } /*get reference to filesystem that related to path*/ struct MountsPublicInterface* fs_implementation = entry->mount_fs; struct MountSpecificPublicInterface* fs_specific_implementation = fs_implementation->implem(fs_implementation); const char* path = fs_specific_implementation->handle_path(fs_specific_implementation, fd); if ( path != NULL ){ ret = chdir(path); } else{ SET_ERRNO(ENOENT); return -1; } LOG_SHORT_SYSCALL_FINISH( ret, "get_phys_pages=%d", ret ); return ret; }
/*get pointer to file structure *substitude glibc implementation */ FILE *fdopen(int fd, const char *mode){ LOG_SYSCALL_START("fd=%d mode=%s", fd, mode); FILE* f = NULL; struct MountsManager* mm = mounts_manager(); /*get access to main mounts object*/ struct MountsInterface* mif = mm->mount_byhandle(fd); /*get valid mount or NULL*/ if ( mif ){ struct mount_specific_implem* implem = mif->implem(); assert(implem); /*mount specific implem can't be NULL*/ /*check if handle has appropriate path*/ const char* path = implem->handle_path(fd); /*run fopen with path parameter instead fd handle*/ if ( path ){ ZRT_LOG(L_SHORT, "fopen(path:%s, mode:%s)", path, mode); f = fopen(path, mode); } } if ( f == NULL ){ SET_ERRNO(EBADF); } LOG_SYSCALL_FINISH( (f==NULL), "fd=%d mode=%s", fd, mode ); return f; }
/* irt fdio *************************/ int zrt_zcall_enhanced_close(int handle){ LOG_SYSCALL_START("handle=%d", handle); errno = 0; int ret = s_transparent_mount->close(s_transparent_mount,handle); LOG_SHORT_SYSCALL_FINISH( ret, "handle=%d", handle); return ret; }
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_enhanced_fstat(int handle, struct stat *st){ LOG_SYSCALL_START("handle=%d stat=%p", handle, st); errno = 0; VALIDATE_SYSCALL_PTR(stat); int ret = s_transparent_mount->fstat(s_transparent_mount, handle, st); if ( ret == 0 ){ ZRT_LOG_STAT(L_INFO, st); } LOG_SHORT_SYSCALL_FINISH( ret, "handle=%d", handle); return ret; }
/* irt memory *************************/ int zrt_zcall_enhanced_sysbrk(void **newbrk){ int ret=-1; LOG_SYSCALL_START("*newbrk=%p", *newbrk); struct MemoryManagerPublicInterface* memif = memory_interface_instance(); int32_t retaddr = memif->sysbrk(memif, *newbrk ); if ( retaddr != -1 ){ /*get new address via pointer*/ *newbrk = (void*)retaddr; ret=0; } LOG_INFO_SYSCALL_FINISH( retaddr, "*newbrk=%p", *newbrk); return ret; }
int zrt_zcall_enhanced_getdents(int fd, struct dirent *dirent_buf, size_t count, size_t *nread){ int ret = -1; LOG_SYSCALL_START("fd=%d dirent_buf=%p count=%u", fd, dirent_buf, count); errno=0; VALIDATE_SYSCALL_PTR(dirent_buf); int32_t bytes_readed = s_transparent_mount->getdents(s_transparent_mount, fd, (char*)dirent_buf, count); if ( bytes_readed >= 0 ){ *nread = bytes_readed; ret=0; } LOG_SHORT_SYSCALL_FINISH( ret, "fd=%d count=%u", fd, count); return ret; }
int zrt_zcall_enhanced_read(int handle, void *buf, size_t count, size_t *nread){ int ret=-1; LOG_SYSCALL_START("handle=%d buf=%p count=%u", handle, buf, count); errno = 0; VALIDATE_SYSCALL_PTR(buf); int32_t bytes_read = s_transparent_mount->read(s_transparent_mount,handle, buf, count); if ( bytes_read >= 0 ){ /*get read bytes by pointer*/ *nread = bytes_read; ret = 0; } LOG_INFO_SYSCALL_FINISH( ret, "bytes_read=%d, handle=%d", bytes_read, handle); return ret; }
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_enhanced_stat(const char *pathname, struct stat * stat){ LOG_SYSCALL_START("pathname=%s stat=%p", pathname, stat); char* absolute_path; char temp_path[PATH_MAX]; int ret=-1; errno = 0; VALIDATE_SYSCALL_PTR(pathname); VALIDATE_SYSCALL_PTR(stat); if ( (absolute_path = realpath(pathname, temp_path)) != NULL ){ if ( (ret = s_transparent_mount->stat(s_transparent_mount, absolute_path, stat)) == 0 ){ ZRT_LOG_STAT(L_INFO, stat); } } LOG_SHORT_SYSCALL_FINISH( ret, "pathname=%s", pathname); 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_enhanced_mmap(void **addr, size_t length, int prot, int flags, int fd, off_t off){ int32_t retcode = -1; LOG_SYSCALL_START("addr=%p length=%u prot=%u flags=%u fd=%u off=%lld", *addr, length, prot, flags, fd, off); struct MemoryManagerPublicInterface* memif = memory_interface_instance(); retcode = memif->mmap(memif, *addr, length, prot, flags, fd, off); if ( (void*)retcode != MAP_FAILED ){ *addr = (void*)retcode; retcode=0; } LOG_INFO_SYSCALL_FINISH( retcode, "addr=%p length=%u prot=%s flags=%s fd=%u off=%lld", *addr, length, STR_ALLOCA_COPY(STR_MMAP_PROT_FLAGS(prot)), STR_ALLOCA_COPY(STR_MMAP_FLAGS(flags)), fd, off); return retcode; }
int zrt_zcall_enhanced_write(int handle, const void *buf, size_t count, size_t *nwrote){ int ret=-1; int log_state = __zrt_log_is_enabled(); /*disable logging while writing to stdout and stderr channel */ if ( handle <= 2 && log_state ){ __zrt_log_enable(0); } LOG_SYSCALL_START("handle=%d buf=%p count=%u", handle, buf, count); VALIDATE_SYSCALL_PTR(buf); int32_t bytes_wrote = s_transparent_mount->write(s_transparent_mount,handle, buf, count); if ( bytes_wrote >= 0 ){ /*get wrote bytes by pointer*/ *nwrote = bytes_wrote; ret=0; } LOG_INFO_SYSCALL_FINISH( ret, "bytes_wrote=%d, handle=%d count=%u", bytes_wrote, handle, count); if ( log_state ) __zrt_log_enable(log_state); /*restore log state*/ 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; }