Question
Help in Unix in bash here is the apue.h file lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len)) #define write_lock(fd, offset, whence, len) lock_reg((fd), F_SETLK, F_WRLCK,
Help in Unix in bash here is the apue.h file
lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len)) #define write_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len)) #define writew_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len)) #define un_lock(fd, offset, whence, len) \ lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))
pid_t lock_test(int, int, off_t, int, off_t); /* {Prog locktest} */
#define is_read_lockable(fd, offset, whence, len) \ (lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0) #define is_write_lockable(fd, offset, whence, len) \ (lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)
void err_msg(const char *, ...); /* {App misc_source} */ void err_dump(const char *, ...) __attribute__((noreturn)); void err_quit(const char *, ...) __attribute__((noreturn)); void err_cont(int, const char *, ...); void err_exit(int, const char *, ...) __attribute__((noreturn)); void err_ret(const char *, ...); void err_sys(const char *, ...) __attribute__((noreturn));
void log_msg(const char *, ...); /* {App misc_source} */ void log_open(const char *, int, int); void log_quit(const char *, ...) __attribute__((noreturn)); void log_ret(const char *, ...); void log_sys(const char *, ...) __attribute__((noreturn)); void log_exit(int, const char *, ...) __attribute__((noreturn));
void TELL_WAIT(void); /* parent/child from {Sec race_conditions} */ void TELL_PARENT(pid_t); void TELL_CHILD(pid_t); void WAIT_PARENT(void); void WAIT_CHILD(void);
#endif /* _APUE_H */
Explain the logic of the program in Example 2, especially on (a) when SIGTSTP is received, which process (parent or child) is handling the signal, and (b) what happens (or is done) by the signal handler (signhand).
void sighand(int signum){
/* supposedly need to reset this here (per "man signal" and
it's discussion of signals under linux), but doesn't actually
seem to matter. Documentation != observed program behavior. */
kill(pid_child,SIGKILL);
fprintf(stderr, "nyah, nyah Mr. #%d. ", signum);
}
(3) Modify the program in Example 2 so that (a) the signal is handled by the child (not the parent), and (b) output message (fprintf statement) in sighand for SIGTSTP will also print the PID of the current process handling the signal.
void sighand(int signum){
/* supposedly need to reset this here (per "man signal" and
it's discussion of signals under linux), but doesn't actually
seem to matter. Documentation != observed program behavior. */
kill(pid_child,SIGKILL);
fprintf(stderr, "nyah, nyah Mr. #%d. ", signum);
}
EX 1:
#include "apue.h"
static void sig_usr(int); /* one handler for both signals */
int
main(void)
{
if (signal(SIGUSR1, sig_usr) == SIG_ERR)
err_sys("cant catch SIGUSR1");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)
err_sys("cant catch SIGUSR2");
for ( ; ; )
pause();
}
static void
sig_usr(int signo) /* argument is signal number */
{
if (signo == SIGUSR1)
printf("received SIGUSR1 ");
else if (signo == SIGUSR2)
printf("received SIGUSR2 ");
else
err_dump("received signal %d ", signo);
}
Commands for EX 1:
$ ./a.out & [1] 7216 $ kill -USR1 7216 received SIGUSR1 |
|
$ kill -USR2 7216 received SIGUSR2 |
|
$ kill 7216 [1]+ Terminated |
./a.out
|
EX 2:
// minishell part 1 - Shell sample code with execvp
#include
#include
#include
#include
#define MAX_ARG 10
int pid_child;
/*** Main ***/
void sighand(int signum);
int main(){
// declare variables
char *prompt = "sh1$ ";
char line[256];
char line1[256];
char program[32], command[32], *args[MAX_ARG];
int pid, status, i;
// print the prompt
printf("%s", prompt);
// Try getting input. If error or EOF, exit
while(fgets(line, sizeof line, stdin) != NULL)
{
// fgets leaves ' ' in input buffer. ditch it
line[strlen(line)-1] = '\0';
strcpy(line1,line);
// If the input is not null, get in
if (line != NULL) {
// parse command and arg
args[0] = strtok(line, " "); // grab command
for(i=1; i<10; i++) // grab arguments
args[i] = strtok(NULL, " ");
strcpy(command, args[0]); // store command variable
// check to see if the command is 'exit'
if(!strcmp("exit", args[0])) {
exit(0);
}
// check to see if the command is 'cd'
else if(!strcmp("cd", args[0])) {
chdir(args[1]);
}
// handles all other commands
else {
pid = fork(); // fork to create new child
if(pid == 0) { // code to be run by the child
signal(SIGTSTP, SIG_IGN);
status = execvp(command, args); // execute
exit(0); // exit child
}
else { // code to be run by the parent
pid_child = pid;
signal(SIGTSTP, sighand);
waitpid(-1); // wait for children to finish
signal(SIGTSTP, SIG_DFL);
}
}
}
// print the prompt
printf("%s", prompt );
}
return 0;
}
void sighand(int signum)
{
/* supposedly need to reset this here (per "man signal" and
it's discussion of signals under linux), but doesn't actually
seem to matter. Documentation != observed program behavior. */
//signal(signum, nyahnyah);
kill(pid_child,SIGKILL);
fprintf(stderr, "nyah, nyah Mr. #%d. ", signum);
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started