void CDirUtils::create_directory_recursive(const char* dirpath, mode_t permissions) { char* slash; char* pathname = strdupa(dirpath); // _GNU_SOURCE char* pathname_p = pathname; // 过滤掉头部的斜杠 while ('/' == *pathname_p) ++pathname_p; for (;;) { slash = strchr(pathname_p, '/'); if (NULL == slash) // 叶子目录 { if (0 == mkdir(pathname, permissions)) break; if (EEXIST == errno) break; THROW_SYSCALL_EXCEPTION(NULL, errno, "mkdir"); } *slash = '\0'; if ((-1 == mkdir(pathname, permissions)) && (errno != EEXIST)) THROW_SYSCALL_EXCEPTION(NULL, errno, "mkdir"); *slash++ = '/'; while ('/' == *slash) ++slash; // 过滤掉相连的斜杠 pathname_p = slash; } }
void CUtils::common_pipe_write(int fd, const char* buffer, int32_t buffer_size) { int ret = 0; int32_t size = buffer_size; // 第一个while循环写入大小 while (true) { ret = write(fd, &size, sizeof(size)); if ((-1 == ret) && (EINTR == errno)) continue; if (-1 == ret) THROW_SYSCALL_EXCEPTION(NULL, errno, "write"); break; } const char* bufferp = buffer; // 第二个while循环根据大小写入内容 while (size > 0) { ret = write(fd, bufferp, size); if ((-1 == ret) && (EINTR == errno)) continue; if (-1 == ret) THROW_SYSCALL_EXCEPTION(NULL, errno, "write"); size -= ret; bufferp += ret; } }
SYS_NAMESPACE_BEGIN void CDirUtils::list(const std::string& dirpath , std::vector<std::string>* subdir_names , std::vector<std::string>* file_names , std::vector<std::string>* link_names) throw (CSyscallException) { DIR* dir = opendir(dirpath.c_str()); if (NULL == dir) THROW_SYSCALL_EXCEPTION(NULL, errno, "opendir"); for (;;) { errno = 0; struct dirent* ent = readdir(dir); if (NULL == ent) { if (errno != 0) { int errcode = errno; if (EACCES == errcode) { // 忽略无权限的 continue; } closedir(dir); THROW_SYSCALL_EXCEPTION(NULL, errcode, "readdir"); } break; // over } // 排除当前目录和父目录 if ((0 == strcmp(ent->d_name, ".")) || (0 == strcmp(ent->d_name, ".."))) { continue; } if (DT_DIR == ent->d_type) { if (subdir_names != NULL) subdir_names->push_back(ent->d_name); } else if (DT_REG == ent->d_type) { if (file_names != NULL) file_names->push_back(ent->d_name); } else if (DT_LNK == ent->d_type) { if (link_names != NULL) link_names->push_back(ent->d_name); } } closedir(dir); }
off_t CFileUtils::get_file_size(int fd) throw (CSyscallException) { struct stat buf; if (-1 == fstat(fd, &buf)) THROW_SYSCALL_EXCEPTION(NULL, errno, "fstat"); if (!S_ISREG(buf.st_mode)) THROW_SYSCALL_EXCEPTION(NULL, errno, "fstat"); return buf.st_size; }
void CSysVSharedMemory::open(const char* path) throw (CSyscallException) { if (NULL == path) THROW_SYSCALL_EXCEPTION(NULL, EINVAL, NULL); key_t key = ftok(path, getpid()); if (-1 == key) THROW_SYSCALL_EXCEPTION(NULL, errno, "ftok"); _shmid = shmget(key, 1, 0); if (-1 == _shmid) THROW_SYSCALL_EXCEPTION(NULL, errno, "shmget"); }
bool CSqlLogger::write_log(const std::string& sql) { try { int32_t length = static_cast<int32_t>(sql.size()); sys::LockHelper<sys::CLock> lock_helper(_lock); if ((-1 == _log_fd) || need_rotate()) { rotate_log(); } if (-1 == _log_fd) { return false; } struct iovec iov[2]; iov[0].iov_base = &length; iov[0].iov_len = sizeof(length); iov[1].iov_base = const_cast<char*>(sql.data()); iov[1].iov_len = sql.size(); ssize_t bytes_written = writev(_log_fd, iov, sizeof(iov)/sizeof(iov[0])); if (bytes_written != static_cast<int>(iov[0].iov_len+iov[1].iov_len)) { const int errcode = errno; THROW_SYSCALL_EXCEPTION(utils::CStringUtils::format_string("writev %s error: %s", _log_filepath.c_str(), sys::Error::to_string(errcode).c_str()), errcode, "writev"); } // 计数 ++_total_lines; const int32_t lines = argument::lines->value(); if ((lines > 0) && (++_num_lines >= lines)) { _num_lines = 0; if (-1 == fdatasync(_log_fd)) { const int errcode = errno; THROW_SYSCALL_EXCEPTION(utils::CStringUtils::format_string("fdatasync %s error: %s", _log_filepath.c_str(), sys::Error::to_string(errcode).c_str()), errno, "fdatasync"); } } return true; } catch (sys::CSyscallException& ex) { MYLOG_ERROR("[%s] write [%s] to [%s] failed: %s\n", _dbinfo->str().c_str(), sql.c_str(), _log_filepath.c_str(), ex.str().c_str()); return false; } }
size_t CFileUtils::file_copy(const char* src_filename, const char* dst_filename) throw (CSyscallException) { int src_fd = open(src_filename, O_RDONLY); if (-1 == src_fd) THROW_SYSCALL_EXCEPTION(NULL, errno, "open"); sys::CloseHelper<int> src_ch(src_fd); int dst_fd = open(dst_filename, O_WRONLY|O_CREAT|O_EXCL); if (-1 == dst_fd) THROW_SYSCALL_EXCEPTION(NULL, errno, "open"); sys::CloseHelper<int> dst_ch(dst_fd); return file_copy(src_fd, dst_fd); }
void CUtils::enable_core_dump(bool enabled, int core_file_size) { if (enabled) { struct rlimit rlim; rlim.rlim_cur = (core_file_size < 0)? RLIM_INFINITY: core_file_size; rlim.rlim_max = rlim.rlim_cur; if (-1 == setrlimit(RLIMIT_CORE, &rlim)) THROW_SYSCALL_EXCEPTION(NULL, errno, "setrlimit"); } if (-1 == prctl(PR_SET_DUMPABLE, enabled? 1: 0)) THROW_SYSCALL_EXCEPTION(NULL, errno, "prctl"); }
void* CLibssh2::open_scp_read_channel(const std::string& remote_filepath) { LIBSSH2_CHANNEL* channel = NULL; LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); for (;;) { struct stat fileinfo; channel = libssh2_scp_recv(session, remote_filepath.c_str(), &fileinfo); if (channel != NULL) break; int errcode = get_session_errcode(); if (errcode != LIBSSH2_ERROR_EAGAIN) { THROW_EXCEPTION(get_session_errmsg(), errcode); } else { if (!timedwait_socket()) { THROW_SYSCALL_EXCEPTION("open scp channel timeout", ETIMEDOUT, "poll"); } } } return channel; }
void* CLibssh2::open_ssh_channel() { LIBSSH2_CHANNEL* channel = NULL; LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); // 建立会话通道 while (true) { channel = libssh2_channel_open_session(session); if (channel != NULL) break; int errcode = get_session_errcode(); if (errcode != LIBSSH2_ERROR_EAGAIN) { THROW_EXCEPTION(get_session_errmsg(), errcode); } else { if (!timedwait_socket()) { THROW_SYSCALL_EXCEPTION("open session timeout", ETIMEDOUT, "poll"); } } } return channel; }
void CLibssh2::validate_authorization(const std::string& password) { int errcode; LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); while (true) { if (!password.empty()) { errcode = libssh2_userauth_password(session, _username.c_str(), password.c_str()); } else { errcode = libssh2_userauth_publickey_fromfile(session, _username.c_str(), "/home/user/.ssh/id_rsa.pub", "/home/user/.ssh/id_rsa", password.c_str()); } if (0 == errcode) { break; } else if (errcode != LIBSSH2_ERROR_EAGAIN) { THROW_EXCEPTION(get_session_errmsg(), get_session_errcode()); } else { if (!timedwait_socket()) { THROW_SYSCALL_EXCEPTION("validate_authorization timeout", ETIMEDOUT, "poll"); } } } }
void* CLibssh2::open_scp_write_channel(const std::string& remote_filepath, int filemode, size_t filesize, time_t mtime, time_t atime) { LIBSSH2_CHANNEL* channel = NULL; LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); for (;;) { channel = libssh2_scp_send_ex(session, remote_filepath.c_str(), filemode&0777, filesize, (long)mtime, (long)atime); if (channel != NULL) break; int errcode = get_session_errcode(); if (errcode != LIBSSH2_ERROR_EAGAIN) { THROW_EXCEPTION(get_session_errmsg(), errcode); } else { if (!timedwait_socket()) { THROW_SYSCALL_EXCEPTION("open scp channel timeout", ETIMEDOUT, "poll"); } } } return channel; }
void CLibssh2::handshake() { LIBSSH2_SESSION* session = static_cast<LIBSSH2_SESSION*>(_session); while (true) { // ssh2握手 int errcode = libssh2_session_handshake(session, _socket_fd); if (0 == errcode) { break; } else if (errcode != LIBSSH2_ERROR_EAGAIN) { THROW_EXCEPTION(get_session_errmsg(), get_session_errcode()); } else { if (!timedwait_socket()) { THROW_SYSCALL_EXCEPTION("handshake timeout", ETIMEDOUT, "poll"); } } } }
bool CUtils::is_directory(int fd) { struct stat buf; if (-1 == fstat(fd, &buf)) THROW_SYSCALL_EXCEPTION(NULL, errno, "fstat"); return S_ISDIR(buf.st_mode); }
bool CUtils::is_directory(const char* path) { struct stat buf; if (-1 == stat(path, &buf)) THROW_SYSCALL_EXCEPTION(NULL, errno, "stat"); return S_ISDIR(buf.st_mode); }
int CUdpSocket::send_to(const void* buffer, size_t buffer_size, const struct sockaddr_in& to_addr) throw (sys::CSyscallException) { int bytes = ::sendto(get_fd(), buffer, buffer_size, 0, (struct sockaddr*)&to_addr, sizeof(struct sockaddr_in)); if (-1 == bytes) THROW_SYSCALL_EXCEPTION(NULL, errno, "sendto"); return bytes; }
void CUtils::set_process_name(const std::string& new_name) { if (!new_name.empty()) { if (-1 == prctl(PR_SET_NAME, new_name.c_str())) THROW_SYSCALL_EXCEPTION(NULL, errno, "prctl"); } }
void CFileUtils::remove(const char* filepath) throw (CSyscallException) { if (-1 == unlink(filepath)) { if (errno != ENOENT) THROW_SYSCALL_EXCEPTION(NULL, errno, "unlink"); } }
uint32_t CFileUtils::get_file_mode(int fd) throw (CSyscallException) { struct stat st; if (-1 == fstat(fd, &st)) THROW_SYSCALL_EXCEPTION(NULL, errno, "fstat"); return st.st_mode; }
uint32_t CFileUtils::crc32_file(const char* filepath) throw (CSyscallException) { int fd = open(filepath, O_RDONLY); if (-1 == fd) THROW_SYSCALL_EXCEPTION(NULL, errno, "open"); sys::CloseHelper<int> ch(fd); return crc32_file(fd); }
off_t CFileUtils::get_file_size(const char* filepath) throw (CSyscallException) { int fd = open(filepath, O_RDONLY); if (-1 == fd) THROW_SYSCALL_EXCEPTION(NULL, errno, "fstat"); sys::CloseHelper<int> ch(fd); return get_file_size(fd); }
void CUdpSocket::listen(uint16_t port) throw (sys::CSyscallException) { struct sockaddr_in listen_addr; int fd = ::socket(AF_INET, SOCK_DGRAM, 0); if (-1 == fd) THROW_SYSCALL_EXCEPTION(NULL, errno, "socket"); listen_addr.sin_family = AF_INET; listen_addr.sin_port = htons(port); listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); memset(listen_addr.sin_zero, 0, sizeof(listen_addr.sin_zero)); if (-1 == bind(fd, (struct sockaddr*)&listen_addr, sizeof(listen_addr))) THROW_SYSCALL_EXCEPTION(NULL, errno, "bind"); set_fd(fd); }
int CUdpSocket::receive_from(void* buffer, size_t buffer_size, struct sockaddr_in* from_addr) throw (sys::CSyscallException) { socklen_t address_len = sizeof(struct sockaddr_in); int bytes = recvfrom(get_fd(), buffer, buffer_size, 0, (struct sockaddr*)from_addr, &address_len); if (-1 == bytes) THROW_SYSCALL_EXCEPTION(NULL, errno, "recvfrom"); return bytes; }
bool CDataChannel::full_write_tofile(int file_fd, size_t& size, size_t offset) { char* buffer = new char[sys::CUtils::get_page_size()]; utils::DeleteHelper<char> dh(buffer, true); size_t remaining_size = size; size_t current_offset = offset; for (;;) { ssize_t retval = CDataChannel::receive(buffer, remaining_size); if (0 == retval) { // 连接被对端关闭 size = size - remaining_size; THROW_SYSCALL_EXCEPTION(NULL, -1, "recv"); } else if (-1 == retval) { // 连接异常 size = size - remaining_size; return false; } else { int written = pwrite(file_fd, buffer, retval, current_offset); if (written != retval) { size = size - remaining_size; THROW_SYSCALL_EXCEPTION(NULL, (-1 == written)? errno: EIO, "pwrite"); } current_offset += written; remaining_size -= written; // 全部接收完成 if (0 == remaining_size) break; } } size = size - remaining_size; return true; }
void* CSysVSharedMemory::attach(int flag) throw (CSyscallException) { if (_shmaddr != NULL) { _shmaddr = shmat(_shmid, NULL, flag); if ((void *)-1 == _shmaddr) THROW_SYSCALL_EXCEPTION(NULL, errno, "shmat"); } return _shmaddr; }
void CSysVSharedMemory::close() throw (CSyscallException) { if (_shmid != -1) { //struct shmid_ds buf; if (-1 == shmctl(_shmid, IPC_RMID, NULL)) THROW_SYSCALL_EXCEPTION(NULL, errno, "shmctl"); _shmid = -1; } }
void CEpoller::del_events(CEpollable* epollable) { int fd = epollable->get_fd(); if (fd != -1) { int retval = epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, NULL); if (-1 == retval) THROW_SYSCALL_EXCEPTION(NULL, errno, "epoll_ctl"); epollable->set_epoll_events(-1); } }
void CUtils::common_pipe_read(int fd, char** buffer, int32_t* buffer_size) { int ret = 0; int32_t size = 0; // 第一个while循环读取大小 while (true) { ret = read(fd, &size, sizeof(size)); if ((-1 == ret) && (EINTR == errno)) continue; if (-1 == ret) THROW_SYSCALL_EXCEPTION(NULL, errno, "read"); break; } *buffer_size = size; *buffer = new char[size]; char* bufferp = *buffer; // 第二个while循环根据大小读取内容 while (size > 0) { ret = read(fd, bufferp, size); if ((0 == ret) || (ret == size)) break; if ((-1 == ret) && (EINTR == errno)) continue; if (-1 == ret) { delete *buffer; THROW_SYSCALL_EXCEPTION(NULL, errno, "read"); } bufferp += ret; size -= ret; } }
bool CSysVSharedMemory::create(const char* path, mode_t mode) throw (CSyscallException) { key_t key = IPC_PRIVATE; // 得到IPC键 if (path != NULL) { key_t key = ftok(path, getpid()); if (-1 == key) THROW_SYSCALL_EXCEPTION(NULL, errno, "ftok"); } // 创建共享内存 _shmid = shmget(key, 1, IPC_CREAT | IPC_EXCL | mode); if (-1 == _shmid) { if (EEXIST == errno) return false; THROW_SYSCALL_EXCEPTION(NULL, errno, "shmget"); } return true; }
ssize_t CDataChannel::send(const char* buffer, size_t buffer_size) { ssize_t retval; if (0 == buffer_size) { THROW_SYSCALL_EXCEPTION(NULL, EINVAL, NULL); } for (;;) { retval = ::send(_fd, buffer, buffer_size, 0); if (retval != -1) break; if (EWOULDBLOCK == errno) break; if (EINTR == errno) continue; THROW_SYSCALL_EXCEPTION(NULL, errno, "send"); } atomic_add(retval, &gs_send_buffer_bytes); return retval; }