/* Loesung von Jan Siersch */ #include #include #include #include #include #include #include "morse.h" #define DIT '.' #define DAH '-' char* self; volatile int sig = 0; volatile pid_t pid = 0; long xatol(const char *nptr) { char *endPtr; long value = strtol(nptr, &endPtr, 10); if (*endPtr != '\0') { perror("xatol failed"); exit(EXIT_FAILURE); } return value; } void xtransmit(pid_t target, char encoded) { int signal; switch(encoded) { case DIT: signal = SIGUSR1; break; case DAH: signal = SIGUSR2; break; case '\0': signal = SIGTERM; break; default: perror("invalid encoded char"); exit(EXIT_FAILURE); break; } if (kill(target, signal)) { perror("kill failed"); exit(EXIT_FAILURE); } } void helpQuit() { printf("usage: %s TARGET_PID\n", self); exit(EXIT_FAILURE); } void sigAction(int _sig, siginfo_t *info, void *context) { sig = _sig; pid = info->si_pid; } int main(int argc, char *argv[]) { // parse arguments self = *argv++; argc--; if (argc != 1) { helpQuit(); } pid_t target = xatol(*argv); // register action for the necessary signals int signals[] = {SIGINT}; struct sigaction sigAct = {{0}}; sigAct.sa_sigaction = sigAction; sigAct.sa_flags = SA_SIGINFO; for (int i = 0; i < (sizeof(signals) / sizeof(int)); ++i) { sigaction(signals[i], &sigAct, 0); } int letter; while((letter = getchar()) != EOF) { char* encoded = encode((unsigned char) letter); // interpret other characters (newlines etc.) as FULL STOPS if (!encoded) encoded = encode((unsigned char) '.'); for(int i = 0; i < strlen(encoded) + 1; ++i) { // send part of the letter (including the '\0') xtransmit(target, encoded[i]); // wait for confirmation pause(); // sanity check if (pid != target || sig != SIGINT) { perror("who did that?"); exit(EXIT_FAILURE); } } } return EXIT_SUCCESS; }