logo

utils-std

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

renice.c (3300B)


  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. int c = -1;
  65. while((c = getopt(argc, argv, ":gpun:")) != -1)
  66. {
  67. char *endptr = NULL;
  68. switch(c)
  69. {
  70. case 'g':
  71. which = PRIO_PGRP;
  72. break;
  73. case 'p':
  74. which = PRIO_PROCESS;
  75. break;
  76. case 'u':
  77. which = PRIO_USER;
  78. break;
  79. case 'n':
  80. adj = strtol(optarg, &endptr, 10);
  81. if(endptr && *endptr != 0) errno = EINVAL;
  82. if(errno != 0)
  83. {
  84. fprintf(stderr,
  85. "renice: error: Failed parsing '%s' as a number: %s\n",
  86. optarg,
  87. strerror(errno));
  88. usage();
  89. return 1;
  90. }
  91. if(adj < PRIO_MIN)
  92. {
  93. fprintf(stderr, "renice: error: '-n %ld' is lower than PRIO_MIN(%d)\n", adj, PRIO_MIN);
  94. return 1;
  95. }
  96. if(adj > PRIO_MAX)
  97. {
  98. fprintf(stderr, "renice: error: '-n %ld' is greater than PRIO_MAX(%d)\n", adj, PRIO_MAX);
  99. return 1;
  100. }
  101. if(adj == 0)
  102. {
  103. fprintf(stderr, "renice: error: '-n 0' makes no sense\n");
  104. return 1;
  105. }
  106. break;
  107. case ':':
  108. fprintf(stderr, "renice: error: Missing operand for option: '-%c'\n", optopt);
  109. usage();
  110. return 1;
  111. case '?':
  112. fprintf(stderr, "renice: error: Unrecognised option: '-%c'\n", optopt);
  113. usage();
  114. return 1;
  115. default:
  116. abort();
  117. }
  118. }
  119. argc -= optind;
  120. argv += optind;
  121. if(argc == 0)
  122. {
  123. fprintf(stderr, "renice: error: No IDs passed\n");
  124. usage();
  125. return 1;
  126. }
  127. if(adj == 0)
  128. {
  129. fprintf(stderr, "renice: error: Mandatory option '-n adj' not passed\n");
  130. usage();
  131. return 1;
  132. }
  133. for(int i = 0; i < argc; i++)
  134. {
  135. char *endptr = NULL;
  136. char *arg = argv[i];
  137. long who = strtol(arg, &endptr, 0);
  138. if(endptr && *endptr != 0) errno = EINVAL;
  139. if(errno != 0)
  140. {
  141. fprintf(stderr,
  142. "renice: error: Failed parsing argument '%s' as a number: %s\n",
  143. arg,
  144. strerror(errno));
  145. usage();
  146. return 1;
  147. }
  148. if(renice(which, who, adj) != 0) return 1;
  149. }
  150. return 0;
  151. }