/* Copyright (c) 2026 The Solidite Developers
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. */
#include <bitset>
#include <iostream>
#include <vector>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <libintl.h>
#include <signal.h>
/* Questionably IEEE Std 1003.1-2024 and XSI conformant
* needs testing */
constexpr char SIGNALS_LIST[] = "SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGALRM"
" SIGTERM\n";
int main(int argc, char* argv[]) {
// locale work
std::locale::global(std::locale(""));
std::cerr.imbue(std::locale());
std::bitset<2> options = 0b00;
// options[0]=skip next arg from being processed
// options[1]=stop processing arguments (-- encountered)
std::vector<std::size_t> pids;
int signal = 15;
for (int i = 1; i < argc; ++i) {
if (options.test(0) == 1) {
options.reset(0);
continue;
} else if (std::strcmp(argv[i], "--") == 0 && options.test(1) == 0) {
options.set(1);
continue;
} else if (options.test(1) == 1) {
pids.push_back(std::atoi(argv[i]));
continue;
}
if (std::strcmp(argv[i], "-l") == 0 && argv[i + 1] == nullptr) {
std::cout << SIGNALS_LIST;
return 0;
} else if (std::strcmp(argv[i], "-l") == 0) {
switch (std::atoi(argv[i + 1])) {
case 0:
std::cout << "0\n";
options.set(0);
break;
case 1:
std::cout << "HUP\n";
options.set(0);
break;
case 2:
std::cout << "INT\n";
options.set(0);
break;
case 3:
std::cout << "QUIT\n";
options.set(0);
break;
case 6:
std::cout << "ABRT\n";
options.set(0);
break;
case 9:
std::cout << "KILL\n";
options.set(0);
break;
case 14:
std::cout << "ALRM\n";
options.set(0);
break;
case 15:
std::cout << "TERM\n";
options.set(0);
break;
default:
std::cerr << "bad signal\n";
options.set(0);
break;
}
} else if (std::strcmp(argv[i], "-s") == 0) {
if (argv[i + 1] == nullptr) {
std::cerr << "signal name required after -s\n";
continue;
}
if (std::strcmp(argv[i + 1], "0") == 0) {
signal = 0;
} else if (std::strcmp(argv[i + 1], "HUP") == 0) {
signal = 1;
} else if (std::strcmp(argv[i + 1], "INT") == 0) {
signal = 2;
} else if (std::strcmp(argv[i + 1], "QUIT") == 0) {
signal = 3;
} else if (std::strcmp(argv[i + 1], "ABRT") == 0) {
signal = 6;
} else if (std::strcmp(argv[i + 1], "KILL") == 0) {
signal = 9;
} else if (std::strcmp(argv[i + 1], "ALRM") == 0) {
signal = 14;
} else if (std::strcmp(argv[i + 1], "TERM") == 0) {
signal = 15;
} else {
std::cerr << "bad signal name\n";
}
options.set(0);
continue;
} else if (std::strcmp(argv[i], "-0") == 0) {
signal = 0;
} else if (std::strcmp(argv[i], "-1") == 0) {
signal = 1;
} else if (std::strcmp(argv[i], "-2") == 0) {
signal = 2;
} else if (std::strcmp(argv[i], "-3") == 0) {
signal = 3;
} else if (std::strcmp(argv[i], "-6") == 0) {
signal = 6;
} else if (std::strcmp(argv[i], "-9") == 0) {
signal = 9;
} else if (std::strcmp(argv[i], "-14") == 0) {
signal = 14;
} else if (std::strcmp(argv[i], "-15") == 0) {
signal = 15;
} else if (std::strcmp(argv[i], "-UP") == 0) {
signal = 1;
} else if (std::strcmp(argv[i], "-INT") == 0) {
signal = 2;
} else if (std::strcmp(argv[i], "-QUIT") == 0) {
signal = 3;
} else if (std::strcmp(argv[i], "-ABRT") == 0) {
signal = 6;
} else if (std::strcmp(argv[i], "-KILL") == 0) {
signal = 9;
} else if (std::strcmp(argv[i], "-ALRM") == 0) {
signal = 14;
} else if (std::strcmp(argv[i], "-TERM") == 0) {
signal = 15;
} else {
pids.push_back(std::atoi(argv[i]));
}
}
for (std::size_t pid : pids) {
kill(pid, signal);
}
return 0;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>