User Tools

Site Tools


progsys:index

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
progsys:index [2017/10/19 15:14] – [Calculer en Pipeline] orelprogsys:index [2024/03/18 15:06] (current) – external edit 127.0.0.1
Line 276: Line 276:
 </code> </code>
  
-Dans ce cas, un même père crée tous les fils.+__Indice__ :  Dans ce cas, un même père crée tous les fils de la façon suivante... mais cela n'explique pas tout !
      
   Père             (cmdN)   Père             (cmdN)
Line 790: Line 790:
     int k = atoi(argv[1]);     int k = atoi(argv[1]);
  
-    for(int s = ; s < argc ; s++)+    for(int s = ; s < argc ; s++)
       for(int i = 0 ; i < k ; i++) {       for(int i = 0 ; i < k ; i++) {
  kill(ppid, atoi(argv[s])); // envoi signal  kill(ppid, atoi(argv[s])); // envoi signal
Line 809: Line 809:
     sigemptyset(&act.sa_mask);     sigemptyset(&act.sa_mask);
      
-    for(int sig = ; sig < NSIGNORT ; sig++) {+    for(int sig = ; sig < NSIGNORT ; sig++) {
       sigaction(sig, &act, NULL);       sigaction(sig, &act, NULL);
       tab[sig] = 0;       tab[sig] = 0;
Line 917: Line 917:
      
   return 0;   return 0;
 +}
 +</code>
 +
 +==== Open Pipe Command (exo 3, DS 2017-2018) ====
 +
 +On souhaite disposer d’une fonction //open_pipe_command// dont le profil est :
 +
 +  int open_pipe_command (int *fd, char *cmd, char **argv)
 +
 +Cette fonction crée un processus chargé d’exécuter la commande //cmd// avec les arguments //argv//, et renvoie deux descripteurs (dans le tableau fd) permettant respectivement d’écrire vers l’entrée standard de la commande (descripteur fd[1]) et de lire depuis la sortie standard de la commande (descripteur fd[0]). On utilisera pour cela deux tubes permettant d’établir une connexion bidirectionnelle avec le processus exécutant la commande. La fonction retournera le //pid// du processus fils exécutant la commande.
 +
 +<code C open_pipe_command.c>
 +/* gcc -Wall -std=c99 open_pipe_command.c && ./a.out */
 +
 +#include <stdio.h>
 +#include <unistd.h>
 +#include <stdlib.h>
 +#include <string.h>
 +#include <sys/types.h>
 +#include <sys/wait.h>
 +
 +#define HELLO "hello world!" // 12 
 +
 +int open_pipe_command(int * fd, char * cmd, char **argv)
 +{
 +  int pr[2]; pipe(pr); 
 +  int pw[2]; pipe(pw); 
 +  /* user reads in fd[0]=pr[0] & writes in fd[1]=pw[1] */
 +  fd[0] = pr[0]; fd[1] = pw[1];   
 +  int pid = fork();
 +  if(pid == 0) { /* child */        
 +    close(pw[1]); close(pr[0]); /* useless */
 +    /* cmd writes in pr[1]=1 & reads in pw[0]=0 */
 +    dup2(pw[0],0); dup2(pr[1],1); 
 +    close(pw[0]); close(pr[1]); 
 +    execvp(cmd, argv); 
 +    perror("Error execvp");
 +    exit(EXIT_FAILURE);
 +  }
 +  close(pw[0]); close(pr[1]); /* useless */
 +  return pid; /* success > 0*/
 +}
 +
 +int main(int argc, char * argv[])
 +{
 +  int fd[2];
 +  char* cmd[] = {"tr", "a-z", "A-Z", NULL};
 +  int pid = open_pipe_command(fd, *cmd, cmd);
 +  if(pid <= 0) return EXIT_FAILURE;
 +  write(fd[1], HELLO, strlen(HELLO)+1);
 +  close(fd[1]);
 +  char msg[128];
 +  int r = read(fd[0], msg, 128);  
 +  printf("msg[%d]: %s -> %s\n", r, HELLO, msg);
 +  close(fd[0]);
 +  waitpid(pid, NULL, 0);
 +  return EXIT_SUCCESS;
 +}
 +</code>
 +
 +==== Ctrl-C ====
 +
 +Un processus fils est dans le même PGID (process group ID) que son père par defaut (pgid père = pgid fils = pid père). Un kill sur -pid du père envoie le signal à tous le groupe, donc au fils également...
 +
 +<code C sigint.c>
 +#include <stdlib.h>
 +#include <stdio.h>
 +#include <unistd.h>
 +#include <signal.h>
 +#include <sys/types.h>
 +
 +void handler(int sig)
 +{
 +    printf("paf\n");
 +}
 +
 +int main(void)
 +{
 +    signal(SIGINT, handler); // TODO: utiliser sigaction() plutôt que signal() !
 +
 +    if (fork() == 0)
 +    {
 +        printf("child: %d %d\n", getpid(), getpgid(0));
 +        pause();
 +        printf("child: bye bye!\n");
 +        exit(EXIT_SUCCESS);
 +    }
 +
 +    printf("father: %d %d\n", getpid(), getpgid(0));
 +    pause();
 +    printf("father: bye bye!\n");
 +    return EXIT_SUCCESS;
 +}
 +</code>
 +
 +
 +==== Timeout ====
 +
 +<code C executer-avant-delai.c>
 +
 +#define _GNU_SOURCE
 +#include <unistd.h>
 +#include <signal.h>
 +#include <stdio.h>
 +#include <setjmp.h>
 +
 +static struct sigaction sa, old;
 +static sigjmp_buf env;
 +
 +static void myalarm(int sig)
 +{
 +  printf("alarm!\n");
 +  siglongjmp(env,1);
 +}
 +
 +int executer_avant_delai( void (*fun)(void *), void *parametre, int delai_en_seconde)
 +{
 +  int ret = 1;
 +  sa.sa_handler = myalarm;
 +  sa.sa_flags = 0; // SA_RESETHAND;
 +  sigemptyset(&sa.sa_mask);
 +  sigaction(SIGALRM, &sa, &old);
 +
 +  alarm(delai_en_seconde);
 +  if(sigsetjmp(env,1) == 0)
 +    fun(parametre);
 +  else
 +    ret = 0; // alarm
 +  alarm(0);
 +  sigaction(SIGALRM, &old, NULL);
 +  return ret;
 } }
 </code> </code>
progsys/index.1508426096.txt.gz · Last modified: 2024/03/18 15:05 (external edit)