Reputation: 171
I've got a task to write a program that lists all active users, and the ammount of processes they have active, when the program receives a SIGHUP signal, and exits, when it gets a SIGINT signal.
I've got this for listing users and process count
ps -u "$(echo $(w -h | cut -d ' ' -f1 | sort -u))" o user= | sort | uniq -c | sort -rn
And this is where i got with my program. I might be going about it the wrong way and could use a bit of help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
void sig_handler(int signo) {
if (signo == SIGHUP){
int pid = 0;
if (pid = fork() != 0) {
execl("/bin/ps", "ps", "-u", "\"$(echo $(w -h | cut -d ' ' -f1 | sort -u))\"", "o", "user=", "|", "sort", "|", "uniq", "-c", "|", "sort", "-rn", NULL);
} else {
printf("Signal received: SIGINT\nReported by: Parent process\n\n");
}
}
}
int main(void) {
if (signal(SIGHUP, sig_handler) == SIG_ERR)
printf("\nCan't catch SIGINT\n");
while (1)
sleep(1);
return 0;
}
Upvotes: 1
Views: 253
Reputation: 409166
You need to read about operator precedence. The line
if (pid = fork() != 0) {
does not do what you think it does!
In fact the compiler sees it as
if (pid = (fork() != 0)) {
This means, among other things, that you run the execl
in the parent process, and not the child which is customary.
As for your problem, it's because you try to run shell-specific things (embedded commands, piping etc.) but you're not actually running a shell.
Either you have to exec
a shell, or use the e.g. the system
function.
Upvotes: 2