나는 내 자신의 껍질을 만들고있어. 명령을 실행하고 &으로 종료하면 백그라운드에서 프로세스가 실행되므로 백그라운드 프로세스를 포그 라운드에 넣을 수있는 fg 명령을 만들고 싶습니다.포 그라운드 신호 tcsetpgrp c
fg 기능을 만드는 데 문제가 있습니다. 올바르게 이해한다면, 자식 프로세스에 signal()을 넣으면 자식 프로세스가 신호를받을 수있게됩니다. 신호는 signum과 핸들러 함수라는 두 개의 인수를받습니다. tcsetpgrp()를 사용하여 주어진 백그라운드 프로세스를 포 그라운드로 설정합니다. 그래서 lsh_fg에서 나는 tcsetpgrp (STDIN_FILENO, pid)를 호출한다.
그래서 signum은 tcsetpgrp()에서 신호를받을 수 있도록 sigttou 여야합니다.
는내가 (tcsetpgrp를하기 때문에, 핸들러 내부에 넣어되어야 하는지를 모른다는) 매뉴얼 페이지를 설명으로 할 예정이다 : 는 " 함수 tcsetpgrp를()는 프로세스 그룹 ID 을 pgrp와 프로세스 그룹을 만드는 fd 에 연결된 터미널의 전경 프로세스 그룹 " 내가 이해하는 것처럼 tcsetpgrp()는 신호 (sigttou, handler)가있는 프로세스로 신호를 보내고, 신호를 받으면 포 그라운드로 보냅니다. 그러나 그것이 작동하지 않기 때문에 나는 이것을 분명히 오해하고 있습니다.
내 질문 : tcsetpgrp()와 signal (sigttou, handler)가 함께 작동하는 방식을 어떻게 이해해야합니까? 그리고 내 처리기에는 무엇이 포함되어야합니까? 정말 답장 해 주셔서 감사합니다. :-) 아래 코드를 참조하십시오. Ps : 저는 C와 시스템 프로그래밍을 처음 접했고 이것은 내 첫 번째 게시물이기 때문에 코드에 관한 건설적인 비판을 환영합니다. 고마워 : D
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
pid_t pid;
int toke_c;
//function declaration for the function pointers
int lsh_cd(char **args);
int lsh_pwd(char **args);
int lsh_exit(char **args);
int lsh_fg(char **args);
//An array of functions:
int (*builtin_func[]) (char **) = {
&lsh_cd,
&lsh_pwd,
&lsh_exit,
&lsh_fg
};
//An array of the given strings:
char *builtin_str[] = {
"cd",
"pwd",
"exit",
"fg"
};
///built in functions cd and pwd
int lsh_fg(char **args){
tcsetpgrp(STDIN_FILENO, pid);
return 1;
}
void fg_handler()
{
//What to put here???
}
///built in functions cd and pwd
int lsh_cd(char **args)
{
if (args[1] == NULL) {
fprintf(stderr, "lsh: cd: no arguments given\n");
} else {
if (chdir(args[1]) != 0) {
perror("lsh");
}
}
return 1;
}
int lsh_pwd(char **args)
{
char * cwd;
cwd=getcwd (NULL,0);
printf ("%s\n ", cwd);
return 1;
}
int lsh_exit(char **args)
{
return 0;
}
/* Handlers Here*/
void killer()
{
if (pid == 0)
exit(0);
}
void handler()
{
//I DON'T KNOW WHAT TO PUT HERE
}
int lsh_launch(char **args)
{
int status=0;
pid = fork();
if (pid == 0) {
// child process
signal(SIGINT, killer);
if (execvp(args[0], args) == -1) {
fprintf(stderr,"Command not found in $PATH\n");
}
return 1;
} else if (pid < 0) {
//error
perror("lsh");
} else {
// parent
signal(SIGINT, killer);
waitpid(pid, &status, WUNTRACED);
}
return 1;
}
int lsh_background(char **args)
{
pid_t pid;
int status=0;
pid = fork();
if (pid == 0) {
// child process
setpgid(0, 0);
signal(SIGINT, killer);
signal(SIGTTOU, fg_handler);
if (execvp(args[0], args) == -1) {
fprintf(stderr,"Command not found in $PATH\n");
}
return 1;
} else if (pid < 0) {
//error
perror("lsh");
} else {
// parent
signal(SIGTTOU, fg_handler);
signal(SIGINT, killer);
}
return 1;
}
//if a command was entered that we've been using
int lsh_exec(int argc, char **args)
{
int i;
if (args[0] == NULL) {return 1;}
int tresh=4;
char **args1=malloc(toke_c*sizeof(char *));
int j;
for(j=0;j<toke_c-1;j++){
args1[j]=args[j];
}
if(strcmp(args[toke_c-1],"&")==0){
return lsh_background(args1);
}
for (i = 0; i < tresh; i++) {
if (strcmp(args[0], builtin_str[i]) == 0) {
return (*builtin_func[i])(args);
}
}
return lsh_launch(args);
}
#define MAX_STR 256
//reading the line
char *lsh_lread(void)
{
char *str = malloc (MAX_STR);
fgets (str, MAX_STR, stdin);
}
//tokenizer
char **lsh_tokenizer(char *line)
{
int bufsize = 64;
int pos_t = 0;
char **tokens = malloc(bufsize * sizeof(char*));
char *token;
token = strtok(line, " \t\r\n\a");
while (token != NULL) {
tokens[pos_t] = token;
pos_t++;
token = strtok(NULL, " \t\r\n\a");
}
tokens[pos_t] = NULL;
toke_c=pos_t;
return tokens;
}
void lsh_loop(void)
{
int argc;
char *line;
char **args;
int status;
do {
printf(">> ");
line = lsh_lread();
args = lsh_tokenizer(line);
status = lsh_exec(argc,args);
free(line);
free(args);
} while (status);
}
int main(int argc, char **argv)
{
lsh_loop();
return 0;
}