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 i aplicacions en C

De SergiTurWiki
Share/Save/Bookmark
Dreceres ràpides: navegació, cerca

Contingut

Funcions exec en C

Hi ha diferents funcions de C per executar aplicacions/comandes. Totes comencen per exec però només hi ha una crida de sistema: execve. Totes les funciones exec acaben fent ús d'aquesta crida de sistema.

IMPORTANT: Les crides exec no creen nous processos! Només substitueixen en procés que les executa per un altre programa. El "nou procés" té el 
mateix PID que el procés que ha executat exec.


C utilitza les funcions :

#include <unistd.h>

extern char **environ;

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

La crida de sistema de UNIX és:

Crida al sistema:

#include <unistd.h>

int execve(const char *filename, char *const argv[],char *const envp[]);

Per tal d'executar comandes i aplicacions. No s'ha de confondre aquestes funcions de C amb la crida de sistema execve. Els altres sufixos volen dir:

Les diferències entre execv i execl estan en que execl utilitza una llista de paràmetres indefinits a priori per especificar els paràmetres de la comanda que volem executar i execv utilitza un vector.

Consulteu | execve a l'article Crides_al_sistema_de_Unix#Execuci.C3.B3_de_programes._Exec.

Exemples execl

#include <unistd.h>
main()
{
   execl("/bin/ls", "/bin/ls", "-r", "-t", "-l", (char *) 0);
}

Exemples execlp (execl amb PATH)

Execlp és equivalent a execl però si el path a la comanda no conté el caràcter / aleshores es buscarà la comanda a el PATH del sistema (variable d'entorn PATH). La variable d'entorn PATH es pot consultar amb:

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

o

$ env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Si el PATH no està especificat s'utilitza el PATH per defecte:

:/bin:/usr/bin 

Executar una comanda:

$ comanda

En C i amb la funció execpl seria:

execlp(“comanda”, “comanda”, NULL);

Executar una comanda amb paràmetres:

$ ls -l fitxer.txt

En C i amb la funció execpl seria:

execlp(“ls”, “ls”, “-l”, “fitxer.txt”, NULL);

Exemples execle (execl amb ENVIRONMENT)

Cada Shell té unes variables d'entorn que poden influir sobre l'execució de les comandes. Les variables d'entorn es poden consultar amb:

$ env
SSH_AGENT_PID=6900
GPG_AGENT_INFO=/tmp/seahorse-Ryw485/S.gpg-agent:6900:1
SHELL=/bin/bash
DESKTOP_STARTUP_ID=
TERM=xterm
...

Un de les variables d'entorn és PATH:

 $ env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

I per aquesta raó no existeix una funció execlep o execlpe.

Podem establir la variable d'entorn amb:

char *env[] = { "USER=user1", "PATH=/usr/bin:/bin:/opt/bin", (char *) 0 };


Exemples execv

#include <unistd.h>
main()
{
   char *args[] = {"/bin/ls", "-r", "-t", "-l", (char *) 0 };   

   execv("/bin/ls", args);
}

Exemples execve

Exemple 1:

El programa:

#define PROGRAMA_FILL "./SelPri"
...
char  *fargv[3];
...
fargv[0] = PROGRAMA_FILL;
fargv[1] = ./primers;
fargv[2] = 0;
execve(PROGRAMA_FILL, fargv,0);

És equivalent a executar:

$ ./SelPri ./primers
string getErrMsg(int errnum);

Exemple 2:

main()
{
   string envFile("environment_variables.conf");
   CReadEnvironmentVariablesFile readEnvFile;
   char **Env_envp = readEnvFile.ReadFile(envFile);  

   // Command to execute
   char *Env_argv[] = { "/bin/ls", "-l", "-a", (char *) 0 };   

   pid_t pID = fork();
   if (pID == 0)                // child
   { 
      // This version of exec accepts environment variables.
      // Function call does not return on success.  

      int execReturn = execve (Env_argv[0], Env_argv, Env_envp); 

      cout << "Failure! execve error code=" << execReturn << endl;  

      cout << getErrMsg(execReturn) << endl;

      _exit(0); // If exec fails then exit forked process.
   }
   else if (pID < 0)             // failed to fork
   {
      cerr << "Failed to fork" << endl;
   }
   else                             // parent
   {
      cout << "Parent Process" << endl;
   }
}

Vegeu també

Funció system

Permet executar comandes del sistema:

#include <stdlib.h>
int system(const char *command);

ATENCIÓ: system("command"); és equivalent a executar:

$ /bin/sh -c command

Utilitza sh i no pas bash.

Recursos:

Exemple comanda system

#include <stdio.h>
#include <stdlib.h>
main()
{
    system("ls -l");
    printf("Command done!");
}

atexit

Permet executar una funció al finalitzar un programa:

#include <stdlib.h>
int atexit(void (*function)(void));

Exemple extret del manual:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void
bye(void) {
 printf("That was all, folks\n");
}

int
main(void) {
 long a;
 int i;
  
 a = sysconf(_SC_ATEXIT_MAX);
 printf("ATEXIT_MAX = %ld\n", a);

 i = atexit(bye);
 if (i != 0) {
  fprintf(stderr, "cannot set exit function\n");
  return EXIT_FAILURE;
 }
 return EXIT_SUCCESS;
}

Recursos:

onexit

Similar a at_exit però permet passar paràmetres.

 #include <stdlib.h>
 int on_exit(void (*function)(int , void *), void *arg);


Vegeu també

Exec a PHP

Recursos

OpenFPnet
IES Nicolau Copèrnic