勇敢心资源网

当前位置:首页 > 百科 / 正文

msgctl

(2020-03-18 21:26:05) 百科

msgctl

msgctl()定义在sys/msg.h中,其函式原型为:int msgctl(int msqid,int cmd,struct msqid_ds *buf),msgctl系统调用对msqid标识的讯息伫列执行cmd操作列。

基本介绍

  • 中文名:msgctl
  • 调用原型:int msgctl
  • 返回值:0 ,如果成功
  • 使用命令:IPC_STAT

系统调用

我们先来说一下,伫列的msqid_ds结构,对于每一个伫列都有一个msqid_ds来描述伫列当前的状态。结构定义如下:
struct msqid_ds {//Linux系统中的定义
struct ipc_perm msg_perm; /* Ownership and permissions
time_t msg_stime; /* Time of last msgsnd() */
time_t msg_rtime; /* Time of last msgrcv() */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes inqueue (non-standard) */
msgqnum_t msg_qnum; /* Current number of messagesin queue */
msglen_t msg_qbytes; /* Maximum number of bytesallowed in queue */
pid_t msg_lspid; /* PID of last msgsnd() */
pid_t msg_lrpid; /* PID of last msgrcv() */
};//不同的系统中此结构会有不同的新成员
下面我们继续讨论如何使用一个给定的讯息伫列的内部数据结构。我们可以使用系统调用msgctl ( )来控制对讯息伫列的操作。

调用原型

int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

头档案:

linux/msg.h

返回值:

0 ,如果成功。
- 1,如果失败:errno = EACCES (没有读的许可权同时cmd 是IPC_STAT )
EFAULT (buf 指向的地址无效)
EIDRM (在读取中伫列被删除)
EINVAL (msgqid无效, 或者msgsz 小于0 )
EPERM (IPC_SET或者IPC_RMID 命令被使用,但调用程式没有写的许可权)

使用命令

IPC_STAT
读取讯息伫列的数据结构msqid_ds,并将其存储在b u f指定的地址中。
IPC_SET
设定讯息伫列的数据结构msqid_ds中的ipc_perm元素的值。这个值取自buf参数。
IPC_RMID
从系统核心中移走讯息伫列。
我们在前面讨论过了讯息伫列的数据结构(msqid_ds)。系统核心中为系统中的每一个讯息伫列保存一个此数据结构的实例。通过使用IPC_STAT命令,我们可以得到一个此数据结构的副本。下面的程式就是实现此函式的过程: int get_queue_ds( int qid, struct msgqid_ds *qbuf )
{
if( msgctl( qid, IPC_STAT, qbuf) == -1)
{
return(-1);
}
return(0);
} 如果不能複製内部缓冲区,调用进程将返回-1。如果调用成功,则返回0。缓冲区中应该包括讯息伫列中的数据结构。
讯息伫列中的数据结构中唯一可以改动的元素就是ipc_perm。它包括伫列的存取许可权和关于伫列创建者和拥有者的信息。你可以改变用户的id、用户的组id以及讯息伫列的存取许可权。
下面是一个修改伫列存取模式的程式: int change_queue_mode(int qid, char *mode )
{
struct msqid_ds tmpbuf;
/* Retrieve a current copy of the internal data structure */
get_queue_ds( qid, &tmpbuf);
/* Change the permissions using an old trick */
sscanf(mode, "%ho", &tmpbuf.msg_perm.mode);
/* Update the internal data structure */
if( msgctl( qid, IPC_SET, &tmpbuf) == -1)
{
return(-1);
}
return(
} 我们通过调用get_queue_ds来读取伫列的内部数据结构。然后,我们调用sscanf( )修改数据结构msg_perm中的mode 成员的值。但直到调用msgctl()时,许可权的改变才真正完成。在这里msgctl()使用的是IPC_SET命令。
最后,我们使用系统调用msgctl ( )中的IPC_RMID命令删除讯息伫列: int remove_queue(int qid )
{
if( msgctl( qid, IPC_RMID, 0) == -1)
{
return(-1);
}
return(0);
}
};
声明:此文信息来源于网络,登载此文只为提供信息参考,并不用于任何商业目的。如有侵权,请及时联系我们:baisebaisebaise@yeah.net
搜索
随机推荐

勇敢心资源网|豫ICP备19027550号