qfedu-linux-advanced-level/day5/msgque4.c

102 lines
4.0 KiB
C
Raw Normal View History

2023-08-18 16:47:04 +08:00
#include <stdio.h>
#include <sys/types.h> // 系统数据类型定义
#include <sys/ipc.h> // IPC相关头文件
#include <sys/msg.h> // 消息队列相关头文件
#include <string.h> // 字符串操作
#include <stdlib.h> // atol 函数
#include <time.h> // 时间函数
#include <unistd.h> // 头文件含义unix standard即unix标准的意思
// 消息结构体
typedef struct msg_
{
long mType; // 消息类型,必须是 long ,必须在第一个位置
char content[100]; // 消息内容,需要小于消息队列的限制值(8192)
char title[32]; // 消息标题
} MSG;
// msgget 函数用于创建消息队列参数1是键值参数2是权限
int main(int argc, char *argv[])
{
key_t key = ftok("/", 200); // 获取消息队列的键值
int msgqid = msgget(key, IPC_CREAT | 0666); // 创建消息队列
if (msgqid == -1)
{
perror("msgget");
return 1;
}
// 查看 msgqid 消息队列的信息
struct msqid_ds msginfo; // 消息队列信息结构体
int ret = msgctl(msgqid, IPC_STAT, &msginfo); // 获取消息队列信息
if (ret == -1)
{
perror("msgctl");
return 1;
}
time_t st = msginfo.msg_stime; // 最后发送消息的时间
time_t rt = msginfo.msg_rtime; // 最后接收消息的时间
time_t ct = msginfo.msg_ctime; // 最后变更消息的时间
struct tm *stm = localtime(&st); // 转换为北京时间
struct tm *rtm = localtime(&rt); // 转换为北京时间
struct tm *ctm = gmtime(&ct); // 转换为北京时间
// // 手动转换为北京时间
// st += 8 * 60 * 60;
// rt += 8 * 60 * 60;
// ct += 8 * 60 * 60;
// // 把时间戳转换为字符串
// char stime[32] = "";
// char rtime[32] = "";
// char ctime[32] = "";
// ctime_r(&st, stime);
// ctime_r(&rt, rtime);
// ctime_r(&ct, ctime);
// // 打印时间
// printf("最后发送消息的时间: %s", stime);
// printf("最后接收消息的时间: %s", rtime);
// printf("最后变更消息的时间: %s", ctime);
// printf("最后变更消息的时间: %s", ctime);
// + 1900 是因为 struct tm 结构体中的 tm_year 字段表示的是从1900年开始的年数的偏移量。
// +1 是因为 struct tm 结构体中的 tm_mon 字段表示的是月份的偏移量范围是0-11其中0表示一月11表示十二月
printf("最后发送消息的时间: %d-%d-%d %d:%d:%d\n", stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec);
printf("最后接收消息的时间: %d-%d-%d %d:%d:%d\n", rtm->tm_year + 1900, rtm->tm_mon + 1, rtm->tm_mday, rtm->tm_hour, rtm->tm_min, rtm->tm_sec);
printf("最后变更消息的时间: %d-%d-%d %d:%d:%d\n", ctm->tm_year + 1900, ctm->tm_mon + 1, ctm->tm_mday, ctm->tm_hour, ctm->tm_min, ctm->tm_sec);
// 打印消息队列的信息
printf("\n消息队列的信息:\n");
printf("消息队列的标识符: %d\n", msginfo.msg_perm.__key);
printf("消息队列的权限: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出占4位不足4位前面补0
// 修改消息队列的权限
// msginfo.msg_perm.mode = 0644; // 修改权限
msginfo.msg_perm.mode |= 0111; // 修改权限,增加可执行权限
ret = msgctl(msgqid, IPC_SET, &msginfo);
if (ret == -1)
{
perror("msgctl");
return 1;
}
printf("修改消息队列的权限为: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出占4位不足4位前面补0
// execlp("ipcs", "ipcs", "-q", NULL); // 打印消息队列
// 减少权限
msginfo.msg_perm.mode &= ~0101; // 修改权限,减少可执行权限
ret = msgctl(msgqid, IPC_SET, &msginfo);
if (ret == -1)
{
perror("msgctl");
return 1;
}
printf("修改消息队列的权限为: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出占4位不足4位前面补0
execlp("ipcs", "ipcs", "-q", NULL); // 打印消息队列
return 0;
}