#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include<signal.h>
#include<unistd.h>//getch();
#include <termios.h>//getch();
#include <pthread.h>
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
volatile sig_atomic_t flag = 0;
int value = 0;
int count = 0;
char getch()
{
int buf = 0;
struct termios old = { 0 };
fflush(stdout);
if (tcgetattr(0, &old) < 0)
perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSANOW, &old) < 0)
perror("tcsetattr ICANON");
if (read(0, &buf, 1) < 0)
perror("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if (tcsetattr(0, TCSADRAIN, &old) < 0)
perror("tcsetattr ~ICANON");
return buf;
}
void *send_function(void *parg)
{
printf("\n Send Thread ");
count++;
return parg;
}
void *receive_function(void *parg)
{
printf("\n Receive Thread ");
count++;
return parg;
}
void my_function(int sig)
{
flag = 1; // set flag
}
int main()
{
char selection; //user input(s or r)
pthread_t send;
pthread_t receive;
while (1)
{
signal(SIGINT, my_function);
if (flag)
{
printf("\n Choose your terminal S or R \n");
selection = getch();
flag = 0;
}
if (selection == 's')
{
if (pthread_create(&send, NULL, send_function, NULL))
{
printf("Error creating thread=%d\n", count);
return 1;
}
}
else if (selection == 'r')
{
if (pthread_create(&receive, NULL, receive_function, NULL))
{
printf("Error creating thread=%d\n", count);
return 1;
}
}
printf("\n MAIN LOOP\n");
//sleep(1);
}
return 0;
//pthread_exit(NULL);
}
Output1 :
MAIN LOOP
Receive Thread
MAIN LOOP
Receive Thread
MAIN LOOP
Receive Thread
MAIN LOOP
Receive Thread
Receive Thread
Receive Thread
Receive Thread Error creating thread=380
nivas#balakrishnan-HCL-Desktop:~/C_sample$
output2:
MAIN LOOP
MAIN LOOP
MAIN LOOP
Send Thread
Send Thread
Send Thread
Send Thread
Send Thread
MAIN LOOP
Error creating thread=379
In the above code. the code should run infinitely when I press 's' or 'r' it should print "send thread" or "receive thread" accordingly for infinite number of times whereas in this code approx 380 times only the while loop is running.I don't know why it is happening.I have used variable count for debugging purpose,can anyone help?
You need to either detach your threads or join them. Otherwise, you will run out of resources.
Related
The following program checks if a signal is pending. I use the sigpending function to return blocked (or waiting) signals. The problem is that I don't want this, I would like to display all the blocked and pending signals at some point, how can I do that? What should I change?
code:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void catcher(int signum) {
puts("inside catcher!");
if (signum != 0)
perror("signum error");
}
void check_pending(int signum, char * signame) {
sigset_t sigset;
if (sigpending( & sigset) != 0)
perror("sigpending() error");
else if (sigismember( & sigset, signum))
printf("a %s signal is pending\n", signame);
else
printf("no %s signals are pending\n", signame);
}
int main() {
struct sigaction sigact;
sigset_t sigset;
sigemptyset( & sigact.sa_mask);
sigact.sa_flags = 0;
sigact.sa_handler = catcher;
if (sigaction(SIGUSR1, & sigact, NULL) != 0)
perror("sigaction() error");
else {
sigemptyset( & sigset);
sigaddset( & sigset, SIGUSR1);
if (sigprocmask(SIG_SETMASK, & sigset, NULL) != 0)
perror("sigprocmask() error");
else {
puts("SIGUSR1 signals are now blocked");
kill(getpid(), SIGUSR1);
printf("after kill: ");
check_pending(SIGUSR1, "SIGUSR1");
sigemptyset( & sigset);
sigprocmask(SIG_SETMASK, & sigset, NULL);
puts("SIGUSR1 signals are no longer blocked");
check_pending(SIGUSR1, "SIGUSR1");
}
}
}
Use sigignore to dispose the signal. Program below will check pending signals in 1s intervals and display theirs numbers. Terminate with sending SIGTERM.
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int i;
sigset_t sigset;
printf("my pid is %d\n", getpid());
sigfillset(&sigset);
sigprocmask(SIG_SETMASK, &sigset, NULL);
while (1) {
sigpending(&sigset);
for (i = 1; i < 32; ++i) {
if (sigismember(&sigset, i)) {
printf("signal %d pending\n", i);
sigignore(i);
if (i == SIGTERM) {
exit(0);
}
}
}
sleep(1);
}
return 0;
}
I am trying to understand the concept of counting semaphore through an example. But I want to implement this using SysV in Linux.
I am familiar with theoretical part of binary semaphore and counting semaphore.
I have referred this link.
Conceptually, semaphores are used as a signaling mechanism from one process to another, so I was trying to write a simple program.
In the below program, I want thread_1 to wait till it doesn't get a signal from thread_2 and similarly thread_2 should wait till it doesn't get a signal from thread_3.
So that the output should be something like this:
Hello From thread 3
Hello from thread 2
Hello from thread 1
I know it can be achieved using pthread_join() properly but I want to achieve it using semaphores.
Code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
int sem_id;
struct sembuf sops[3];
void thread_1(void)
{
sops[0].sem_num = 0;
sops[0].sem_op = 0;
sops[0].sem_flg = 0;
if(semop(sem_id, sops, 1) < 0)
perror("Semop In thread 3");
else
printf("Hello From thread 1\n");
}
void thread_2(void)
{
sops[0].sem_num = 0;
sops[0].sem_op = -1;
sops[0].sem_flg = 0;
if(semop(sem_id, sops, 1) < 0)
perror("Semop In thread 2");
else
printf("Hello from thread 2\n");
}
void thread_3(void)
{
sops[0].sem_num = 0;
sops[0].sem_op = -1;
sops[0].sem_flg = 0;
if(semop(sem_id, sops, 1) < 0)
perror("Semop In thread 3");
else
printf("Hello from thread 3\n");
}
int main(void)
{
void (*funct[]) = {thread_1, thread_2, thread_3};
key_t semkey;
char i;
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
}arg;
pthread_t thread_id[3];
semkey = ftok("/tmp", 'a');
if(semkey < 0)
perror("Cannot Create Semaphore Key");
else
{
sem_id = semget(semkey, 1, (IPC_CREAT|IPC_EXCL|0666));
if(sem_id < 0)
perror("Cannot create semaphore\n");
else
{
arg.val = 3;
if (semctl(sem_id, 0, SETVAL, arg) == -1) {
perror("semctl");
exit(1);
}
}
}
for(i = 0; i < 3; i++)
{
if(pthread_create(&thread_id[i], NULL, funct[i], NULL) < 0)
perror("Cannot Create thread\n");
}
for(i = 0; i < 3; i++)
pthread_join(thread_id[i], NULL);
if(semctl(sem_id, 0, IPC_RMID, NULL) == -1)
perror("semctl");
return 0;
}
Do I have to use more than one semaphore set to achieve what I am trying to do?
You need two mutexes / semaphores with count 1.
Assuming your threads are called t0,t1,t2 and your semaphores sem0 and sem1, then t0 runs freely and increments sem0, t1 waits on sem0 and increments sem1, and t2 waits on sem1.
Here's a complete draft without error checking:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
static int sem0, sem1;
#define POST1(Sem) semop(Sem, &(struct sembuf){0,1,0}, 1)
#define WAIT1(Sem) semop(Sem, &(struct sembuf){0,-1,0}, 1)
static void* t0(void *unused) { puts("hello from t0"); POST1(sem0); return 0; }
static void* t1(void *unused) { WAIT1(sem0); puts("hello from t1"); POST1(sem1); return 0; }
static void* t2(void *unused) { WAIT1(sem1); puts("hello from t2"); return 0; }
int main(void)
{
key_t sem0_k, sem1_k;
sem0_k = ftok("/tmp", '0');
sem1_k = ftok("/tmp", '1');
sem0 = semget(sem0_k, 1, (IPC_CREAT|IPC_EXCL|0666));
sem1 = semget(sem1_k, 1, (IPC_CREAT|IPC_EXCL|0666));
pthread_t tids[3];
pthread_create(tids+2, NULL, t2, NULL);
sleep(1);
pthread_create(tids+1, NULL, t1, NULL);
sleep(1);
pthread_create(tids+0, NULL, t0, NULL);
for(int i = 0; i < 3; i++)
pthread_join(tids[i], NULL);
semctl(sem0, 0, IPC_RMID, NULL);
semctl(sem1, 0, IPC_RMID, NULL);
return 0;
}
I'm running the threads in reverse order and with 1 second waits in between t0 and t1, and t1 and t2 to show the semaphores do the job of ordering the threads from t0 to t2.
#PSkocik, based on your answer, I modified my code to use a set of two semaphores. Here is the code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
int sem_id;
struct sembuf sops;
void thread_1(void)
{
/*Wait on Set1 of Semaphore*/
sops.sem_num = 1;
sops.sem_op = -1;
sops.sem_flg = 0;
if(semop(sem_id, &sops, 1) < 0)
perror("Semop Wait In thread 3");
else
printf("Hello From thread 1\n");
}
void thread_2(void)
{
/*Wait on Set0 of Semaphore*/
sops.sem_num = 0;
sops.sem_op = -1;
sops.sem_flg = 0;
if(semop(sem_id, &sops, 1) < 0)
perror("Semop Wait In thread 2");
else
printf("Hello from thread 2\n");
/*Post on Set1 of Semaphore*/
sops.sem_num = 1;
sops.sem_op = 1;
sops.sem_flg = 0;
if(semop(sem_id, &sops, 1) < 0)
perror("Semop Post In thread 2");
}
void thread_3(void)
{
printf("Hello from thread 3\n");
/*Post operation on Set0 of semaphore*/
sops.sem_num = 0;
sops.sem_op = 1;
sops.sem_flg = 0;
if(semop(sem_id, &sops, 1) < 0)
perror("Semop In thread 3");
else
{ ; }
}
int main(void)
{
void (*funct[]) = {thread_1, thread_2, thread_3};
key_t semkey;
char i;
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
}arg;
pthread_t thread_id[3];
semkey = ftok("/tmp", 'a');
if(semkey < 0)
perror("Cannot Create Semaphore Key");
else
{
sem_id = semget(semkey, 2, (IPC_CREAT|IPC_EXCL|0666));
if(sem_id < 0)
perror("Cannot create semaphore\n");
else
{
/*arg.val = 3;
if (semctl(sem_id, 0, SETVAL, arg) == -1) {
perror("semctl");
exit(1);
}*/
}
}
for(i = 0; i < 3; i++)
{
if(pthread_create(&thread_id[i], NULL, funct[i], NULL) < 0)
perror("Cannot Create thread\n");
}
for(i = 0; i < 3; i++)
pthread_join(thread_id[i], NULL);
if(semctl(sem_id, 0, IPC_RMID, NULL) == -1)
perror("semctl");
return 0;
}
BTW, thanks a bunch for your explanation.
I'm implementing a solution to a problem that uses shared memory, but somehow, my code seems to "freeze" between a print statement and an if statement.
Here's the relevant code snippet:
#include "ch_problem_headers.h"
int main(int argc, char *argv[])
{
int semid, shmid;
int i;
int waiting_C, waiting_H = 0; // shared
int c_pid,h_pid;
time_t t;
// There should be three semaphores: S for when to pass the molecule on,
// SC for the carbon waiting, and SH for the hydrogen waitin
unsigned short seminit[NUM_SEMS];
struct common *shared;
union semun semctlarg;
srand((unsigned)time(&t));
if((semid = semget(IPC_PRIVATE, NUM_SEMS, IPC_CREAT|0777)) < 0)
{
perror("semget");
exit(EXIT_FAILURE);
}
// Initialize semaphores
seminit[S_SEM] = 1;
seminit[SC_SEM] = 0;
seminit[SH_SEM] = 0;
semctlarg.array = seminit;
// Apply initialization
if((semctl(semid, NUM_SEMS, SETALL, semctlarg)) < 0)
{
perror("semctl");
exit(EXIT_FAILURE);
}
// Get shared memory id
if((shmid = shmget(IPC_PRIVATE, 1*K, IPC_CREAT|IPC_EXCL|0660)) < 0)
{
perror("shmget");
exit(EXIT_FAILURE);
}
// Retrieve pointer to shared data structure
if((shared = (struct common *)shmat(shmid, 0, 0)) < 0)
{
perror("shmat");
exit(EXIT_FAILURE);
}
shared->waiting_C = 0;
shared->waiting_H = 0;
printf("ready to fork\n");
// fork process C
c_pid = fork();
printf("c_pid is %d\n", c_pid);
if(c_pid == 0)
{
printf("I'm process C!/n");
// wait on S
semWait(semid, S_SEM);
// if waiting_H >= 4
if(shared->waiting_H >= 4)
{
// signal SH four times
for(i = 0; i < 4; i++)
{
semSignal(semid, SH_SEM);
printf("H");
}
// Decrement waiting_H by 4
shared->waiting_H -= 4;
// Signal S
semSignal(semid, S_SEM);
}
// Otherwise, increment waiting_C by 1
else
{
shared->waiting_C += 1;
// Signal S and wait for SC
semSignal(semid, S_SEM);
semWait(semid, SC_SEM);
}
}
else
{
printf("C's process id is %d\n", c_pid);
printf("ready to fork again\n");
// fork process H
h_pid = fork();
printf("Is h_pid zero? %d\n", (h_pid == 0));
if(h_pid == 0)
{
printf("I'm process H!/n");
// Wait on S
semWait(semid, S_SEM);
// If waiting_h >= 3
if(shared->waiting_H >= 3)
{
// Signal SH three times, decrement waiting_H by 3, signal SC, decrement
for(i = 0; i < 3; i++)
{
printf("H");
semSignal(semid, SH_SEM);
}
shared->waiting_H -=3;
semSignal(semid, SC_SEM);
shared->waiting_C -= 1;
semSignal(semid, S_SEM);
// waitng_C by 1, and signal S
}
// Otherwise, increment waiting_H by 1, signal S, and wait on SH
else
{
shared->waiting_H += 1;
semSignal(semid, S_SEM);
semWait(semid, SH_SEM);
}
}
else
{
printf("In the parent\n");
}
}
}
And the relevant header file:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#define K 1024
#define NUM_SEMS 3
#define SEMKEY 77
#define SHMKEY 77
#define S_SEM 0
#define SH_SEM 1
#define SC_SEM 2
#define NUM_H 4
#define NUM_C 1
union semun
{
unsigned short *array;
};
struct common
{
int waiting_C;
int waiting_H;
};
void semWait(int semid, int semaphore)
{
struct sembuf psembuf;
psembuf.sem_op = -1;
psembuf.sem_flg = 0;
psembuf.sem_num = semaphore;
semop(semid, &psembuf, 1);
return;
}
void semSignal(int semid, int semaphore)
{
struct sembuf vsembuf;
vsembuf.sem_op = 1;
vsembuf.sem_flg = 0;
vsembuf.sem_num = semaphore;
semop(semid, &vsembuf, 1);
return;
}
The program output when run is as follows:
Parent output (correct) :
ready to fork
c_pid is 2977
C's process ID is 2977
ready to fork again
Is h_pid zero? 0
In the parent
Child output:
Is h_pid zero? 1
c_pid is 0
I tried running the program in valgrind, and the program simply halted after the child output. I'm confused as to how this is possible, as the program seems to simply stop between the c_pid print statement and the if(c_pid == 0) statement.
Does anyone have any idea why this might be? Thanks so much.
I'm trying to create a game in C under linux terminal.
I need to create a tetris game that consists of two c files,
One C file create execute file (a.out) and the other create (draw.out).
The first program create a child process and execute the other.
I need to send signals to the other program, but I found it difficult.
The source code is:
the first file-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <termios.h>
#include <signal.h>
char getch();
int main()
{
int fd[2],pid;
char *args[] = { "./draw.out", NULL },tav;
pipe(fd);
pid=fork();
if(pid==0)
{
execve("draw.out", args, NULL);
}
else
{
while(true)
kill(0,SIGUSR2);
}
return 1;
//getchar();
}
char getch() {
char buf = 0;
struct termios old = {0};
if (tcgetattr(0, &old) < 0)
perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSANOW, &old) < 0)
perror("tcsetattr ICANON");
if (read(0, &buf, 1) < 0)
perror ("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if (tcsetattr(0, TCSADRAIN, &old) < 0)
perror ("tcsetattr ~ICANON");
return (buf);
}
the second file-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <signal.h>
typedef struct
{
int x;
int y;
}Point;
typedef struct
{
Point dots[3];
}Tool;
void drawBoard(int array[][20]);
void initBoard(int array[][20]);
Tool retrieveTool();
bool changeLocation(int array[][20],Tool* tool);
void my_handler(int signum);
int main()
{
bool nextTool=true;
Tool temp=retrieveTool();
int gameBoard[20][20];
signal(SIGUSR2, my_handler);
initBoard(gameBoard);
changeLocation(gameBoard,&temp);
drawBoard(gameBoard);
while(true)
{
signal(SIGUSR2, my_handler);
sleep(1);
system("clear");
if(!changeLocation(gameBoard,&temp))
temp=retrieveTool();
drawBoard(gameBoard);
}
return 1;
//getchar();
}
void initBoard(int array[][20])
{
bool isLast=false;
int i=0,j=0;
for(i=0;i<20;i++)
{
if(i==19)
isLast=true;
for(j=0;j<20;j++)
{
if((j==0)||(j==19)||(isLast))
array[i][j]=1;
else
array[i][j]=0;
}
}
}
void drawBoard(int symbols[][20])
{
int i=0,j=0;
for(i=0;i<20;i++)
{
for(j=0;j<20;j++)
if(symbols[i][j]==1)
printf("*");
else
if(symbols[i][j]==2)
printf("-");
else
printf(" ");
printf("\n");
}
}
Tool retrieveTool()
{
Tool temp;
int startX=0,startY=8,i=0;
for(i=0;i<3;i++)
{
temp.dots[i].x=startX;
temp.dots[i].y=startY;
startY++;
}
return temp;
}
bool changeLocation(int array[][20],Tool* tool)
{
int i=0;
for(i=0;i<3;i++)
{
if(array[tool->dots[i].x+1][tool->dots[i].y]!=0)
return false;
}
i=0;
for(i=0;i<3;i++)
{
array[tool->dots[i].x][tool->dots[i].y]=0;
if((tool->dots[i].x+1)==19)
tool->dots[i].x=-1;
tool->dots[i].x++;
array[tool->dots[i].x][tool->dots[i].y]=2;
}
return true;
}
void my_handler(int signum)
{
if (signum == SIGUSR2)
{
printf("Received SIGUSR1!\n");
}
}
The draw.out is the output file of the second file.
i created the signal handeler in the second file,
But the program still don't recieve the signal, what am i doing wrong?
This fragment:
while(true) kill(0,SIGUSR2);
has no sense. The kill should be used with the process id of the reveiver of SIGUSR2 (the child process in this case, identified by pid). Also note that an infinite loop sending signals to the child process is not what you want.
In the child process, you have an error in the print statement at signal handler:
printf("Received SIGUSR1!\n");
should be
printf("Received SIGUSR2!\n");
Depending on the OS version, you have to reinstall the signal handler once it gets called
Note: you are synchronizing processes, not threads
I have a problem running the below code , which invokes getutent() to count the total number of users currently logged in to the system. The timer will be invoked every 1sec and will set the boolean named "isSigAlrmOccured" to true and exit.The main function checks whether the timer signal is delivered by checking this boolen and monitor the number of loggedin users. Unfortunately, the timer signal is delivered to the main program only two times correctly and I don't get any further signals after that. The pause function call doesn't get interrupted after the first two signals.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <utmp.h>
#include <errno.h>
static int isSigAlrmOccured;
void alarm_handler (int signo)
{
static int i=1;
printf("\n Signal Occurred %d times\n",i++);
isSigAlrmOccured = 1;
}
int main (int argc, char *argv[]) {
struct itimerval delay;
struct utmp *utmpstruct;
int numuser;
int ret;
signal (SIGALRM, alarm_handler);
delay.it_value.tv_sec = 1;
delay.it_value.tv_usec = 0;
delay.it_interval.tv_sec = 1;
delay.it_interval.tv_usec = 0;
ret = setitimer (ITIMER_REAL, &delay, NULL);
if (ret) {
perror ("setitimer");
return 0;
}
for (;;) {
pause ( );
/* count the number of users */
if ( (errno == EINTR) && (isSigAlrmOccured) ) {
isSigAlrmOccured = 0;
setutent();
while ((utmpstruct = getutent())) {
if ((utmpstruct->ut_type == USER_PROCESS) &&
(utmpstruct->ut_name[0] != '\0'))
numuser++;
}
endutent();
}
}
return 0;
}
Output:
Signal Occurred 1 times
Signal Occurred 2 times
The implementation of *utent() is using alarm() and is reseting your alarm.
You'll have to do something else.
strace ttest ( some lines removed for brevity )
[...]
pause()
--- SIGALRM (Alarm clock) # 0 (0) ---
write(1, " Signal Occurred 1 times\n", 25 Signal Occurred 1 times) = 25
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 3
alarm(0) = 5
rt_sigaction(SIGALRM, {0x7f52580a91c0, [], SA_RESTORER, 0x7f5257fd46e0}, {0x40075c, [ALRM], SA_RESTORER|SA_RESTART, 0x7f5257fd46e0}, 8) = 0
alarm(1) = 0
Example code which only sets the alarm during the sleep period.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <utmp.h>
#include <errno.h>
static int isSigAlrmOccured;
void alarm_handler (int signo)
{
static int i=1;
printf("\n Signal Occurred %d times\n",i++);
isSigAlrmOccured = 1;
}
int main (int argc, char *argv[]) {
struct itimerval delay;
struct utmp *utmpstruct;
int numuser;
int ret;
for (;;) {
signal (SIGALRM, alarm_handler);
alarm(1); /* wake me later */
pause ( );
/* count the number of users */
if ( (errno == EINTR) && (isSigAlrmOccured) ) {
signal (SIGALRM, SIG_DFL);
isSigAlrmOccured = 0;
numuser = 0;
setutent();
while ((utmpstruct = getutent())) {
if ((utmpstruct->ut_type == USER_PROCESS) &&
(utmpstruct->ut_name[0] != '\0'))
numuser++;
}
endutent();
printf("found %d users\n", numuser);
}
}
return 0;
}
This page lists the set of functions that are "safe" to call from a signal handler. If you call some other function, the behavior is undefined. I notice that setutent() doesn't seem to be on the lest, for starters ...