예제 #1
0
파일: dir_utils.cpp 프로젝트: ly20119/mooon
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;
    }
}
예제 #2
0
파일: utils.cpp 프로젝트: sdtm1016/mooon
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;
	}
}
예제 #3
0
파일: dir_utils.cpp 프로젝트: ly20119/mooon
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);
}
예제 #4
0
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;
}
예제 #5
0
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");
}
예제 #6
0
파일: sql_logger.cpp 프로젝트: eyjian/mooon
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;
    }
}
예제 #7
0
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);
}
예제 #8
0
파일: utils.cpp 프로젝트: sdtm1016/mooon
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");
}
예제 #9
0
파일: libssh2.cpp 프로젝트: ly20119/mooon
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;
}
예제 #10
0
파일: libssh2.cpp 프로젝트: ly20119/mooon
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;
}
예제 #11
0
파일: libssh2.cpp 프로젝트: ly20119/mooon
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");
            }
        }
    }
}
예제 #12
0
파일: libssh2.cpp 프로젝트: ly20119/mooon
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;
}
예제 #13
0
파일: libssh2.cpp 프로젝트: ly20119/mooon
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");
            }
        }
    }
}
예제 #14
0
파일: utils.cpp 프로젝트: sdtm1016/mooon
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);
}
예제 #15
0
파일: utils.cpp 프로젝트: sdtm1016/mooon
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);
}
예제 #16
0
파일: udp_socket.cpp 프로젝트: wljcom/mooon
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;
}
예제 #17
0
파일: utils.cpp 프로젝트: sdtm1016/mooon
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");
    }
}
예제 #18
0
void CFileUtils::remove(const char* filepath) throw (CSyscallException)
{
    if (-1 == unlink(filepath))
    {
        if (errno != ENOENT)
            THROW_SYSCALL_EXCEPTION(NULL, errno, "unlink");
    }
}
예제 #19
0
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;
}
예제 #20
0
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);
}
예제 #21
0
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);
}
예제 #22
0
파일: udp_socket.cpp 프로젝트: wljcom/mooon
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);
}
예제 #23
0
파일: udp_socket.cpp 프로젝트: wljcom/mooon
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;
}
예제 #24
0
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;
}
예제 #25
0
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;
}
예제 #26
0
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;
    }
}
예제 #27
0
파일: epoller.cpp 프로젝트: ly20119/mooon
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);
    }
}
예제 #28
0
파일: utils.cpp 프로젝트: sdtm1016/mooon
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;
	}
}
예제 #29
0
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;
}
예제 #30
0
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;
}