Kodumda nerede "çocuklar bitene kadar beklemeliyim"? Özel bir kabuğa benzer bir C programım var. Şimdi sıralı ortam değişkenlerini yazdırabilen bir yerleşik işlev checkEnv
var. Ortam değişkenlerini sayarken Şimdi çıkış sonlandırma sinyali yakalamak istiyorumHangi sinyali kullanmalıyım ve nasıl yapmalıyım?
if(StartsWith(line, "checkEnv")) {
built_in_command=1;
pagerValue = getenv ("PAGER");
if (! pagerValue) {
if (ret == 0) {
pager_cmd[0]="less";
} else {
pager_cmd[0]="more";
}
}
else {
pager_cmd[0]=pagerValue;
}
if(i==1) {
cmd[0].argv= printenv;
cmd[1].argv= sort;
cmd[2].argv= pager_cmd;
fork_pipes(3, cmd);
}
else {
for (k = 1; k < i; k++)
{
len += strlen(argv2[k]) + 2;
}
tmp = (char *) malloc(len);
tmp[0] = '\0';
for (k = 1; k < i; k++)
{
pos += sprintf(tmp + pos, "%s%s", (k == 1 ? "" : "|"), argv2[k]);
}
grep[0]="grep";
grep[1]="-E";
grep[2]= tmp;
grep[3]= NULL;
cmd2[0].argv= printenv;
cmd2[1].argv= grep;
cmd2[2].argv= sort;
cmd2[3].argv= pager_cmd;
fork_pipes(4, cmd2);
free(tmp);
}
:
$ ./a.out
miniShell>> checkEnv
"'><;|&(:
_=./a.out
CLUTTER_IM_MODULE=xim
COMPIZ_CONFIG_PROFILE=ubuntu
COMP_WORDBREAKS=
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-mh5oMhyCI6
DEFAULTS_PATH=/usr/share/gconf/ubuntu.default.path
DESKTOP_SESSION=ubuntu
arkasında kod şudur vermez: Yani benim kabuk başlatmak ve benim ortam değişkenleri listeleyebilirsiniz çağrı programını kullanarak program tüm programı sonlandırmak yerine özel kabuğa geri döner. Bu yüzden bazı sinyal işlemlerini kullanmam gerektiğini, ama nasıl ve hangi sinyali kullanmalıyım?
Gerçek çatal bu işlevden kaynaklanır.
/* Helper function that forks pipes */
void fork_pipes(int n, struct command *cmd) {
int i;
int in = 0;
int fd[2];
/** loop and fork() */
for (i = 0; i < n - 1; ++i) {
if (pipe(fd) == -1) {
err_syserr("Failed creating pipe");
}
spawn_proc(in, fd[1], cmd + i);
close(fd[1]);
in = fd[0];
}
if (dup2(in, 0) < 0) {
err_syserr("dup2() failed on stdin for %s: ", cmd[i].argv[0]);
}
fprintf(stderr, "%d: executing %s\n", (int) getpid(), cmd[i].argv[0]);
execvp(cmd[i].argv[0], cmd[i].argv);
err_syserr("failed to execute %s: ", cmd[i].argv[0]);
}
Sinyal işleme nereye gitmeli? Ne yapmaya çalıştığımın en az çalışan örneği nerede? Bunun bir örneği görmüyorum ve bence bu belgeler korkunç, sadece parçacıklar ve tam bir örnek değil.
My yardımcı işlevi
/* Helper function that spawns processes */
int spawn_proc(int in, int out, struct command *cmd) {
pid_t pid;
pid = fork();
if (pid == 0) {
if (in != 0) {
if (dup2(in, 0) < 0)
err_syserr("dup2() failed on stdin for %s: ", cmd->argv[0]);
close(in);
}
if (out != 1) {
if (dup2(out, 1) < 0)
err_syserr("dup2() failed on stdout for %s: ", cmd->argv[0]);
close(out);
}
printf("** we are executing parent ***");
fprintf(stderr, "%d: executing %s\n", (int) getpid(), cmd->argv[0]);
execvp(cmd->argv[0], cmd->argv);
err_syserr("failed to execute %s: ", cmd->argv[0]);
}
else if (pid < 0) {
err_syserr("fork failed: ");
} else {
/* */
printf("** we are the parent ***");
}
return pid;
}
main()
şimdi şuna benzer Benim: Ben gdb
benim kabuk çalıştırırsanız
int main(int argc, char *argv[]) {
sourceCount = 0;
const char *commandFile;
commandFile = NULL;
char *pathValue;
/* struct sigaction sa, osa;
struct sigaction sa2;*/
int errflag;
int cOption;
struct sigaction action;
/* use getopt_long() */
char *argv1[] = {"version", "par2", 0};
/* char *argv2[] = {"help", "-m", "arg1", 0};*/
/* use sigaction */
sigemptyset(&action.sa_mask);
action.sa_handler = handle_sigchld;
action.sa_flags = 0;
sigaction(SIGPIPE, &action, NULL); //Not work with kill -13 process_id
//works well
sigaction(SIGINT, &action, NULL); //work with kill -2 process_id
errflag = 0;
/* use getopt_long() */
while ((cOption = getopt(2, argv1, "m:t:n:fs?")) != -1) {
switch (cOption) {
case 'a':
printf("apples\n");
break;
case 'b':
printf("bananas\n");
break;
case 't':
printf("tree = %s\n", optarg);
break;
case '?':
++errflag;
break;
}
}
/*
while ((cOption = getopt (3, argv2, "m:t:n:fs?")) != -1) {
switch (cOption) {
case 'm':
printf("\n Help msg : %s \n", optarg);
exit(0);
case '?':
printf("\n -? Arg : %s \n", optarg);
break;
case 'n':
printf("\n -n Arg : %s \n", optarg);
break;
}
}
*/
/* get the PATH environment to find if less is installed */
pathValue = getenv("PATH");
if (!pathValue || getenv("PATH") == NULL) {
printf("'%s' is not set.\n", "PATH");
/* Default our path if it is not set. */
putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc");
}
else {
printf("'%s' is set to %s.\n", "PATH", pathValue);
}
exec_program(commandFile);
return (0);
}
Ben normal bir çıkışı olsun.
(gdb) run
Starting program: /home/dac/ClionProjects/shell2/openshell/shell
'PATH' is set to /home/dac/proj/google-cloud-sdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin.
dac:/home/dac/ClionProjects/shell2/openshell $ checkenv
7429: executing printenv
7430: executing grep
7417: executing less
7431: executing sort
process 7417 is executing new program: /bin/less
[Inferior 1 (process 7417) exited normally]
(gdb)
: Orijinal istekte
kodunuzu çok eksik, işte bir örnek gelirse? SIGPIPE? Gerçek kabuğun sana söylemeli. –