logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/

renice.c (3298B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #define _XOPEN_SOURCE 700 // getpriority, setpriority
  6. #include <errno.h>
  7. #include <stdio.h> // fprintf
  8. #include <stdlib.h> // abort
  9. #include <string.h> // strerror
  10. #include <sys/resource.h> // getpriority, setpriority
  11. #include <unistd.h> // getopt, nice
  12. static int
  13. renice(int which, id_t who, int adj)
  14. {
  15. const char *which_s = NULL;
  16. switch(which)
  17. {
  18. case PRIO_PROCESS:
  19. which_s = "PRIO_PROCESS";
  20. break;
  21. case PRIO_PGRP:
  22. which_s = "PRIO_PGRP";
  23. break;
  24. case PRIO_USER:
  25. which_s = "PRIO_USER";
  26. break;
  27. default:
  28. which_s = NULL;
  29. }
  30. errno = 0;
  31. int prio = getpriority(which, who);
  32. if(errno != 0)
  33. {
  34. fprintf(stderr, "renice: error: getpriority(%s, %d): %s\n", which_s, who, strerror(errno));
  35. return -1;
  36. }
  37. prio += adj;
  38. if(setpriority(which, who, prio) != 0)
  39. {
  40. fprintf(stderr,
  41. "renice: error: setpriority(%s, %d, %d): %s\n",
  42. which_s,
  43. who,
  44. prio,
  45. strerror(errno));
  46. return -1;
  47. }
  48. return 0;
  49. }
  50. static void
  51. usage(void)
  52. {
  53. fprintf(stderr, "\
  54. Usage: renice [-p] -n adj PID...\n\
  55. renice -g -n adj PGID...\n\
  56. renice -u -n adj UID...\n\
  57. ");
  58. }
  59. int
  60. main(int argc, char *argv[])
  61. {
  62. long adj = 0;
  63. int which = PRIO_PROCESS;
  64. for(int c = -1; (c = getopt(argc, argv, ":gpun:")) != -1;)
  65. {
  66. char *endptr = NULL;
  67. switch(c)
  68. {
  69. case 'g':
  70. which = PRIO_PGRP;
  71. break;
  72. case 'p':
  73. which = PRIO_PROCESS;
  74. break;
  75. case 'u':
  76. which = PRIO_USER;
  77. break;
  78. case 'n':
  79. adj = strtol(optarg, &endptr, 10);
  80. if(endptr && *endptr != 0) errno = EINVAL;
  81. if(errno != 0)
  82. {
  83. fprintf(stderr,
  84. "renice: error: Failed parsing '%s' as a number: %s\n",
  85. optarg,
  86. strerror(errno));
  87. usage();
  88. return 1;
  89. }
  90. if(adj < PRIO_MIN)
  91. {
  92. fprintf(stderr, "renice: error: '-n %ld' is lower than PRIO_MIN(%d)\n", adj, PRIO_MIN);
  93. return 1;
  94. }
  95. if(adj > PRIO_MAX)
  96. {
  97. fprintf(stderr, "renice: error: '-n %ld' is greater than PRIO_MAX(%d)\n", adj, PRIO_MAX);
  98. return 1;
  99. }
  100. if(adj == 0)
  101. {
  102. fprintf(stderr, "renice: error: '-n 0' makes no sense\n");
  103. return 1;
  104. }
  105. break;
  106. case ':':
  107. fprintf(stderr, "renice: error: Missing operand for option: '-%c'\n", optopt);
  108. usage();
  109. return 1;
  110. case '?':
  111. fprintf(stderr, "renice: error: Unrecognised option: '-%c'\n", optopt);
  112. usage();
  113. return 1;
  114. default:
  115. abort();
  116. }
  117. }
  118. argc -= optind;
  119. argv += optind;
  120. if(argc == 0)
  121. {
  122. fprintf(stderr, "renice: error: No IDs passed\n");
  123. usage();
  124. return 1;
  125. }
  126. if(adj == 0)
  127. {
  128. fprintf(stderr, "renice: error: Mandatory option '-n adj' not passed\n");
  129. usage();
  130. return 1;
  131. }
  132. for(int i = 0; i < argc; i++)
  133. {
  134. char *endptr = NULL;
  135. char *arg = argv[i];
  136. long who = strtol(arg, &endptr, 0);
  137. if(endptr && *endptr != 0) errno = EINVAL;
  138. if(errno != 0)
  139. {
  140. fprintf(stderr,
  141. "renice: error: Failed parsing argument '%s' as a number: %s\n",
  142. arg,
  143. strerror(errno));
  144. usage();
  145. return 1;
  146. }
  147. if(renice(which, who, adj) != 0) return 1;
  148. }
  149. return 0;
  150. }