📄 rc_ctl_fifo.c
字号:
/*
* 文 件 名:rc_ctl_fifo.c
* 功 能:读管道部分相关的函数
* 作 者:马云龙
* E_mail : mayunlong21@163.com
* 开始时间:2007-4-23 16:17
* 结束时间:2007-4-27 13:13
* 修改时间:
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include "rc_pub_define.h"
#include "rc_pub_type.h"
#include "rc_pub_file.h"
#include "rc_pub_fifo.h"
#include "rc_pub_log.h"
#include "rc_pub_path.h"
#include "rc_pub_packet.h"
#include "rc_pub_lock.h"
#include "rc_ctl_define.h"
#include "rc_ctl_data.h"
#include "rc_ctl_table.h"
extern struct_msg_con *head_con;//链接信息的结构体头指针
extern struct_task_net_w *task_w_cam;//网络写摄像机任务队列头指针
extern pthread_mutex_t mutex_w_cam;//写摄像机任务队列的互斥锁
extern pthread_cond_t cond_w_cam;//写摄像机任务线程要使用的条件变量
int rc_file_r_all(const char *filepath, char **buf);
/*
* 功 能:创建管道的路径
* 参 数:path:存储路径的缓冲区
* len:存储路径的缓冲区大小
* 返回值:直接返回0
*/
int rc_create_path_fifo(char *path, int len)
{
bzero(path, len);
strcat(path, PATH_CONNECT_FIFO);
len = strlen(path);
if(path[len - 1] != '/')
path[len] = '/';
strcat(path, NAME_FIFO_SER_READ);
return 0;
}
/*
* 功 能:创建并以读写方式打开一个管道文件
* 返回值:成功返回打开的管道文件的描述符,否则返回-1
*/
int rc_open_fifo()
{
int res;
int fd;
char path[256];
bzero(path, sizeof(path));
strcat(path, PATH_CONNECT_FIFO);
res = rc_create_dir(path, 0777);
if(res < 0)
return -1;
rc_create_path_fifo(path, sizeof(path));
res = rc_fifo_create(path);
if(res < 0)
return -1;
fd = open(path, O_RDWR);
return fd;
}
/*
* 功 能:向管道中写数据
* 参 数:name:管道文件名
* buf:要写的数据缓冲区
* len:要写的数据缓冲区长度
* 返回值:成功返回写入的数据长度,否则返回值小于0
* 说 明:管道文件不存在返回-2,写数据的时候对管道加锁
*/
int rc_fifo_write_lock(const char *name, unsigned char *buf, unsigned int len)
{
int res;
int ret;
int fd;
int rtn;
int mfd;
fd_set setwfd;
struct timeval timeout;
ret = -1;
res = access(name, F_OK);
if(res < 0)
return -2;
fd = open(name, O_RDWR);// | O_NONBLOCK, 0);
if(fd == -1)
{
printf("%s %d %s(%s)\n", __FILE__, __LINE__, strerror(errno), name);
return -1;
}
timeout.tv_sec = 2;
timeout.tv_usec = 0;
rc_lock_file(fd, F_LOCK, 0);//加锁
FD_ZERO(&setwfd);
FD_SET(fd, &setwfd);
mfd = fd + 1;
rtn = select(mfd, 0, &setwfd, 0, &timeout);
if(rtn <= 0)
{
ret = -1;
goto LAB_RETURN;
}
if(FD_ISSET(fd, &setwfd))
{
res = write(fd, buf, len);
if(res > 0)
{
ret = res;
goto LAB_RETURN;
}
}
LAB_RETURN:
rc_lock_file(fd, F_ULOCK, 0);//解锁
close(fd);
return ret;
}
/*
* 功 能:读管道的线程函数
* 参 数:parameter:入口参数
* 返回值:成功返回0,失败返回-1
* 说 明:
*/
int rc_pthread_fifo_r(char *parameter)
{
int fd;
int res;
int len;
int len_file;
int action;
unsigned short int len_tmp;
unsigned short int len_con;
char type;
char path[256];
unsigned char temp[512];
unsigned char tmp_con[512];
unsigned char *buf = NULL;
char *buf_file = NULL;
struct_buf_fifo *msg = NULL;
struct_info_link cam;
struct_task_net_w *newsnd = NULL;
struct_msg_con con;
fd = rc_open_fifo();
if(fd < 0)
pthread_exit(NULL);
while(1)
{
len = sizeof(struct_buf_fifo);
while(1)
{
msg = malloc(len);
if(msg != NULL)
{
break;
}
}
RE_READ_FIFO:
buf = NULL;
buf_file = NULL;
len_file = 0;
len = sizeof(struct_buf_fifo);
while(1)
{
bzero(msg, len);
res = read(fd, msg, len);
if(res <= 0)
continue;
// printf("%s %d read fifo ok res : %d(%d)\n", __FILE__, __LINE__, res, len);
break;
}
bzero(temp, sizeof(temp));
len_tmp = 0;
switch(msg->eventtype)
{
case TYPE_REQUEST_CGI://cgi请求
len_tmp = rc_create_packet_web(msg->msg.web, temp, msg->pid);
if(len_tmp == 0)
{
goto RE_READ_FIFO;
}
type = TYPE_P_C_WEB;
break;
case TYPE_REQUEST_CTL://控件请求
len_tmp = rc_create_p_con_v_c(msg->msg.request, temp);
type = TYPE_P_C_LINK_ASK;
break;
default:
goto RE_READ_FIFO;
break;
}
action = msg->msg.web.action;
bzero(tmp_con, sizeof(tmp_con));
len_con = rc_create_packet_connect(temp, len_tmp, type, tmp_con);
if(len_con == 0)
{
goto RE_READ_FIFO;
}
buf = malloc(LEN_DATA_1024);
if(buf == NULL)
{
goto RE_READ_FIFO;
}
bzero(buf, sizeof(buf));
len = rc_create_packet(tmp_con, len_con, TYPE_P_F_CTL_CON, buf);
if(len == 0)
{
free(buf);
goto RE_READ_FIFO;
}
bzero(&cam ,sizeof(struct_info_link));
bzero(&con, sizeof(struct_msg_con));
// printf("%s %d serial : %s\n", __FILE__, __LINE__, msg->serial);
res = rc_get_info_cam(msg->serial, head_con, &cam);
if(res < 0)
{
goto RE_READ_FIFO;
}
con.sockfd = cam.sockfd;
strcpy(con.serial, msg->serial);
con.type = cam.type;
con.logintime = cam.logintime;
memcpy(&(con.address), &(cam.address), sizeof(struct sockaddr_in));
if(action == TYPE_P_W_UPDATE)
{
bzero(path, sizeof(path));
strcpy(path, msg->msg.web.web.filepath.path);
res = access(path, F_OK);
if(res < 0)
{
goto RE_READ_FIFO;
}
len_file = rc_file_r_all(path, &buf_file);
if(len_file <= 0)
{
goto RE_READ_FIFO;
}
}
newsnd = rc_create_task_new_w(&con, TYPE_CONNECT_CAM, msg, buf, len);
if(newsnd == NULL)
{
goto RE_READ_FIFO;
}
pthread_mutex_lock(&mutex_w_cam);
res = rc_add_task_w(&task_w_cam, newsnd);
if(action == TYPE_P_W_UPDATE)
{
newsnd = rc_create_task_new_w(&con, TYPE_CONNECT_CAM, NULL, buf_file, len_file);
res = rc_add_task_w(&task_w_cam, newsnd);
}
pthread_mutex_unlock(&mutex_w_cam);
pthread_cond_broadcast(&cond_w_cam);
}
pthread_exit(NULL);
return 0;
}
/*
* 功 能:从文件中读取文件的所有内容
* 参 数:filepath:文件的全路径
* buf:缓冲区地址的指针
* 返回值:成功返回文件长度,否则返回-1
* 说 明:文件是全部读取到缓冲区中的,因此要开的缓冲区要和文件一样大小
*/
int rc_file_r_all(const char *filepath, char **buf)
{
int len;
int len_f;
int len_r;
int res;
FILE *fp;
res = access(filepath, F_OK);
if(res < 0)
{
return -1;
}
len_f = rc_get_file_size(filepath);
if(len_f <= 0)
{
return -1;
}
*buf = malloc(len_f);
if(*buf == NULL)
{
return -1;
}
bzero(*buf, len_f);
fp = fopen(filepath, "rb");
if(fp == NULL)
{
free(*buf);
return -1;
}
len = 0;
while(1)
{
if(len == 0)
len_r = len;
else
len_r = len_f - len;
res = fread(((*buf) + len), 1, len_r, fp);
if(res <= 0)
break;
len += res;
if(len >= len_f)
break;
}
if(len < len_f)
{
free(*buf);
len = -1;
}
fclose(fp);
return len;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -