elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Curso de javascript por TickTack


  Mostrar Mensajes
Páginas: [1]
1  Programación / Programación C/C++ / Re: Programacion en C en: 3 Enero 2022, 18:27 pm
Ese mensaje en tu programa indica que falló execl. Asegúrate de que el archivo "hijo" exista en el mismo directorio que "padre", y que sea ejecutable. Puedes ver más detalles sobre el error si después del fprintf que muestra "Error en la ejecucion del proceso hijo\n", pones:
Si, tanto el proceso padre como el proceso hijo ambos estan en el mismo directorio, he puesto la linea de codigo que me has dicho y cuando ejecuto me devuelve:
Error en la ejecucion del proceso hijo
execl: No such file or directory
He intentado solucionarlo, pero segun he visto en los apuntes y en el manual no he conseguido ver los fallos, no se porque tiene fallos de directorio, si tanto el hijo como el padre estan en el mismo directorio


Por ejemplo, tu read está mal, ya que el segundo parámetro debería ser una cadena de caracteres. Y a execl le estás pasando argv[ i ]: tal y como tienes el for, eso es incorrecto. Revísalo bien y verás por qué.

-Ahi he creado un buffer de lectura/escritura, creo que con ello me basta aunque tenia dudas de que en vez de crear un buffer poner la variable NOMBREHIJO
-En cuanto al for no se a cual de los dos se refiere, pero he analizado ambos y no encuentro lo que dices que es incorrecto, no se si te refieres a esto:
 
Código:
if(execl(NOMBREHIJO, NOMBREHIJO, argv[1], NULL) == -1){ //argv[1]
fprintf(stderr, "Error en la ejecucion del proceso hijo\n");
    perror("execl");
exit(EXIT_FAILURE);
alli en vez de argv, he puesto argv[1], no se si ese seria el fallo que me dices...
[/b]

Los procesos hijos deberían terminar con _exit o exit, no con return; no sé por qué cambiaste eso. De cualquier forma forma, esa última línea del case 0 no debería retornar EXIT_FAILURE; eso es sólo cuando se finaliza con error. Y ahora que lo vuelvo a ver, estrictamente hablando, en tu programa no necesitarías ese último exit (o return), ya que los hijos están llamando a execl (que los reemplaza por procesos nuevos), pero de todas formas es importante acostumbrarte a finalizar siempre todos tus procesos hijos

Y esto es cierto :) acabo de fijarme en los manuales y es asi como dice. Gracias!

adjunto el codigo del proceso padre nuevamente y el del hijo a continuacion:


HIJO
Código:
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>

int main(int argc, char *argv[]){

/*Tratamiento de la linea de ordenes*/
if(argc != 2){
fprintf(stderr, "Error en el numero de argumentos\n");
return EXIT_FAILURE;
}

//Para las señales
sleep(5); //El hijo se ejecuta se duerme 5 seg y va ha inprimir el 1º caracter por tubería
//Ve como se matan los procesos hijos.

putchar(argv[1][0]);  //El primer caracter en la salida estandar y escribe en la tuberia, imprime el primer caracter
return EXIT_SUCCESS;
}



PADRE
Código:
#define _POSIX_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <wait.h>

#define NUM_HIJOS 10//El numero de hijos debe ser tantos como numero de parametros haya
#define NOMBREHIJO "./hijo"
#define MAXBUFFER 256 //Tamaño del buffer lectura/escritura

void FinalizarProcesos();

void Manejador(int num);

pid_t pids[NUM_HIJOS];
int longitud_pid=0;//logitud del pid

int main(int argc, char *argv[]){
int fd[2];//Descriptores de la tuberia de comunicacion
int i, j; //Para los bucles
int pid; //PID de un proceso hijo

int status; //terminacion proceso hijo
char buffer[MAXBUFFER];//buffer de lectura/escritura
/*Tratamiento de la linea de ordenes*/
if(argc < 2){// < 2
fprintf(stderr, "Error en el numero de argumentos\n");
exit(EXIT_FAILURE);
}

/*Tratamiento de la señal*/
if(signal(SIGINT, Manejador)== SIG_ERR){
fprintf(stderr, "Error en la manipulacion de la señal\n");
exit(EXIT_FAILURE);
}

/*?? Creacion de la tubería de comunicacion*/
if(pipe(fd) != 0){
fprintf(stderr, "Error en la creacion de la tuberia\n");
return EXIT_FAILURE;
}

//CREACION DE LOS PROCESOS HIJOS
for(i=1; i<NUM_HIJOS; i++){
switch(pids[i-1]=fork()){ //Se guarda el pid en la tabla de procesos y con pids[i-1]se salta el ./padre
case -1:
fprintf(stderr, "Error en la creacion del proceso hijo\n");
FinalizarProcesos();
break;
case 0: //Ejecucuion por el proceso hijo
close(1);
if(dup(fd[1]) != 1){// Asignacion de salida estandar
fprintf(stderr, "Error en la duplicacion del descriptor\n");
return EXIT_FAILURE;
}
if(execl(NOMBREHIJO, NOMBREHIJO, argv[1], NULL) == -1){ //argv[1]
fprintf(stderr, "Error en la ejecucion del proceso hijo\n");
    perror("execl");
exit(EXIT_FAILURE);
}
break;
default: /*Ejecucion por el proceso padre*/
//close(fd[1]);// debe de ir fuera del for
break;
}
longitud_pid++; //Para tener un control de cuantas cosas hay dentro del pids, por ejemplo hola (longitud=1) mundo (longitud=2)
}
close(fd[1]);


/*Espera a la finalizacion de los procesos hijos*/
for(i=1; i<NUM_HIJOS; i++){
pid=wait(NULL);
read(fd[0], buffer, sizeof(buffer));//leerá la tuberia y la escribirá en la salida estandar
//leer un caracter de entrada de la tuberia fd[0] (READ)
}
printf("[Proceso padre] finaliza\n");
return EXIT_SUCCESS;
}

/*FinalizarProcesos: Termina todos los procesos hijos vivos*/
void FinalizarProcesos(void){
int i;
for(i=0; i<longitud_pid; i++){ //Logitud_pid es porque los pids leidos van a tener valor
if(kill(pids[i], SIGTERM) == -1){
fprintf(stderr, "Error al enviar una señal\n");
exit(EXIT_FAILURE);
}

}
}


/*Manejador: Manejador de señal*/
void Manejador(int num){
FinalizarProcesos();
printf("[Proceso padre] finaliza\n");
exit(EXIT_SUCCESS);
}
2  Programación / Programación C/C++ / Re: Programacion en C en: 3 Enero 2022, 10:20 am
Gracias por tu ayuda @RayR. He intentado hacer los cambios según he entendido, pero a la hora de compilarlo no me da un error pero cuando ejecuto el proceso padre con (./padre.o hola mundo) me aparece errores como:
-Error en la ejecucion del proceso hijo
-[Proceso padre] finaliza
Adjunto el código con los cambios.

Código:

#define _POSIX_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <wait.h>

#define NUM_HIJOS 10//El numero de hijos debe ser tantos como numero de parametros haya
#define NOMBREHIJO "./hijo"

void FinalizarProcesos();

void Manejador(int num);

pid_t pids[NUM_HIJOS];
int longitud_pid=0;//logitud del pid

int main(int argc, char *argv[]){
int fd[2];//Descriptores de la tuberia de comunicacion
int i, j; //Para los bucles
int pid; //PID de un proceso hijo

int status; //terminacion proceso hijo

/*Tratamiento de la linea de ordenes*/
if(argc < 2){// < 2
fprintf(stderr, "Error en el numero de argumentos\n");
exit(EXIT_FAILURE);
}

/*Tratamiento de la señal*/
if(signal(SIGINT, Manejador)== SIG_ERR){
fprintf(stderr, "Error en la manipulacion de la señal\n");
exit(EXIT_FAILURE);
}

/*?? Creacion de la tubería de comunicacion*/
if(pipe(fd) != 0){
fprintf(stderr, "Error en la creacion de la tuberia\n");
return EXIT_FAILURE;
}

//CREACION DE LOS PROCESOS HIJOS
for(i=1; i<NUM_HIJOS; i++){
switch(pids[i-1]=fork()){ //Se guarda el pid en la tabla de procesos y con pids[i-1]se salta el ./padre
case -1:
fprintf(stderr, "Error en la creacion del proceso hijo\n");
FinalizarProcesos();
break;
case 0: //Ejecucuion por el proceso hijo
close(1);
if(dup(fd[1]) != 1){// Asignacion de salida estandar
fprintf(stderr, "Error en la duplicacion del descriptor\n");
return EXIT_FAILURE;
}
if(execl(NOMBREHIJO, NOMBREHIJO, argv[i], NULL) == -1){ //argv[1]
fprintf(stderr, "Error en la ejecucion del proceso hijo\n");
return EXIT_FAILURE;
}
return EXIT_FAILURE;
break;
default: /*Ejecucion por el proceso padre*/

break;
}
longitud_pid++; //Para tener un control de cuantas cosas hay dentro del pids, por ejemplo hola (longitud=1) mundo (longitud=2)
}
close(fd[1]);


/*Espera a la finalizacion de los procesos hijos*/
for(i=1; i<NUM_HIJOS; i++){
pid=wait(NULL);
read(fd[0], pids, sizeof(pids));
//leer un caracter de entrada de la tuberia fd[0] (READ)
}
printf("[Proceso padre] finaliza\n");
return EXIT_SUCCESS;
}

/*FinalizarProcesos: Termina todos los procesos hijos vivos*/
void FinalizarProcesos(void){
int i;
for(i=0; i<longitud_pid; i++){ //Logitud_pid es porque los pids leidos van a tener valor
if(kill(pids[i], SIGTERM) == -1){
fprintf(stderr, "Error al enviar una señal\n");
exit(EXIT_FAILURE);
}

}
}


/*Manejador: Manejador de señal*/
void Manejador(int num){
FinalizarProcesos();
printf("[Proceso padre] finaliza\n");
exit(EXIT_SUCCESS);
}
3  Programación / Programación C/C++ / Programacion en C en: 2 Enero 2022, 15:17 pm
Buenas he hecho este codigo pero me queda por implementar una linea de codigo acerca de read que lea un caracter de entrada de la tuberia fd[0] y la verdad no se como hacerlo. Se encuentra en el for: /*Espera a la finalizacion de los procesos hijos*/

Código:
#define _POSIX_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <wait.h>

#define NUM_HIJOS 10//El numero de hijos debe ser tantos como numero de parametros haya
#define NOMBREHIJO "./hijo"

void FinalizarProcesos();

void Manejador(int num);

pid_t pids[NUM_HIJOS];
int longitud_pid=0;//logitud del pid

int main(int argc, char *argv[]){
int fd[2];//Descriptores de la tuberia de comunicacion
int i, j; //Para los bucles
int pid; //PID de un proceso hijo

int status; //terminacion proceso hijo

/*Tratamiento de la linea de ordenes*/
if(argc < 2){// < 2
fprintf(stderr, "Error en el numero de argumentos\n");
exit(EXIT_FAILURE);
}

/*Tratamiento de la señal*/
if(signal(SIGINT, Manejador)== SIG_ERR){
fprintf(stderr, "Error en la manipulacion de la señal\n");
exit(EXIT_FAILURE);
}

/*?? Creacion de la tubería de comunicacion*/
if(pipe(fd) != 0){
fprintf(stderr, "Error en la creacion de la tuberia\n");
return EXIT_FAILURE;
}

//CREACION DE LOS PROCESOS HIJOS
for(i=1; i<NUM_HIJOS; i++){
switch(pids[i-1]=fork()){ //Se guarda el pid en la tabla de procesos y con pids[i-1]se salta el ./padre
case -1:
fprintf(stderr, "Error en la creacion del proceso hijo\n");
return EXIT_FAILURE;
break;
case 0: //Ejecucuion por el proceso hijo
close(1);
if(dup(fd[1]) != 1){// Asignacion de salida estandar
fprintf(stderr, "Error en la duplicacion del descriptor\n");
return EXIT_FAILURE;
}
if(execl(NOMBREHIJO, NOMBREHIJO, argv[i], NULL) == -1){ //argv[1]
fprintf(stderr, "Error en la ejecucion del proceso hijo\n");
exit(EXIT_FAILURE);
}
break;
default: /*Ejecucion por el proceso padre*/
close(fd[1]);
break;
}
longitud_pid++; //Para tener un control de cuantas cosas hay dentro del pids, por ejemplo hola (longitud=1) mundo (longitud=2)
}

/*Espera a la finalizacion de los procesos hijos*/
for(i=1; i<NUM_HIJOS; i++){
pid=wait(NULL);
//leer un caracter de entrada de la tuberia fd[0] (READ)
}
printf("[Proceso padre] finaliza\n");
return EXIT_SUCCESS;
}

/*FinalizarProcesos: Termina todos los procesos hijos vivos*/
void FinalizarProcesos(void){
int i;
for(i=0; i<longitud_pid; i++){ //Logitud_pid es porque los pids leidos van a tener valor
if(kill(pids[i], SIGTERM) == -1){
fprintf(stderr, "Error al enviar una señal\n");
exit(EXIT_FAILURE);
}

}
}


/*Manejador: Manejador de señal*/
void Manejador(int num){
FinalizarProcesos();
printf("[Proceso padre] finaliza\n");
exit(EXIT_SUCCESS);
}
4  Programación / Programación C/C++ / Re: Duda con un programa en C en: 28 Diciembre 2021, 08:10 am
Puede ser voy a ponerlo, gracias
5  Programación / Programación C/C++ / Duda con un programa en C en: 28 Diciembre 2021, 06:30 am
Hola, no se muy bien como puedo especificar en mi codigo que en lugar de tener o crear 5 procesos hijos, se creen tantos procesos hijos como numero de argumentos hallan
Código:
#define _POSIX_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <wait.h>

#define NUM_HIJOS 5//El numero de hijos debe ser tantos como numero de parametros haya
#define NOMBREHIJO "hijo"

void FinalizarProcesos();

void Manejador(int num);
pid_t pids[NUM_HIJOS];

int main(int argc, char *argv[]){
int i, j;
int pid;
/*Tratamiento de la linea de ordenes*/
if(argc != 2){
printf(stderr, "Error en el numero de argumentos\n");
exit(EXIT_FAILURE);
}
/*Tratamiento de la señal*/
if(signal(SIGINT, Manejador)== SIG_ERR){
fprintf(stderr, "Error en la manipulacion de la señal\n");
exit(EXIT_FAILURE);
}
/*Creacion de los procesos hijos*/
for(i=0; i<NUM_HIJOS; i++){
switch(pids[i]=fork()){ //Se guarda el pid en la tabla de procesos
case -1:
fprintf(stderr, "Error en la creacion del proceso hijo\n");
FinalizarProcesos();
break;
case 0:
if(execl(NOMBREHIJO, NOMBREHIJO, argv[1], NULL) == -1){
fprintf(stderr, "Error en la ejecucioon del proceso hijo\n");
exit(EXIT_FAILURE);
}
break;
}

}
/*Espera a la finalizacion de los procesos hijos*/
for(i=0; i<NUM_HIJOS; i++){
pid=wait(NULL);
for(j=0;j<NUM_HIJOS; j++){
if(pid==pids[j]){
printf("[Preoceso padre] el proceso %d ha terminado\n", pid);
pids[j]=0; //0 para indicar que no existe el proceso
}
}
}
printf("[Proceso padre] finaliza\n");
return EXIT_SUCCESS;
}

/*FinalizarProcesos: Termina todos los procesos hijos vivos*/
void FinalizarProcesos(void){
int i;

for(i=0; i<NUM_HIJOS; i++){
if(pids[i] != 0){ //Solo se mata a los procesos hijos vivos
if(kill(pids[i], SIGINT) == -1){
fprintf(stderr, "Error al enviar una señal\n");
}
}
}
}

/*Manejador: Manejador de señal*/
void Manejador(int num){
FinalizarProcesos();
printf("[Proceso padre] finaliza\n");
exit(EXIR_SUCCESS);
}
Páginas: [1]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines