一、简介
对linux下C/C++代码的总结,以便以后的参考。
二、详解
1、文件重命名
bool rename(const char* src, const char* dst)
{
struct stat src_stat;
struct stat dst_stat;
char dst_tmp[PATH_MAX];
if (::stat(src, &src_stat) < 0)
return false;
int i;
for (i = strlen(dst) - 1; i >= 0; i--)
{
if (dst[i] == '/')
break;
}
memcpy(dst_tmp, dst, i + 1);
dst_tmp[i + 1] = '\0';
if (::stat(dst_tmp, &dst_stat) < 0)
return false;
if (src_stat.st_dev == dst_stat.st_dev) //
{
if (::rename(src, dst) != -1)
return true;
return false;
}
else //
{
string cmd = "mv ";
cmd += src;
cmd += " ";
cmd += dst;
return (::system(cmd.c_str()) != -1);
}
}
2、C++读写文件
/***c++相对的文件读取方式***/
void read_db_info(string& user_name, string& password, string& connect_string)
{
ifstream fs(".passwd");
assert(fs != NULL);
char ch;
user_name = "";
while (fs.get(ch)) {
if (ch == '\n')
break;
else
user_name += ch;
}
password = "";
while (fs.get(ch)) {
if (ch == '\n')
break;
else
password += ch;
}
connect_string = "";
while (fs.get(ch)) {
if (ch == '\n')
break;
else
connect_string += ch;
}
}
void read_db_info(string& connect_string)
{
ifstream fs(".passwd");
assert(fs != NULL);
char ch;
connect_string = "";
while (fs.get(ch)) {
if (ch == '\n')
break;
else
connect_string += ch;
}
}
void write_db_info(const string& user_name, const string& password, const string& connect_string)
{
ofstream fs(".passwd");
assert(fs != NULL);
fs << user_name << '\n';
fs << password << '\n';
fs << connect_string << '\n';
}
3、获取Oracle数据库序列
/************************************
OBJECT = occi.cpp
EXEC = occi
LIBS=-I$(ORACLE_HOME)/precomp/public \
-I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/rdbms/public
PUBFLAGS = -L$(ORACLE_HOME)/lib -L$(ORACLE_HOME)/rdbms/lib -lclntsh -locci
cc = xlC_r -q64
all:
$(cc) -g -o $(EXEC) $(OBJECT) $(LIBS) $(PUBFLAGS)
ok:
./$(EXEC)
clean:
rm -rf $(EXEC) *.o
****************************************/
#include<occi.h>
#include <iostream>
#include <string>
using namespace std;
using namespace oracle::occi;
unsigned int get_sequences(string name, string pw, string cons, string sn_name)
{
Environment *env = NULL;
Connection *conn = NULL;
Statement *stmt = NULL;
ResultSet *rs = NULL;
string username = name;
string password = pw;
string connstring = cons;
string sql = "";
unsigned int num = 0;
sql += "select " + sn_name + ".nextval from dual";
try{
env = Environment::createEnvironment();
conn = env->createConnection(username, password, connstring);
stmt = conn->createStatement();
stmt->setSQL(sql);
rs = stmt->executeQuery();
if (rs->next()) {
num = rs->getUInt(1);
}
else {
cout<<"get wrong id!"<<endl;
}
stmt->closeResultSet (rs);
}catch(SQLException &ex){
if (rs) stmt->closeResultSet (rs);
cout<<"error:"<<ex.what()<<endl;
}
conn->terminateStatement(stmt);
env->terminateConnection(conn);
Environment::terminateEnvironment(env);
return num;
}
int main()
{
string username ="audit_user";
string password="audit_user";
string connstring="IOCS";
string sequences_name = "ZTE_SOFT";
unsigned int num = get_sequences(username, password, connstring, sequences_name);
cout<<"sequence num is:"<<num<<endl;
return 0;
}
4、守护进程的创建
(1)参考
/* 守护进程的全过程,部分代码需参考include静态库 */
#include "include.h"
#include <sys/time.h>
#include <sys/resource.h>
int close_all_fd() //关闭大于2的所有文件描述符
{
struct rlimit lim;
unsigned int i;
if (getrlimit(RLIMIT_NOFILE, &lim) < 0) return -1;
if (lim.rlim_cur == RLIM_INFINITY) lim.rlim_cur = 1024;
for (i = 3; i < lim.rlim_cur; i ++) {
if (close(i) < 0 && errno != EBADF) return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
int nListenSock = -1, nLocalSock = -1, nRemoteSock = -1;
pid_t nChild;
if (argc != 2) /* 命令行参数:“proxy1 本地端口” */
{
PrintLog(stdout, "proxy1 LOCALPORT\n");
return 1;
}
/* ---------------------------父进程------------------------------- */
/* ① 创建侦听套接字 */
ASSERT(CreateSock(&nListenSock, atoi(argv[1]), 8) == 0);
PrintLog(stdout, "listen service: service is activated.");
//InitServer(); /* ② 进程转后台运行 */
while (1) {
/* ③ 等待并创建连接套接字 */
if (!VERIFY(AcceptSock(&nLocalSock, nListenSock) == 0)) continue; /* ③ 继续等待 */
VERIFY((nChild = fork()) >= 0); /* ④ 创建子进程 */
if (nChild == 0) break; /* 子进程跳转到子进程代码 */
close(nLocalSock); /* ⑤ 父进程关闭连接套接字 */
}
/* ---------------------------子进程------------------------------- */
close(nListenSock); /* ⑦ 子进程关闭侦听套接字 */
dup2(nLocalSock, 0);
dup2(nLocalSock, 1);
dup2(nLocalSock, 2);
close(nLocalSock);
close_all_fd();
printf("-------------begin--------------\n");
execl("./inetd_son", "./inetd_son", 0);
printf("------------end----------------\n");
return 0;
}
(2)centos下守护进程
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <syslog.h>
#include <signal.h>
#include <sys/param.h>
int init_daemon()
{
int pid;
int i;
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGHUP, SIG_IGN);
pid = fork();
if (pid > 0){
exit(0);
}
else if (pid < 0){
return -1;
}
setsid();
pid = fork();
if (pid > 0){
exit(0);
}
else if (pid < 0){
return -1;
}
for (i = 0; i < NOFILE; close(i++));
chdir("/");
umask(0);
signal(SIGCHLD, SIG_IGN);
return 0;
}
int main()
{
init_daemon();
FILE *fd = fopen("/tmp/temp.log", "w+");
while(1){
fprintf(fd, "init_daemon is running...\n");
fflush(fd);
sleep(3);
}
fclose(fd);
return 0;
}
注:使用root权限,文件/tmp/temp.log会不断地增加内容。
5、简单的加密解密
#include<iostream>
#include<cstring>
#include<cstdio>
#include <unistd.h>
using namespace std;
int KEY_LEN = 8;
int key[] = { 0x4A, 0x50, 0x4C, 0x53, 0x43, 0x57, 0x43, 0x44 };
void decrypt(const char* cipher, char* text)
{
int len = strlen(cipher) / 2;
int tmp,i;
for (i = 0; i < len; i++)
{
tmp = (cipher[i * 2] - 'a') << 4;
tmp |= cipher[i * 2 + 1] - 'a';
text[i] = (char)(tmp ^ key[i % KEY_LEN]);
}
text[len] = '\0';
}
void encrypt(const char* text, char* cipher)
{
int len = strlen(text);
char* ptr = cipher;
int tmp;
for (int i = 0; i < len; i++)
{
tmp = static_cast<int>(text[i]) ^ key[i % KEY_LEN];
cipher[i * 2] = ((tmp >> 4) & 0x0f) + 'a';
cipher[i * 2 + 1] = (tmp & 0x0f) + 'a';
}
cipher[len * 2] = '\0';
}
int main(int arg, char ** argv){
char pass[30] = {0};
char text[30] = {0};
cout << "请输入明码:";
cin >> pass;
encrypt(pass,text);
cout << "密码:" << text << endl;
decrypt(text,pass);
cout << "明码:" << pass << endl;
return 0;
}
6、数据压缩和解压缩(zlib库)
/**/
#include <iostream>
#include <string>
#include <fstream>
#include <zlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
using namespace std;
typedef unsigned char* uChar_p;
typedef unsigned long uLong;
const int body_length = 81920;
int compress_body(string&boay, char file_body[])
{
int err;
uLong len = strlen(file_body) + 1;
uLong boay_len = body_length + 1;
char com[body_length+1];
err = compress2((uChar_p)(com), &boay_len, (uChar_p)file_body, len, -1);
if (err != Z_OK) {
cerr << "compess error: " << err << '\n';
return -1;
}
boay = com;
cout << "{" << boay << "}" <<endl;
char uncomp[body_length+1] ={0};
uLong lenth = body_length + 1;
err = uncompress((uChar_p)uncomp, &lenth, (uChar_p)com, boay_len);
if (err != Z_OK) {
cerr << "uncompress error:"<< err <<endl;
return -1;
}
cout << "{" << uncomp << "}" <<endl;
// FILE *fp = fopen("uncompress_body.rsp", "ab");
// fprintf(fp, "%s",uncomp);
// fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
if(argc != 2 ) {
cout<<"please input again!"<<endl;
return -1;
}
char buf[97820];
FILE *fp = fopen(argv[1], "r+");
fseek(fp, 0, SEEK_END);
int len = ftell(fp);
fseek(fp, 0, SEEK_SET);
fread(buf, 1, len+1, fp);
//cout<<buf<<endl;
string boay = "";
compress_body(boay, buf);
// FILE *write_fp = fopen("compress_body.rsp", "ab");
// fprintf(write_fp, "%s",boay.c_str());
// fclose(write_fp);
return 0;
}
编译运行:
g++ -o zlib zlib_test.cpp -lz
./zlib test
压缩后的数据包括特殊字符,也可能包括\0,因此复制的时候要特别注意。
6、select使用
#include <stdio.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/types.h>
#include <stdlib.h>
#include <memory.h>
int main()
{
fd_set readfds;
struct timeval timeout;
int ret;
printf("fdset:%d\n", sizeof(fd_set));
FD_ZERO(&readfds);
FD_SET(0, &readfds);
timeout.tv_sec = 10;
timeout.tv_usec = 0;
while(1)
{
printf("before select!\n");
ret = select(1, &readfds, NULL, NULL, &timeout);
printf("after select!\n");
switch(ret)
{
case 0:
printf("no data in ten seconds.\n");
exit(0);
break;
case -1:
perror("select");
exit(1);
break;
default:
getchar();
printf("data is available now\n");
}
}
return 0;
}