xi_file_re xi_file_unlock(xint32 fd, xint64 spos, xint64 len) { OVERLAPPED overlapped; const DWORD offsetLow = (DWORD)(spos & 0xFFFFFFFF); const DWORD offsetHigh = (DWORD)((spos >> 0x20) & 0x7FFFFFFF); const DWORD nNumberOfBytesToUnlockLow = (DWORD)(len & 0xFFFFFFFF); const DWORD nNumberOfBytesToUnlockHigh = (DWORD)((len >> 0x20) & 0x7FFFFFFF); xg_fd_t *fdesc; if (fd < 0) { return XI_FILE_RV_ERR_ARGS; } fdesc = xg_fd_get(fd); xi_mem_set(&overlapped, 0, sizeof(overlapped)); overlapped.Offset = offsetLow; overlapped.OffsetHigh = offsetHigh; if (!UnlockFileEx(fdesc->desc.f.fd, /* [in] file handle to lock */ (DWORD) 0, /* [in] reserved */ nNumberOfBytesToUnlockLow, /* [in] number of bytes to lock (low) */ nNumberOfBytesToUnlockHigh, /* [in] number of bytes to lock (high) */ (LPOVERLAPPED) & overlapped)) { /* [in] contains file offset to lock start */ return XI_FILE_RV_ERR_ARGS; } return XI_FILE_RV_OK; }
xint64 xi_file_seek(xint32 fd, xint64 pos, xint32 whence) { LARGE_INTEGER ret; xint32 method = 0; xg_fd_t *fdesc; if (fd < 0) { return XI_FILE_RV_ERR_ARGS; } ret.QuadPart = pos; switch (whence) { case XI_FILE_SEEK_SET: method = FILE_BEGIN; break; case XI_FILE_SEEK_CUR: method = FILE_CURRENT; break; case XI_FILE_SEEK_END: method = FILE_END; break; default: return XI_FILE_RV_ERR_ARGS; } fdesc = xg_fd_get(fd); ret.LowPart = SetFilePointer(fdesc->desc.f.fd, ret.LowPart, &ret.HighPart, method); if (ret.LowPart == INVALID_SET_FILE_POINTER) { return XI_FILE_RV_ERR_ARGS; } return ret.QuadPart; }
xssize xi_file_write(xint32 fd, const xvoid *buf, xsize buflen) { xbool ret = 0; xg_fd_t *fdesc = NULL; DWORD wbytes = 0; DWORD blen = (DWORD) buflen; if (fd < 0 || buf == NULL) { return XI_FILE_RV_ERR_ARGS; } if (buflen == 0) { return 0; } fdesc = xg_fd_get(fd); if (fdesc->type == XG_FD_TYPE_FILE || fdesc->type == XG_FD_TYPE_PIPE) { ret = WriteFile(fdesc->desc.f.fd, buf, blen, &wbytes, NULL); if (!ret) { return XI_FILE_RV_ERR_ARGS; } } else if (fdesc->type == XG_FD_TYPE_SOCK) { wbytes = send(fdesc->desc.s.fd, (xchar *)buf, blen, 0); if ((xint32)wbytes == SOCKET_ERROR) { return XI_FILE_RV_ERR_ARGS; } } return wbytes; }
xssize xi_file_read(xint32 fd, xvoid *buf, xsize buflen) { xbool ret = 0; xg_fd_t *fdesc = NULL; DWORD rbytes = 0; DWORD blen = (DWORD) buflen; if (fd < 0 || buf == NULL) { return XI_FILE_RV_ERR_ARGS; } if (buflen == 0) { return 0; } fdesc = xg_fd_get(fd); if (fdesc->type == XG_FD_TYPE_FILE || fdesc->type == XG_FD_TYPE_PIPE) { ret = ReadFile(fdesc->desc.f.fd, buf, blen, &rbytes, NULL); if (!ret) { return XI_FILE_RV_ERR_ARGS; } } else if (fdesc->type == XG_FD_TYPE_SOCK) { rbytes = recv(fdesc->desc.s.fd, (xchar *)buf, blen, 0); if ((xint32)rbytes == SOCKET_ERROR) { return XI_FILE_RV_ERR_ARGS; } } return rbytes; }
xvoid xi_sel_fdset(xint32 fd, xi_fdset_t *fdset) { xg_fd_t *sdesc = xg_fd_get(fd); if (fdset == NULL || sdesc == NULL) { return; } else { fd_set *t = &fdset->fdset; FD_SET(sdesc->desc.s.fd, t); } }
xint32 xi_sel_fdisset(xint32 fd, xi_fdset_t *fdset) { xg_fd_t *sdesc = xg_fd_get(fd); if (fdset == NULL || sdesc == NULL) { return XI_SELECT_RV_ERR_ARGS; } else { fd_set *t = &fdset->fdset; return FD_ISSET(sdesc->desc.s.fd, t); } }
xi_pollset_re xi_pollset_remove(xi_pollset_t *pset, xi_pollfd_t fd) { xuint32 i; xbool found; xg_fd_t *sdesc; if (pset == NULL) { return XI_POLLSET_RV_ERR_ARGS; } if (fd.desc < 0) { return XI_POLLSET_RV_ERR_ARGS; } if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_lock(&pset->lock); } sdesc = xg_fd_get(fd.desc); found = FALSE; for (i=0; i<pset->used; i++) { if (pset->pfds[i].desc == fd.desc) { xi_mem_copy(&(pset->pfds[i]), &(pset->pfds[i+1]), sizeof(xi_pollfd_t) * (pset->used -i-1)); FD_CLR(sdesc->desc.s.fd, &pset->set_read); FD_CLR(sdesc->desc.s.fd, &pset->set_write); FD_CLR(sdesc->desc.s.fd, &pset->set_except); found = TRUE; break; } } if (!found) { if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } return XI_POLLSET_RV_ERR_NF; } pset->used--; if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } return XI_POLLSET_RV_OK; }
xi_file_re xi_file_close(xint32 fd) { xbool ret; xg_fd_t *fdesc; if (fd < 0) { return XI_FILE_RV_ERR_ARGS; } fdesc = xg_fd_get(fd); ret = CloseHandle(fdesc->desc.f.fd); if (!ret) { return XI_FILE_RV_ERR_ARGS; } return xg_fd_close(fd); }
xi_pollset_re xi_pollset_add(xi_pollset_t *pset, xi_pollfd_t fd) { xg_fd_t *sdesc; if (pset == NULL) { return XI_POLLSET_RV_ERR_ARGS; } if (fd.desc < 0) { return XI_POLLSET_RV_ERR_ARGS; } if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_lock(&pset->lock); } if (pset->used >= pset->size) { if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } return XI_POLLSET_RV_ERR_OVER; } sdesc = xg_fd_get(fd.desc); if (fd.evts & XI_POLL_EVENT_IN) { FD_SET(sdesc->desc.s.fd, &pset->set_read); } if (fd.evts & XI_POLL_EVENT_OUT) { FD_SET(sdesc->desc.s.fd, &pset->set_write); } if (fd.evts & XI_POLL_EVENT_ERR) { FD_SET(sdesc->desc.s.fd, &pset->set_except); } pset->pfds[pset->used].desc = fd.desc; pset->pfds[pset->used].evts = fd.evts; pset->pfds[pset->used].context = fd.context; pset->used++; if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } return XI_POLLSET_RV_OK; }
xi_file_re xi_file_sync(xint32 fd) { xbool ret; xg_fd_t *fdesc; if (fd < 0) { return XI_FILE_RV_ERR_ARGS; } fdesc = xg_fd_get(fd); if (fdesc->type != XG_FD_TYPE_FILE) { return XI_FILE_RV_ERR_ARGS; } ret = FlushFileBuffers(fdesc->desc.f.fd); if (!ret) { return XI_FILE_RV_ERR_ARGS; } return XI_FILE_RV_OK; }
xint32 xi_file_rpeek(xint32 fd) { xbool ret = 0; DWORD rbytes = 0; xg_fd_t *fdesc = NULL; if (fd < 0) { return XI_FILE_RV_ERR_ARGS; } fdesc = xg_fd_get(fd); if (fdesc->type == XG_FD_TYPE_FILE) { ret = TRUE; } else if (fdesc->type == XG_FD_TYPE_SOCK) { ret = ioctlsocket(fdesc->desc.s.fd, FIONREAD, &rbytes); } if (!ret) { return XI_FILE_RV_ERR_ARGS; } return rbytes; }
xi_file_re xi_file_lock(xint32 fd, xint64 spos, xint64 len, xint32 bexcl, xint32 bwait) { DWORD dwFlags = 0; OVERLAPPED overlapped; const DWORD offsetLow = (DWORD)(spos & 0xFFFFFFFF); const DWORD offsetHigh = (DWORD)((spos >> 0x20) & 0x7FFFFFFF); const DWORD nNumberOfBytesToLockLow = (DWORD)(len & 0xFFFFFFFF); const DWORD nNumberOfBytesToLockHigh = (DWORD)((len >> 0x20) & 0x7FFFFFFF); xg_fd_t *fdesc; if (fd < 0) { return XI_FILE_RV_ERR_ARGS; } fdesc = xg_fd_get(fd); if (!bwait) { dwFlags |= LOCKFILE_FAIL_IMMEDIATELY; } if (bexcl) { dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; } xi_mem_set(&overlapped, 0, sizeof(overlapped)); overlapped.Offset = offsetLow; overlapped.OffsetHigh = offsetHigh; if (!LockFileEx(fdesc->desc.f.fd, /* [in] file handle to lock */ dwFlags, /* [in] flags describing lock type */ (DWORD) 0, /* [in] reserved */ nNumberOfBytesToLockLow, /* [in] number of bytes to lock (low) */ nNumberOfBytesToLockHigh, /* [in] number of bytes to lock (high) */ (LPOVERLAPPED) & overlapped)) { /* [in] contains file offset to lock start */ return XI_FILE_RV_ERR_ARGS; } return XI_FILE_RV_OK; }
xssize xi_file_writev(xint32 fd, const xi_file_iovec_t *iov, xint32 iovlen) { xbool ret = 0; DWORD wbytes = 0; xg_fd_t *fdesc = NULL; xint32 i = 0; xssize totalWrite = 0; if (fd < 0 || iov == NULL) { return XI_FILE_RV_ERR_ARGS; } if (iovlen == 0) { return 0; } fdesc = xg_fd_get(fd); while (i < iovlen) { if (fdesc->type == XG_FD_TYPE_FILE || fdesc->type == XG_FD_TYPE_PIPE) { ret = WriteFile(fdesc->desc.f.fd, iov[i].iov_base, iov[i].iov_len, &wbytes, NULL); if (!ret) { break; } } else if (fdesc->type == XG_FD_TYPE_SOCK) { wbytes = send(fdesc->desc.s.fd, (xchar *)iov[i].iov_base, iov[i].iov_len, 0); if ((xint32)wbytes == SOCKET_ERROR) { break; } } totalWrite += wbytes; i++; } return totalWrite; }
xi_file_re xi_file_fstat(xint32 fd, xi_file_stat_t *s) { BY_HANDLE_FILE_INFORMATION se; SYSTEMTIME st; LARGE_INTEGER fsize; xbool ret; xg_fd_t *fdesc; xi_time_t xtime; xlong utc; if (fd < 0 || s == NULL) { return XI_FILE_RV_ERR_ARGS; } fdesc = xg_fd_get(fd); ret = GetFileInformationByHandle(fdesc->desc.f.fd, &se); if (!ret) { return XI_FILE_RV_ERR_ARGS; } if (se.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { s->type = XI_FILE_TYPE_DIR; } else { s->type = XI_FILE_TYPE_REG; } if (se.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { s->perm = 00400; } else { s->perm = 00600; } fsize.LowPart = se.nFileSizeLow; fsize.HighPart = se.nFileSizeHigh; s->size = fsize.QuadPart; s->blocks = (s->size / 4096L) + 1; FileTimeToSystemTime(&se.ftCreationTime, &st); xtime.year = st.wYear + 1601; xtime.mon = st.wMonth; xtime.day = st.wDay; xtime.hour = st.wHour; xtime.min = st.wMinute; xtime.sec = st.wSecond; xtime.msec = st.wMilliseconds; xi_clock_time2sec(&utc, xtime); s->created = (utc * 1000) + xtime.msec; FileTimeToSystemTime(&se.ftLastAccessTime, &st); xtime.year = st.wYear + 1601; xtime.mon = st.wMonth; xtime.day = st.wDay; xtime.hour = st.wHour; xtime.min = st.wMinute; xtime.sec = st.wSecond; xtime.msec = st.wMilliseconds; xi_clock_time2sec(&utc, xtime); s->accessed = (utc * 1000) + xtime.msec; FileTimeToSystemTime(&se.ftLastWriteTime, &st); xtime.year = st.wYear + 1601; xtime.mon = st.wMonth; xtime.day = st.wDay; xtime.hour = st.wHour; xtime.min = st.wMinute; xtime.sec = st.wSecond; xtime.msec = st.wMilliseconds; xi_clock_time2sec(&utc, xtime); s->modified = (utc * 1000) + xtime.msec; xi_strcpy(s->pathname, fdesc->desc.f.path); xi_strcpy(s->filename, xi_pathname_basename(fdesc->desc.f.path)); return XI_FILE_RV_OK; }
xint32 xi_pollset_poll(xi_pollset_t *pset, xi_pollfd_t *rfds, xint32 rlen, xint32 msecs) { xint32 ret; xuint32 loopcnt, i, j; fd_set tr, tw, te; struct timeval tout; if (pset == NULL || rfds == NULL) { return XI_POLLSET_RV_ERR_ARGS; } if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_lock(&pset->lock); } xi_mem_copy(&tr, &pset->set_read, sizeof(fd_set)); xi_mem_copy(&tw, &pset->set_write, sizeof(fd_set)); xi_mem_copy(&te, &pset->set_except, sizeof(fd_set)); if (msecs < 0) { ret = select(pset->used+1, &tr, &tw, &te, NULL); } else { tout.tv_sec = msecs / 1000; tout.tv_usec = (msecs % 1000) * 1000; ret = select(pset->used+1, &tr, &tw, &te, &tout); } if (ret > 0) { loopcnt = (xuint32)((ret > rlen) ? rlen : ret); for (i=0, j=0; i<pset->used && j<loopcnt; i++) { int ret_events = 0; xg_fd_t *sdesc = xg_fd_get(pset->pfds[i].desc); if (pset->pfds[i].evts & XI_POLL_EVENT_IN) { if (FD_ISSET(sdesc->desc.s.fd, &tr)) { rfds[j] = pset->pfds[i]; ret_events |= XI_POLL_EVENT_IN; } } if (pset->pfds[i].evts & XI_POLL_EVENT_OUT) { if (FD_ISSET(sdesc->desc.s.fd, &tw)) { rfds[j] = pset->pfds[i]; ret_events |= XI_POLL_EVENT_OUT; } } if (pset->pfds[i].evts & XI_POLL_EVENT_ERR) { if (FD_ISSET(sdesc->desc.s.fd, &te)) { rfds[j] = pset->pfds[i]; ret_events |= XI_POLL_EVENT_ERR; } } if (ret_events) { rfds[j].evts = ret_events; j++; } } } else if (ret == 0) { if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } return XI_POLLSET_RV_ERR_TIMEOUT; } else { if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } switch (WSAGetLastError()) { case WSAEINTR: return XI_POLLSET_RV_ERR_INTR; default: return XI_POLLSET_RV_ERR_ARGS; } } if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } return loopcnt; }
#endif // _WIN64 if (fhnd == NULL) { log_print(XDLOG, "File mapping is failed!!!!!!!!!!!\n"); return XI_MMAP_RV_ERR_NFILE; } ret = MapViewOfFile(fhnd, mvaccess, (DWORD)((offset>>0x20)&0x7fffffff), (DWORD)(offset&0xffffffff), length); if (ret == NULL) { CloseHandle(fhnd); return XI_MMAP_RV_ERR_ARGS; } else { (*addr) = VirtualAlloc(ret, length, MEM_COMMIT, fmaccess);; CloseHandle(fhnd); return XI_MMAP_RV_OK; } } else { fdesc = xg_fd_get(fd); if (fdesc == NULL) { log_print(XDLOG, "Cannot get the descriptor!!!!!!!!!!!\n"); return XI_MMAP_RV_ERR_BADFD; } fhnd = CreateFileMapping(fdesc->desc.f.fd, NULL, fmaccess, 0, 0, NULL); if (fhnd == NULL) { log_print(XDLOG, "File mapping is failed!!!!!!!!!!!\n"); return XI_MMAP_RV_ERR_NFILE; } ret = MapViewOfFile(fhnd, mvaccess, (DWORD)((offset>>0x20)&0x7fffffff), (DWORD)(offset&0xffffffff), length); if (ret == NULL) { CloseHandle(fhnd); return XI_MMAP_RV_ERR_ARGS; } else { (*addr) = ret;