/* * (C) 2007-2010 Alibaba Group Holding Limited. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * * Version: $Id: func.cpp 983 2011-10-31 09:59:33Z duanfei $ * * Authors: * duolong * - initial release * */ #define _XOPEN_SOURCE 500 #include #include #include "func.h" #include #include using namespace std; namespace common { const uint32_t Func::CRC_VALUE=0x4d494e4f; const uint32_t Func::_crc32tab[] = { 0x0,0x77073096,0xee0e612c,0x990951ba,0x76dc419,0x706af48f,0xe963a535,0x9e6495a3,0xedb8832,0x79dcb8a4, 0xe0d5e91e,0x97d2d988,0x9b64c2b,0x7eb17cbd,0xe7b82d07,0x90bf1d91,0x1db71064,0x6ab020f2,0xf3b97148,0x84be41de, 0x1adad47d,0x6ddde4eb,0xf4d4b551,0x83d385c7,0x136c9856,0x646ba8c0,0xfd62f97a,0x8a65c9ec,0x14015c4f,0x63066cd9, 0xfa0f3d63,0x8d080df5,0x3b6e20c8,0x4c69105e,0xd56041e4,0xa2677172,0x3c03e4d1,0x4b04d447,0xd20d85fd,0xa50ab56b, 0x35b5a8fa,0x42b2986c,0xdbbbc9d6,0xacbcf940,0x32d86ce3,0x45df5c75,0xdcd60dcf,0xabd13d59,0x26d930ac,0x51de003a, 0xc8d75180,0xbfd06116,0x21b4f4b5,0x56b3c423,0xcfba9599,0xb8bda50f,0x2802b89e,0x5f058808,0xc60cd9b2,0xb10be924, 0x2f6f7c87,0x58684c11,0xc1611dab,0xb6662d3d,0x76dc4190,0x1db7106,0x98d220bc,0xefd5102a,0x71b18589,0x6b6b51f, 0x9fbfe4a5,0xe8b8d433,0x7807c9a2,0xf00f934,0x9609a88e,0xe10e9818,0x7f6a0dbb,0x86d3d2d,0x91646c97,0xe6635c01, 0x6b6b51f4,0x1c6c6162,0x856530d8,0xf262004e,0x6c0695ed,0x1b01a57b,0x8208f4c1,0xf50fc457,0x65b0d9c6,0x12b7e950, 0x8bbeb8ea,0xfcb9887c,0x62dd1ddf,0x15da2d49,0x8cd37cf3,0xfbd44c65,0x4db26158,0x3ab551ce,0xa3bc0074,0xd4bb30e2, 0x4adfa541,0x3dd895d7,0xa4d1c46d,0xd3d6f4fb,0x4369e96a,0x346ed9fc,0xad678846,0xda60b8d0,0x44042d73,0x33031de5, 0xaa0a4c5f,0xdd0d7cc9,0x5005713c,0x270241aa,0xbe0b1010,0xc90c2086,0x5768b525,0x206f85b3,0xb966d409,0xce61e49f, 0x5edef90e,0x29d9c998,0xb0d09822,0xc7d7a8b4,0x59b33d17,0x2eb40d81,0xb7bd5c3b,0xc0ba6cad,0xedb88320,0x9abfb3b6, 0x3b6e20c,0x74b1d29a,0xead54739,0x9dd277af,0x4db2615,0x73dc1683,0xe3630b12,0x94643b84,0xd6d6a3e,0x7a6a5aa8, 0xe40ecf0b,0x9309ff9d,0xa00ae27,0x7d079eb1,0xf00f9344,0x8708a3d2,0x1e01f268,0x6906c2fe,0xf762575d,0x806567cb, 0x196c3671,0x6e6b06e7,0xfed41b76,0x89d32be0,0x10da7a5a,0x67dd4acc,0xf9b9df6f,0x8ebeeff9,0x17b7be43,0x60b08ed5, 0xd6d6a3e8,0xa1d1937e,0x38d8c2c4,0x4fdff252,0xd1bb67f1,0xa6bc5767,0x3fb506dd,0x48b2364b,0xd80d2bda,0xaf0a1b4c, 0x36034af6,0x41047a60,0xdf60efc3,0xa867df55,0x316e8eef,0x4669be79,0xcb61b38c,0xbc66831a,0x256fd2a0,0x5268e236, 0xcc0c7795,0xbb0b4703,0x220216b9,0x5505262f,0xc5ba3bbe,0xb2bd0b28,0x2bb45a92,0x5cb36a04,0xc2d7ffa7,0xb5d0cf31, 0x2cd99e8b,0x5bdeae1d,0x9b64c2b0,0xec63f226,0x756aa39c,0x26d930a,0x9c0906a9,0xeb0e363f,0x72076785,0x5005713, 0x95bf4a82,0xe2b87a14,0x7bb12bae,0xcb61b38,0x92d28e9b,0xe5d5be0d,0x7cdcefb7,0xbdbdf21,0x86d3d2d4,0xf1d4e242, 0x68ddb3f8,0x1fda836e,0x81be16cd,0xf6b9265b,0x6fb077e1,0x18b74777,0x88085ae6,0xff0f6a70,0x66063bca,0x11010b5c, 0x8f659eff,0xf862ae69,0x616bffd3,0x166ccf45,0xa00ae278,0xd70dd2ee,0x4e048354,0x3903b3c2,0xa7672661,0xd06016f7, 0x4969474d,0x3e6e77db,0xaed16a4a,0xd9d65adc,0x40df0b66,0x37d83bf0,0xa9bcae53,0xdebb9ec5,0x47b2cf7f,0x30b5ffe9, 0xbdbdf21c,0xcabac28a,0x53b39330,0x24b4a3a6,0xbad03605,0xcdd70693,0x54de5729,0x23d967bf,0xb3667a2e,0xc4614ab8, 0x5d681b02,0x2a6f2b94,0xb40bbe37,0xc30c8ea1,0x5a05df1b,0x2d02ef8d}; int Func::get_disk_usage (const char *path, int64_t * used_bytes, int64_t * total_bytes, int64_t *used_rate){ *used_bytes = 1; *total_bytes = 1; struct statfs buf; if (statfs (path, &buf) != 0) { return -1; } *used_bytes = (int64_t) (buf.f_blocks - buf.f_bfree) * buf.f_bsize; *total_bytes = (int64_t) (buf.f_blocks) * buf.f_bsize; *used_rate = (int64_t )100**used_bytes/ *total_bytes; return 0; } #define _LINE_LENGTH 300 bool Func::get_cpu_mem(float &cpu,size_t &mem, int pid,int tid = -1) { bool ret = false; char cmdline[100]; sprintf(cmdline, "ps -o %%cpu,rss,%%mem,pid,tid -mp %d", pid); FILE *file; file = popen(cmdline, "r"); if (file == NULL) { printf("file == NULL\n"); return false; } char line[_LINE_LENGTH]; float l_cpuPrec=0; int l_mem=0; float l_memPrec=0; int l_pid=0; int l_tid=0; if (fgets(line, _LINE_LENGTH, file) != NULL) { if (fgets(line, _LINE_LENGTH, file) != NULL) { sscanf( line, "%f %d %f %d -", &l_cpuPrec, &l_mem, &l_memPrec, &l_pid ); cpu = l_cpuPrec; mem = l_mem/1024; if( tid == -1 ) ret = true; else { while( fgets(line, _LINE_LENGTH, file) != NULL ) { sscanf( line, "%f - - - %d", &l_cpuPrec, &l_tid ); if( l_tid == tid ) { printf("cpuVal is tid:%d\n",tid); cpu = l_cpuPrec; ret = true; break; } } if( l_tid != tid ) printf("TID not exist\n"); } } else printf("PID not exist\n"); } else printf("Command or Parameter wrong\n"); pclose(file); return ret; } //added by zzy bool Func::get_sys_cpu_mem(float & sys_cpu_prec, float & sys_mem_prec, size_t & sys_mem_used) { bool ret = false; char cmdline[100]; char line[_LINE_LENGTH]; float s_cpuPrec = 0; size_t s_mem_total = 0; size_t s_mem_used = 0; memset(cmdline, 0, 100); sprintf(cmdline, "top -n 1|grep Cpu|cut -d \",\" -f 4|sed \"s/\x1B\[[0-9;]*[a-zA-Z]//g\"|sed \"s/\x1B\([0-9;]*[a-zA-Z]//g\"|sed \"s/ //g\""); FILE *file1; file1 = popen(cmdline, "r"); if(file1 == NULL) { printf("file1 == NULL\n"); pclose(file1); return ret; } memset(line, 0, _LINE_LENGTH); if(fgets(line, _LINE_LENGTH, file1) != NULL) { sscanf(line, "%f-", &s_cpuPrec); } else { printf("get CPU info Command or Parameter wrong\n"); pclose(file1); return ret; } pclose(file1); memset(cmdline, 0, 100); sprintf(cmdline, "top -n 1|grep Mem|cut -d \",\" -f 1|cut -d \":\" -f 2|sed \"s/\x1B\[[0-9;]*[a-zA-Z]//g\"|sed \"s/\x1B\([0-9;]*[a-zA-Z]//g\"|sed \"s/ //g\""); FILE *file2; file2 = popen(cmdline, "r"); if(file2 == NULL) { printf("file2 == NULL\n"); pclose(file2); return ret; } memset(line, 0, _LINE_LENGTH); if(fgets(line, _LINE_LENGTH, file2) != NULL) { sscanf(line, "%lu-", &s_mem_total); } else { printf("get mem info Command or Parameter wrong\n"); pclose(file2); return ret; } pclose(file2); memset(cmdline, 0, 100); sprintf(cmdline, "top -n 1|grep Mem|cut -d \",\" -f 2|sed \"s/\x1B\[[0-9;]*[a-zA-Z]//g\"|sed \"s/\x1B\([0-9;]*[a-zA-Z]//g\"|sed \"s/ //g\""); FILE *file3; file3 = popen(cmdline, "r"); if(file3 == NULL) { printf("file3 == NULL\n"); pclose(file3); return ret; } memset(line, 0, _LINE_LENGTH); if(fgets(line, _LINE_LENGTH, file3) != NULL) { sscanf(line, "%lu-", &s_mem_used); } else { printf("get mem info Command or Parameter wrong\n"); pclose(file3); return ret; } pclose(file3); sys_cpu_prec = 100.0 - s_cpuPrec; sys_mem_prec = 1.0 * s_mem_used / s_mem_total; sys_mem_used = s_mem_used / 1024; ret = true; return ret; } bool sys_r_t_bytes_cal(unsigned long int & r_bytes_sys, unsigned long int & t_bytes_sys) { bool ret = false; FILE *fp = fopen("/proc/net/dev", "r"); if(fp == NULL) { printf("open file /proc/net/dev failed!\n"); return ret; } char buf[200], ifname[20]; unsigned long int r_bytes = 0, t_bytes = 0, r_packets = 0, t_packets = 0; // skip first two lines for (int i = 0; i < 2; i++) { fgets(buf, 200, fp); } unsigned long int r_bytes_total = 0, t_bytes_total = 0; while (fgets(buf, 200, fp)) { sscanf(buf, "%[^:]: %lu %lu %*lu %*lu %*lu %*lu %*lu %*lu %lu %lu", ifname, &r_bytes, &r_packets, &t_bytes, &t_packets); r_bytes_total += r_bytes; t_bytes_total += t_bytes; } r_bytes_sys = r_bytes_total; t_bytes_sys = t_bytes_total; ret = true; fclose(fp); return ret; } bool Func::get_sys_net_io(float & sys_net_io) { bool ret = false; unsigned long int r_bytes_sys_t1 = 0, t_bytes_sys_t1 = 0; unsigned long int r_bytes_sys_t2 = 0, t_bytes_sys_t2 = 0; struct timeval start, end; unsigned long timer; ret = sys_r_t_bytes_cal(r_bytes_sys_t1, t_bytes_sys_t1); gettimeofday(&start, NULL); if(ret == false) { printf("call sys_r_t_bytes failed!\n"); return ret; } sleep(1); ret = sys_r_t_bytes_cal(r_bytes_sys_t2, t_bytes_sys_t2); if(ret == false) { printf("call sys_r_t_bytes failed!\n"); return ret; } gettimeofday(&end, NULL); timer = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec- start.tv_usec; float net_io = (1.0 * ((r_bytes_sys_t2 - r_bytes_sys_t1) + (t_bytes_sys_t2 - t_bytes_sys_t1)) / timer) * 1000000; sys_net_io = net_io; ret = true; return ret; } //added by zzy int Func::get_base_name(const char* _path, char* dirpath) { char path[255]={0}; strcpy(path,_path); int length = strlen(path); char* slash = path + length - 1; while (*slash == '/') { slash--; length--; } for (; length > 0; length--) { if (path[length - 1] == '/') { length--; break; } } if (length == 0) { strcpy(dirpath, "."); } else { memcpy(dirpath, path, length); dirpath[length] = '\0'; } return 0; } int32_t Func::split_string(const char* line, const char del, std::vector& fields) { const char* start = line; const char* p = NULL; char buffer[BUFSIZ]; while (start != NULL) { p = strchr(start, del); if (p != NULL) { assert(p - start < BUFSIZ); strncpy(buffer, start, p - start); buffer[p - start] = 0; if (buffer[0] != '\0') fields.push_back(buffer); start = p + 1; } else { if (start[0] != '\0') fields.push_back(start); break; } } return fields.size(); } uint32_t Func::get_local_addr(const char* dev_name) { int fd, intrface; struct ifreq buf[16]; struct ifconf ifc; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) <= 0) { return 0; } ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t) buf; if (ioctl(fd, SIOCGIFCONF, (char *) &ifc)) { close(fd); return 0; } intrface = ifc.ifc_len / sizeof(struct ifreq); while (intrface-- > 0) { if (ioctl(fd, SIOCGIFFLAGS, (char *) &buf[intrface])) { continue; } if (buf[intrface].ifr_flags & IFF_LOOPBACK) continue; if (!(buf[intrface].ifr_flags & IFF_UP)) continue; if (dev_name != NULL && strcmp(dev_name, buf[intrface].ifr_name)) continue; if (!(ioctl(fd, SIOCGIFADDR, (char *) &buf[intrface]))) { close(fd); return ((struct sockaddr_in *) (&buf[intrface].ifr_addr))->sin_addr.s_addr; } } close(fd); return 0; } // get avg load in one minute int Func::get_load_avg() { int l = 0; double d; if (getloadavg(&d, 1) == 1) { l = (int) (d * 100); if (l < 10) l = 10; } return l; } // create dir int Func::make_directory(char* dirpath) { struct stat stats; if (lstat(dirpath, &stats) == 0 && S_ISDIR(stats.st_mode)) return (0); mode_t umask_value = umask(0); umask(umask_value); mode_t mode = ((S_IRWXU | S_IRWXG | S_IRWXO) & (~umask_value)) | S_IWUSR | S_IXUSR; char* slash = dirpath; while (*slash == '/') slash++; while (1) { slash = strchr(slash, '/'); if (slash == NULL) break; *slash = '\0'; mkdir(dirpath, mode); *slash++ = '/'; while (*slash == '/') slash++; } if (mkdir(dirpath, mode) == -1) return -1; else return 0; } // get self ip // convert to lower char* Func::str_to_lower(char* psz_buf) { if (psz_buf == NULL) return psz_buf; char* p = psz_buf; while (*p) { if ((*p) & 0x80) p++; else if ((*p) >= 'A' && (*p) <= 'Z') (*p) += 32; p++; } return psz_buf; } // convert to upper char* Func::str_to_upper(char* psz_buf) { if (psz_buf == NULL) return psz_buf; char* p = psz_buf; while (*p) { if ((*p) & 0x80) p++; else if ((*p) >= 'a' && (*p) <= 'z') (*p) -= 32; p++; } return psz_buf; } uint32_t Func::crc(uint32_t crc, const char* data, const int32_t len) { int32_t i; for (i = 0; i < len; ++i) { crc = (crc >> 8) ^ _crc32tab[(crc ^ (*data)) & 0xff]; data++; } return (crc); } int Func::write_pid(const char* lock_file) { int lfp = open(lock_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (lfp < 0) exit(1); char str[32]; int pid = getpid(); sprintf(str, "%d\n", getpid()); write(lfp, str, strlen(str)); close(lfp); return pid; } uint64_t Func::getphymemsize () { return sysconf (_SC_PHYS_PAGES) * sysconf (_SC_PAGESIZE); } int64_t Func::curr_time() { struct timeval t; gettimeofday(&t, NULL); return (t.tv_sec * 1000000LL + t.tv_usec); } int Func::GetLocalIP (const char *dev_name, char *ipaddr) { int sock_get_ip; struct sockaddr_in *sin; struct ifreq ifr_ip; if ((sock_get_ip = socket (AF_INET, SOCK_STREAM, 0)) == -1) { printf ("socket create failse...GetLocalIp!/n"); return -1; } memset (&ifr_ip, 0, sizeof (ifr_ip)); strncpy (ifr_ip.ifr_name, dev_name, sizeof (ifr_ip.ifr_name) - 1); if (ioctl (sock_get_ip, SIOCGIFADDR, &ifr_ip) < 0) { return -1; } sin = (struct sockaddr_in *) &ifr_ip.ifr_addr; strcpy (ipaddr, inet_ntoa (sin->sin_addr)); //printf ("local ip:%s \n", ipaddr); close (sock_get_ip); return 0; } }/** common **/