IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Execució de comandes. exec

foreground

El codi:

switch (pid = fork()) {
  case –1 : error(“fork”);
  case 0: execlp(“comanda”, “comanda”, NULL);
          error(“exec”);
  default: /* Fem wait fins que detectem finalitzacio procés ls */
           do {
             ret = wait(&stat);
           } while ((ret!=-1) && (ret!=pid));
           if (ret == -1) error(“wait”);
}

És equivalent a

$ comanda

background (&)

El codi:

switch (fork()) {
  case –1 : error(“fork”);
  case 0: execlp(“comanda”, “comanda”, NULL);
          error(“exec”);
  /* no fem wait perque s’ha executat en background */
}

És equivalent a:

$ comanda & 

Pipe (|)

Consulteu l'apartat Pipes de l'article Crides al sistema.

Exemple. Com executar dos comandes amb pipe

$ ps aux | grep proces

main()

{
  int fd[2], st;
  if (pipe(fd)<0) error(“pipe”);
  switch (fork()) {
    case – 1: error(“fork”);
    case 0: if (close(1) < 0) error(“close”);
            if (dup(fd[1]) < 0) error(“dup”);
            if (close(fd[0]) < 0) error(“close”);
            if (close(fd[1]) < 0) error(“close”);
            execlp(“ps”, “ps”, “aux”, NULL);
            error(“Executant ps aux”);
    default: swith(fork()) {
               case –1 : error(“fork”);
               case 0: if (close(0) < 0) error(“close”);
                       if (dup(fd[0]) < 0) error(“close”);
                       if (close(fd[0]) < 0) error(“close”);
                       if (close(fd[1]) < 0) error(“close”);
                       execlp(“grep”, “grep”, “[mn]”, NULL);
                       error(“exec grep”);
               default: if   (close(fd[0]) < 0) error(“close”);
                        if   (close(fd[1]) < 0) error(“close”);
                         if  (wait(&st) < 0) error(“wait”);
                         if  (wait(&st) < 0) error(“wait”);
             }
  }
}


Redireccions de la sortida (>) i entrada (<) estàndard

Redireccions de la sortida (>)

  1. Es tanca la sortida estàndard (close(1);)
  2. S'obre el fitxer de sortida (i li assigna el primer descriptor de fitxer lliure que és el de sortida que acabem de tancar)

Exemple:

if (close(1) < 0) {
 //Control d'error
} 
if (open(“fitxer.txt”, O_WRONLY|O_CREATE|O_TRUNC, 0600) < 0) {
 //Control d'error
}
execlp(“comanda”, “yes”, NULL);
//Control errors

És equivalent a:

$ comanda > fitxer.txt

Redireccions de la entrada (<)

  1. Es tanca la sortida estàndard (close(0);)
  2. S'obre el fitxer d'entrada (i li assigna el primer descriptor de fitxer lliure que és el de entrada que acabem de tancar)

Exemple':

open("/etc/ld.so.preload", O_RDONLY)

if (close(0) < 0) {
 //Control d'error
} 
if (open("fitxer.txt", O_RDONLY)  < 0) {
 //Control d'error
}
execlp(“comanda”, “yes”, NULL);
//Control errors

És equivalent a:

$ comanda < fitxer.txt

Exemple 1

$ comanda > resultat.txt &
$ ls –l resultat.txt

Codi en C

int stat, pid, ret;
switch (fork()) {
  case –1 : // Controlar error . P. ex. error(“Error al fer un fork”);
  case 0: close(1)
          if (open(“resultat.txt”, O_WRONLY|O_CREATE|O_TRUNC, 0600) < 0) {
           // Controlar error . P. ex. error(“Error al fer un open”);
          }
          execlp(“comanda”, “comanda”, NULL);
          //Si arribem aquí és un error de execlp
          //error(“Error al fer un execlp”);

  /* no executem un wait al pare perquè estem executant en background */
}
switch (pid = fork()) {
  case –1 : // Controlar error . P. ex. error(“Error al fer un fork”);
  case 0: execlp(“ls”, “ls”, “-l”, “resultat.txt”, NULL);
          // Controlar error . P. ex. error(“Error al fer un execpl”);
  default: /* Fem wait fins que detectem finalitzacio procés ls */
           do {
             ret = wait(&stat);
           } while ((ret!=-1) && (ret!=pid));
           if (ret == -1) error(“wait”);
}

Exemple 2

La comanda:

$ ls –la | grep [mn] > sortida.txt
main()
{
  int fd[2], st;
  if (pipe(fd)<0) error(“pipe”);
  switch (fork()) {
    case – 1: error(“fork”);
    case 0: if (close(1) < 0) error(“close”);
            if (dup(fd[1]) < 0) error(“dup”);
            if (close(fd[0]) < 0) error(“close”);
            if (close(fd[1]) < 0) error(“close”);
            execlp(“ls”, “ls”, “-la”, NULL);
            error(“exec ls”);
    default: swith(fork()) {
               case –1 : error(“fork”);
               case 0: if (close(0) < 0) error(“close”);
                       if (dup(fd[0]) < 0) error(“close”);
                       if (close(fd[0]) < 0) error(“close”);
                       if (close(fd[1]) < 0) error(“close”);
                       if (close(1) < 0) error(“close”);
                        if (open(“sortida.txt”,O_WRONLY|O_TRUNC|O_CREAT)<0)
                            error(“open”);
                       execlp(“grep”, “grep”, “[mn]”, NULL);
                       error(“exec grep”);
               default: if   (close(fd[0]) < 0) error(“close”);
                        if   (close(fd[1]) < 0) error(“close”);
                         if  (wait(&st) < 0) error(“wait”);
                         if  (wait(&st) < 0) error(“wait”);
             }
  }
}