词条 | msgctl |
释义 | 系统调用msgctl() 下面我们继续讨论如何使用一个给定的消息队列的内部数据结构。我们可以使用系统调用msgctl ( )来控制对消息队列的操作。 系统调用: msgctl( ) ; 调用原型: int msgctl ( int msgqid, int cmd, struct msqid_ds *buf ); 返回值: 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); } }; |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。