以下是修改后的代码:
```c
#include 
#include 
#include 
#include 
#include 
void show_msg(int msgid);
int main(int argc, char **argv) {
    key_t mkey;
    int msg_id;
    if (argc != 2) {
        fprintf(stderr, "usage: showing keyval \n");
        exit(1);
    }
    mkey = (key_t) atoi(argv[1]);
    if ((msg_id = msgget(mkey, 0)) == -1) {
        perror("msgget failed");
        exit(2);
    }
    show_msg(msg_id);
    exit(0);
}
void show_msg(int msgid) {
    struct msqid_ds buf;
    if (msgctl(msgid, IPC_STAT, &buf) == -1) {
        perror("msgctl");
        exit(EXIT_FAILURE);
    }
    printf("Message queue owner UID: %d\n", buf.msg_perm.uid);
    printf("Message queue owner GID: %d\n", buf.msg_perm.gid);
    printf("Message queue access permissions: %#o\n", buf.msg_perm.mode);
    printf("\n");
    printf("Key: %d\n", buf.msg_perm.__key);
    printf("Number of messages on queue: %ld\n", buf.msg_qnum);
    printf("Maximum number of bytes allowed on queue: %ld\n", buf.msg_qbytes);
    printf("PID of last msgsnd: %d\n", buf.msg_lspid);
    printf("PID of last msgrcv: %d\n", buf.msg_lrpid);
    printf("Time of last msgsnd: %s", ctime(&buf.msg_stime));
    printf("Time of last msgrcv: %s", ctime(&buf.msg_rtime));
    printf("Time of last change: %s", ctime(&buf.msg_ctime));
}
```
在原有的基础上,我们添加了一个新的函数show_msg来打印消息队列的所有者和权限。同时,我们也将mqstat_print函数重命名为show_msg,并对其进行了修改,使其能够打印出更多的消息队列信息。