logo

utils-std

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

renice.c (3273B)


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