| 1 | diff -u -r ../util-linux-2.29.1/sys-utils/ipcutils.c ./sys-utils/ipcutils.c |
| 2 | --- ../util-linux-2.29.1/sys-utils/ipcutils.c 2016-11-02 13:57:31.661167155 +0100 |
| 3 | +++ ./sys-utils/ipcutils.c 2017-02-01 23:01:22.043207759 +0100 |
| 4 | @@ -18,513 +18,56 @@ |
| 5 | |
| 6 | int ipc_msg_get_limits(struct ipc_limits *lim) |
| 7 | { |
| 8 | - if (path_exist(_PATH_PROC_IPC_MSGMNI) && |
| 9 | - path_exist(_PATH_PROC_IPC_MSGMNB) && |
| 10 | - path_exist(_PATH_PROC_IPC_MSGMAX)) { |
| 11 | - |
| 12 | - lim->msgmni = path_read_s32(_PATH_PROC_IPC_MSGMNI); |
| 13 | - lim->msgmnb = path_read_s32(_PATH_PROC_IPC_MSGMNB); |
| 14 | - lim->msgmax = path_read_s32(_PATH_PROC_IPC_MSGMAX); |
| 15 | - } else { |
| 16 | - struct msginfo msginfo; |
| 17 | - |
| 18 | - if (msgctl(0, IPC_INFO, (struct msqid_ds *) &msginfo) < 0) |
| 19 | - return 1; |
| 20 | - lim->msgmni = msginfo.msgmni; |
| 21 | - lim->msgmnb = msginfo.msgmnb; |
| 22 | - lim->msgmax = msginfo.msgmax; |
| 23 | - } |
| 24 | - |
| 25 | - return 0; |
| 26 | + return -1; |
| 27 | } |
| 28 | |
| 29 | int ipc_sem_get_limits(struct ipc_limits *lim) |
| 30 | { |
| 31 | - FILE *f; |
| 32 | - int rc = 0; |
| 33 | - |
| 34 | - lim->semvmx = SEMVMX; |
| 35 | - |
| 36 | - f = path_fopen("r", 0, _PATH_PROC_IPC_SEM); |
| 37 | - if (f) { |
| 38 | - rc = fscanf(f, "%d\t%d\t%d\t%d", |
| 39 | - &lim->semmsl, &lim->semmns, &lim->semopm, &lim->semmni); |
| 40 | - fclose(f); |
| 41 | - |
| 42 | - } |
| 43 | - |
| 44 | - if (rc != 4) { |
| 45 | - struct seminfo seminfo = { .semmni = 0 }; |
| 46 | - union semun arg = { .array = (ushort *) &seminfo }; |
| 47 | - |
| 48 | - if (semctl(0, 0, IPC_INFO, arg) < 0) |
| 49 | - return 1; |
| 50 | - lim->semmni = seminfo.semmni; |
| 51 | - lim->semmsl = seminfo.semmsl; |
| 52 | - lim->semmns = seminfo.semmns; |
| 53 | - lim->semopm = seminfo.semopm; |
| 54 | - } |
| 55 | - |
| 56 | - return 0; |
| 57 | + return -1; |
| 58 | } |
| 59 | |
| 60 | int ipc_shm_get_limits(struct ipc_limits *lim) |
| 61 | { |
| 62 | - lim->shmmin = SHMMIN; |
| 63 | - |
| 64 | - if (path_exist(_PATH_PROC_IPC_SHMALL) && |
| 65 | - path_exist(_PATH_PROC_IPC_SHMMAX) && |
| 66 | - path_exist(_PATH_PROC_IPC_SHMMNI)) { |
| 67 | - |
| 68 | - lim->shmall = path_read_u64(_PATH_PROC_IPC_SHMALL); |
| 69 | - lim->shmmax = path_read_u64(_PATH_PROC_IPC_SHMMAX); |
| 70 | - lim->shmmni = path_read_u64(_PATH_PROC_IPC_SHMMNI); |
| 71 | - |
| 72 | - } else { |
| 73 | - struct shminfo *shminfo; |
| 74 | - struct shmid_ds shmbuf; |
| 75 | - |
| 76 | - if (shmctl(0, IPC_INFO, &shmbuf) < 0) |
| 77 | - return 1; |
| 78 | - shminfo = (struct shminfo *) &shmbuf; |
| 79 | - lim->shmmni = shminfo->shmmni; |
| 80 | - lim->shmall = shminfo->shmall; |
| 81 | - lim->shmmax = shminfo->shmmax; |
| 82 | - } |
| 83 | - |
| 84 | - return 0; |
| 85 | + return -1; |
| 86 | } |
| 87 | |
| 88 | int ipc_shm_get_info(int id, struct shm_data **shmds) |
| 89 | { |
| 90 | - FILE *f; |
| 91 | - int i = 0, maxid; |
| 92 | - char buf[BUFSIZ]; |
| 93 | - struct shm_data *p; |
| 94 | - struct shmid_ds dummy; |
| 95 | - |
| 96 | - p = *shmds = xcalloc(1, sizeof(struct shm_data)); |
| 97 | - p->next = NULL; |
| 98 | - |
| 99 | - f = path_fopen("r", 0, _PATH_PROC_SYSV_SHM); |
| 100 | - if (!f) |
| 101 | - goto shm_fallback; |
| 102 | - |
| 103 | - while (fgetc(f) != '\n'); /* skip header */ |
| 104 | - |
| 105 | - while (fgets(buf, sizeof(buf), f) != NULL) { |
| 106 | - /* scan for the first 14-16 columns (e.g. Linux 2.6.32 has 14) */ |
| 107 | - p->shm_rss = 0xdead; |
| 108 | - p->shm_swp = 0xdead; |
| 109 | - if (sscanf(buf, |
| 110 | - "%d %d %o %"SCNu64 " %u %u " |
| 111 | - "%"SCNu64 " %u %u %u %u %"SCNi64 " %"SCNi64 " %"SCNi64 |
| 112 | - " %"SCNu64 " %"SCNu64 "\n", |
| 113 | - &p->shm_perm.key, |
| 114 | - &p->shm_perm.id, |
| 115 | - &p->shm_perm.mode, |
| 116 | - &p->shm_segsz, |
| 117 | - &p->shm_cprid, |
| 118 | - &p->shm_lprid, |
| 119 | - &p->shm_nattch, |
| 120 | - &p->shm_perm.uid, |
| 121 | - &p->shm_perm.gid, |
| 122 | - &p->shm_perm.cuid, |
| 123 | - &p->shm_perm.cgid, |
| 124 | - &p->shm_atim, |
| 125 | - &p->shm_dtim, |
| 126 | - &p->shm_ctim, |
| 127 | - &p->shm_rss, |
| 128 | - &p->shm_swp) < 14) |
| 129 | - continue; /* invalid line, skipped */ |
| 130 | - |
| 131 | - if (id > -1) { |
| 132 | - /* ID specified */ |
| 133 | - if (id == p->shm_perm.id) { |
| 134 | - i = 1; |
| 135 | - break; |
| 136 | - } else |
| 137 | - continue; |
| 138 | - } |
| 139 | - |
| 140 | - p->next = xcalloc(1, sizeof(struct shm_data)); |
| 141 | - p = p->next; |
| 142 | - p->next = NULL; |
| 143 | - i++; |
| 144 | - } |
| 145 | - |
| 146 | - if (i == 0) |
| 147 | - free(*shmds); |
| 148 | - fclose(f); |
| 149 | - return i; |
| 150 | - |
| 151 | - /* Fallback; /proc or /sys file(s) missing. */ |
| 152 | -shm_fallback: |
| 153 | - maxid = shmctl(0, SHM_INFO, &dummy); |
| 154 | - |
| 155 | - for (int j = 0; j <= maxid; j++) { |
| 156 | - int shmid; |
| 157 | - struct shmid_ds shmseg; |
| 158 | - struct ipc_perm *ipcp = &shmseg.shm_perm; |
| 159 | - |
| 160 | - shmid = shmctl(j, SHM_STAT, &shmseg); |
| 161 | - if (shmid < 0 || (id > -1 && shmid != id)) { |
| 162 | - continue; |
| 163 | - } |
| 164 | - |
| 165 | - i++; |
| 166 | - p->shm_perm.key = ipcp->KEY; |
| 167 | - p->shm_perm.id = shmid; |
| 168 | - p->shm_perm.mode = ipcp->mode; |
| 169 | - p->shm_segsz = shmseg.shm_segsz; |
| 170 | - p->shm_cprid = shmseg.shm_cpid; |
| 171 | - p->shm_lprid = shmseg.shm_lpid; |
| 172 | - p->shm_nattch = shmseg.shm_nattch; |
| 173 | - p->shm_perm.uid = ipcp->uid; |
| 174 | - p->shm_perm.gid = ipcp->gid; |
| 175 | - p->shm_perm.cuid = ipcp->cuid; |
| 176 | - p->shm_perm.cgid = ipcp->cuid; |
| 177 | - p->shm_atim = shmseg.shm_atime; |
| 178 | - p->shm_dtim = shmseg.shm_dtime; |
| 179 | - p->shm_ctim = shmseg.shm_ctime; |
| 180 | - p->shm_rss = 0xdead; |
| 181 | - p->shm_swp = 0xdead; |
| 182 | - |
| 183 | - if (id < 0) { |
| 184 | - p->next = xcalloc(1, sizeof(struct shm_data)); |
| 185 | - p = p->next; |
| 186 | - p->next = NULL; |
| 187 | - } else |
| 188 | - break; |
| 189 | - } |
| 190 | - |
| 191 | - if (i == 0) |
| 192 | - free(*shmds); |
| 193 | - return i; |
| 194 | + return -1; |
| 195 | } |
| 196 | |
| 197 | void ipc_shm_free_info(struct shm_data *shmds) |
| 198 | { |
| 199 | - while (shmds) { |
| 200 | - struct shm_data *next = shmds->next; |
| 201 | - free(shmds); |
| 202 | - shmds = next; |
| 203 | - } |
| 204 | -} |
| 205 | - |
| 206 | -static void get_sem_elements(struct sem_data *p) |
| 207 | -{ |
| 208 | - size_t i; |
| 209 | - |
| 210 | - if (!p || !p->sem_nsems || p->sem_perm.id < 0) |
| 211 | - return; |
| 212 | - |
| 213 | - p->elements = xcalloc(p->sem_nsems, sizeof(struct sem_elem)); |
| 214 | - |
| 215 | - for (i = 0; i < p->sem_nsems; i++) { |
| 216 | - struct sem_elem *e = &p->elements[i]; |
| 217 | - union semun arg = { .val = 0 }; |
| 218 | - |
| 219 | - e->semval = semctl(p->sem_perm.id, i, GETVAL, arg); |
| 220 | - if (e->semval < 0) |
| 221 | - err(EXIT_FAILURE, _("%s failed"), "semctl(GETVAL)"); |
| 222 | - |
| 223 | - e->ncount = semctl(p->sem_perm.id, i, GETNCNT, arg); |
| 224 | - if (e->ncount < 0) |
| 225 | - err(EXIT_FAILURE, _("%s failed"), "semctl(GETNCNT)"); |
| 226 | - |
| 227 | - e->zcount = semctl(p->sem_perm.id, i, GETZCNT, arg); |
| 228 | - if (e->zcount < 0) |
| 229 | - err(EXIT_FAILURE, _("%s failed"), "semctl(GETZCNT)"); |
| 230 | - |
| 231 | - e->pid = semctl(p->sem_perm.id, i, GETPID, arg); |
| 232 | - if (e->pid < 0) |
| 233 | - err(EXIT_FAILURE, _("%s failed"), "semctl(GETPID)"); |
| 234 | - } |
| 235 | + return; |
| 236 | } |
| 237 | |
| 238 | int ipc_sem_get_info(int id, struct sem_data **semds) |
| 239 | { |
| 240 | - FILE *f; |
| 241 | - int i = 0, maxid; |
| 242 | - struct sem_data *p; |
| 243 | - struct seminfo dummy; |
| 244 | - union semun arg; |
| 245 | - |
| 246 | - p = *semds = xcalloc(1, sizeof(struct sem_data)); |
| 247 | - p->next = NULL; |
| 248 | - |
| 249 | - f = path_fopen("r", 0, _PATH_PROC_SYSV_SEM); |
| 250 | - if (!f) |
| 251 | - goto sem_fallback; |
| 252 | - |
| 253 | - while (fgetc(f) != '\n') ; /* skip header */ |
| 254 | - |
| 255 | - while (feof(f) == 0) { |
| 256 | - if (fscanf(f, |
| 257 | - "%d %d %o %" SCNu64 " %u %u %u %u %" |
| 258 | - SCNi64 " %" SCNi64 "\n", |
| 259 | - &p->sem_perm.key, |
| 260 | - &p->sem_perm.id, |
| 261 | - &p->sem_perm.mode, |
| 262 | - &p->sem_nsems, |
| 263 | - &p->sem_perm.uid, |
| 264 | - &p->sem_perm.gid, |
| 265 | - &p->sem_perm.cuid, |
| 266 | - &p->sem_perm.cgid, |
| 267 | - &p->sem_otime, |
| 268 | - &p->sem_ctime) != 10) |
| 269 | - continue; |
| 270 | - |
| 271 | - if (id > -1) { |
| 272 | - /* ID specified */ |
| 273 | - if (id == p->sem_perm.id) { |
| 274 | - get_sem_elements(p); |
| 275 | - i = 1; |
| 276 | - break; |
| 277 | - } else |
| 278 | - continue; |
| 279 | - } |
| 280 | - |
| 281 | - p->next = xcalloc(1, sizeof(struct sem_data)); |
| 282 | - p = p->next; |
| 283 | - p->next = NULL; |
| 284 | - i++; |
| 285 | - } |
| 286 | - |
| 287 | - if (i == 0) |
| 288 | - free(*semds); |
| 289 | - fclose(f); |
| 290 | - return i; |
| 291 | - |
| 292 | - /* Fallback; /proc or /sys file(s) missing. */ |
| 293 | -sem_fallback: |
| 294 | - arg.array = (ushort *) (void *)&dummy; |
| 295 | - maxid = semctl(0, 0, SEM_INFO, arg); |
| 296 | - |
| 297 | - for (int j = 0; j <= maxid; j++) { |
| 298 | - int semid; |
| 299 | - struct semid_ds semseg; |
| 300 | - struct ipc_perm *ipcp = &semseg.sem_perm; |
| 301 | - arg.buf = (struct semid_ds *)&semseg; |
| 302 | - |
| 303 | - semid = semctl(j, 0, SEM_STAT, arg); |
| 304 | - if (semid < 0 || (id > -1 && semid != id)) { |
| 305 | - continue; |
| 306 | - } |
| 307 | - |
| 308 | - i++; |
| 309 | - p->sem_perm.key = ipcp->KEY; |
| 310 | - p->sem_perm.id = semid; |
| 311 | - p->sem_perm.mode = ipcp->mode; |
| 312 | - p->sem_nsems = semseg.sem_nsems; |
| 313 | - p->sem_perm.uid = ipcp->uid; |
| 314 | - p->sem_perm.gid = ipcp->gid; |
| 315 | - p->sem_perm.cuid = ipcp->cuid; |
| 316 | - p->sem_perm.cgid = ipcp->cuid; |
| 317 | - p->sem_otime = semseg.sem_otime; |
| 318 | - p->sem_ctime = semseg.sem_ctime; |
| 319 | - |
| 320 | - if (id < 0) { |
| 321 | - p->next = xcalloc(1, sizeof(struct sem_data)); |
| 322 | - p = p->next; |
| 323 | - p->next = NULL; |
| 324 | - i++; |
| 325 | - } else { |
| 326 | - get_sem_elements(p); |
| 327 | - break; |
| 328 | - } |
| 329 | - } |
| 330 | - |
| 331 | - if (i == 0) |
| 332 | - free(*semds); |
| 333 | - return i; |
| 334 | + return -1; |
| 335 | } |
| 336 | |
| 337 | void ipc_sem_free_info(struct sem_data *semds) |
| 338 | { |
| 339 | - while (semds) { |
| 340 | - struct sem_data *next = semds->next; |
| 341 | - free(semds->elements); |
| 342 | - free(semds); |
| 343 | - semds = next; |
| 344 | - } |
| 345 | + return; |
| 346 | } |
| 347 | |
| 348 | int ipc_msg_get_info(int id, struct msg_data **msgds) |
| 349 | { |
| 350 | - FILE *f; |
| 351 | - int i = 0, maxid; |
| 352 | - struct msg_data *p; |
| 353 | - struct msqid_ds dummy; |
| 354 | - struct msqid_ds msgseg; |
| 355 | - |
| 356 | - p = *msgds = xcalloc(1, sizeof(struct msg_data)); |
| 357 | - p->next = NULL; |
| 358 | - |
| 359 | - f = path_fopen("r", 0, _PATH_PROC_SYSV_MSG); |
| 360 | - if (!f) |
| 361 | - goto msg_fallback; |
| 362 | - |
| 363 | - while (fgetc(f) != '\n') ; /* skip header */ |
| 364 | - |
| 365 | - while (feof(f) == 0) { |
| 366 | - if (fscanf(f, |
| 367 | - "%d %d %o %" SCNu64 " %" SCNu64 |
| 368 | - " %u %u %u %u %u %u %" SCNi64 " %" SCNi64 " %" SCNi64 "\n", |
| 369 | - &p->msg_perm.key, |
| 370 | - &p->msg_perm.id, |
| 371 | - &p->msg_perm.mode, |
| 372 | - &p->q_cbytes, |
| 373 | - &p->q_qnum, |
| 374 | - &p->q_lspid, |
| 375 | - &p->q_lrpid, |
| 376 | - &p->msg_perm.uid, |
| 377 | - &p->msg_perm.gid, |
| 378 | - &p->msg_perm.cuid, |
| 379 | - &p->msg_perm.cgid, |
| 380 | - &p->q_stime, |
| 381 | - &p->q_rtime, |
| 382 | - &p->q_ctime) != 14) |
| 383 | - continue; |
| 384 | - |
| 385 | - if (id > -1) { |
| 386 | - /* ID specified */ |
| 387 | - if (id == p->msg_perm.id) { |
| 388 | - if (msgctl(id, IPC_STAT, &msgseg) != -1) |
| 389 | - p->q_qbytes = msgseg.msg_qbytes; |
| 390 | - i = 1; |
| 391 | - break; |
| 392 | - } else |
| 393 | - continue; |
| 394 | - } |
| 395 | - |
| 396 | - p->next = xcalloc(1, sizeof(struct msg_data)); |
| 397 | - p = p->next; |
| 398 | - p->next = NULL; |
| 399 | - i++; |
| 400 | - } |
| 401 | - |
| 402 | - if (i == 0) |
| 403 | - free(*msgds); |
| 404 | - fclose(f); |
| 405 | - return i; |
| 406 | - |
| 407 | - /* Fallback; /proc or /sys file(s) missing. */ |
| 408 | -msg_fallback: |
| 409 | - maxid = msgctl(0, MSG_INFO, &dummy); |
| 410 | - |
| 411 | - for (int j = 0; j <= maxid; j++) { |
| 412 | - int msgid; |
| 413 | - struct ipc_perm *ipcp = &msgseg.msg_perm; |
| 414 | - |
| 415 | - msgid = msgctl(j, MSG_STAT, &msgseg); |
| 416 | - if (msgid < 0 || (id > -1 && msgid != id)) { |
| 417 | - continue; |
| 418 | - } |
| 419 | - |
| 420 | - i++; |
| 421 | - p->msg_perm.key = ipcp->KEY; |
| 422 | - p->msg_perm.id = msgid; |
| 423 | - p->msg_perm.mode = ipcp->mode; |
| 424 | - p->q_cbytes = msgseg.msg_cbytes; |
| 425 | - p->q_qnum = msgseg.msg_qnum; |
| 426 | - p->q_lspid = msgseg.msg_lspid; |
| 427 | - p->q_lrpid = msgseg.msg_lrpid; |
| 428 | - p->msg_perm.uid = ipcp->uid; |
| 429 | - p->msg_perm.gid = ipcp->gid; |
| 430 | - p->msg_perm.cuid = ipcp->cuid; |
| 431 | - p->msg_perm.cgid = ipcp->cgid; |
| 432 | - p->q_stime = msgseg.msg_stime; |
| 433 | - p->q_rtime = msgseg.msg_rtime; |
| 434 | - p->q_ctime = msgseg.msg_ctime; |
| 435 | - p->q_qbytes = msgseg.msg_qbytes; |
| 436 | - |
| 437 | - if (id < 0) { |
| 438 | - p->next = xcalloc(1, sizeof(struct msg_data)); |
| 439 | - p = p->next; |
| 440 | - p->next = NULL; |
| 441 | - } else |
| 442 | - break; |
| 443 | - } |
| 444 | - |
| 445 | - if (i == 0) |
| 446 | - free(*msgds); |
| 447 | - return i; |
| 448 | + return -1; |
| 449 | } |
| 450 | |
| 451 | void ipc_msg_free_info(struct msg_data *msgds) |
| 452 | { |
| 453 | - while (msgds) { |
| 454 | - struct msg_data *next = msgds->next; |
| 455 | - free(msgds); |
| 456 | - msgds = next; |
| 457 | - } |
| 458 | + return; |
| 459 | } |
| 460 | |
| 461 | void ipc_print_perms(FILE *f, struct ipc_stat *is) |
| 462 | { |
| 463 | - struct passwd *pw; |
| 464 | - struct group *gr; |
| 465 | - |
| 466 | - fprintf(f, "%-10d %-10o", is->id, is->mode & 0777); |
| 467 | - |
| 468 | - if ((pw = getpwuid(is->cuid))) |
| 469 | - fprintf(f, " %-10s", pw->pw_name); |
| 470 | - else |
| 471 | - fprintf(f, " %-10u", is->cuid); |
| 472 | - |
| 473 | - if ((gr = getgrgid(is->cgid))) |
| 474 | - fprintf(f, " %-10s", gr->gr_name); |
| 475 | - else |
| 476 | - fprintf(f, " %-10u", is->cgid); |
| 477 | - |
| 478 | - if ((pw = getpwuid(is->uid))) |
| 479 | - fprintf(f, " %-10s", pw->pw_name); |
| 480 | - else |
| 481 | - fprintf(f, " %-10u", is->uid); |
| 482 | - |
| 483 | - if ((gr = getgrgid(is->gid))) |
| 484 | - fprintf(f, " %-10s\n", gr->gr_name); |
| 485 | - else |
| 486 | - fprintf(f, " %-10u\n", is->gid); |
| 487 | + return; |
| 488 | } |
| 489 | |
| 490 | void ipc_print_size(int unit, char *msg, uint64_t size, const char *end, |
| 491 | int width) |
| 492 | { |
| 493 | - char format[32]; |
| 494 | - |
| 495 | - if (!msg) |
| 496 | - /* NULL */ ; |
| 497 | - else if (msg[strlen(msg) - 1] == '=') |
| 498 | - printf("%s", msg); |
| 499 | - else if (unit == IPC_UNIT_BYTES) |
| 500 | - printf(_("%s (bytes) = "), msg); |
| 501 | - else if (unit == IPC_UNIT_KB) |
| 502 | - printf(_("%s (kbytes) = "), msg); |
| 503 | - else |
| 504 | - printf("%s = ", msg); |
| 505 | - |
| 506 | - switch (unit) { |
| 507 | - case IPC_UNIT_DEFAULT: |
| 508 | - case IPC_UNIT_BYTES: |
| 509 | - sprintf(format, "%%%dju", width); |
| 510 | - printf(format, size); |
| 511 | - break; |
| 512 | - case IPC_UNIT_KB: |
| 513 | - sprintf(format, "%%%dju", width); |
| 514 | - printf(format, size / 1024); |
| 515 | - break; |
| 516 | - case IPC_UNIT_HUMAN: |
| 517 | - sprintf(format, "%%%ds", width); |
| 518 | - printf(format, size_to_human_string(SIZE_SUFFIX_1LETTER, size)); |
| 519 | - break; |
| 520 | - default: |
| 521 | - /* impossible occurred */ |
| 522 | - abort(); |
| 523 | - } |
| 524 | - |
| 525 | - if (end) |
| 526 | - printf("%s", end); |
| 527 | + return; |
| 528 | } |