Msgctl implements msgctl(2).
(t *kernel.Task, sysno uintptr, args arch.SyscallArguments)
| 122 | |
| 123 | // Msgctl implements msgctl(2). |
| 124 | func Msgctl(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { |
| 125 | id := ipc.ID(args[0].Int()) |
| 126 | cmd := args[1].Int() |
| 127 | buf := args[2].Pointer() |
| 128 | |
| 129 | creds := auth.CredentialsFromContext(t) |
| 130 | |
| 131 | r := t.IPCNamespace().MsgqueueRegistry() |
| 132 | |
| 133 | switch cmd { |
| 134 | case linux.IPC_INFO: |
| 135 | info := r.IPCInfo(t) |
| 136 | _, err := info.CopyOut(t, buf) |
| 137 | return 0, nil, err |
| 138 | case linux.MSG_INFO: |
| 139 | msgInfo := r.MsgInfo(t) |
| 140 | _, err := msgInfo.CopyOut(t, buf) |
| 141 | return 0, nil, err |
| 142 | case linux.IPC_RMID: |
| 143 | return 0, nil, r.Remove(id, creds) |
| 144 | } |
| 145 | |
| 146 | // Remaining commands use a queue. |
| 147 | queue, err := r.FindByID(id) |
| 148 | if err != nil { |
| 149 | return 0, nil, err |
| 150 | } |
| 151 | |
| 152 | switch cmd { |
| 153 | case linux.MSG_STAT: |
| 154 | // Technically, we should be treating id as "an index into the kernel's |
| 155 | // internal array that maintains information about all shared memory |
| 156 | // segments on the system". Since we don't track segments in an array, |
| 157 | // we'll just pretend the msqid is the index and do the same thing as |
| 158 | // IPC_STAT. Linux also uses the index as the msqid. |
| 159 | fallthrough |
| 160 | case linux.IPC_STAT: |
| 161 | stat, err := queue.Stat(t) |
| 162 | if err != nil { |
| 163 | return 0, nil, err |
| 164 | } |
| 165 | _, err = stat.CopyOut(t, buf) |
| 166 | return 0, nil, err |
| 167 | |
| 168 | case linux.MSG_STAT_ANY: |
| 169 | stat, err := queue.StatAny(t) |
| 170 | if err != nil { |
| 171 | return 0, nil, err |
| 172 | } |
| 173 | _, err = stat.CopyOut(t, buf) |
| 174 | return 0, nil, err |
| 175 | |
| 176 | case linux.IPC_SET: |
| 177 | var ds linux.MsqidDS |
| 178 | if _, err := ds.CopyIn(t, buf); err != nil { |
| 179 | return 0, nil, linuxerr.EINVAL |
| 180 | } |
| 181 | err := queue.Set(t, &ds) |
nothing calls this directly
no test coverage detected
searching dependent graphs…