C/Visual C - Comando ps

 
Vista:

Comando ps

Publicado por Alvaro Luna (19 intervenciones) el 09/04/2007 13:20:25
Buenos días.
Tengo que hacer un programa C bajo Unix que revise si otros procesos se están ejecutando(lo que viene a ser un monitor de procesos). El comando ps de Unix da la información sobre los procesos, lo que necesito es una función C equivalente al comando ps que no lo debo ejecutar porque va demasiado lento.

He buscado información y he encontrado funciones como la getpid, que devuelve el pid del proceso que llama a esta función getpid. Necesito una funcion C que devuelva el PID de un proceso que se le pasa como argumento.
pid_t nombre_funcion(nombre_proceso), de tal forma que teniendo en ejecucion un proceso llamado suma admitiera una llamada:
pid_t pid;
pid=nombre_funcion("suma");

Saludos
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Comando ps

Publicado por Tom (27 intervenciones) el 09/04/2007 14:09:31
¿ Qué Unix ?
En Solaris, por ejemplo, puedes obtener la informacion del /proc (casi de la misma manera que en casi todos los Linux).

man -s4 proc
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Comando ps

Publicado por Alvaro Luna (19 intervenciones) el 09/04/2007 15:27:20
Gracias por la respuesta.

Es Solaris. Consultando el man que dices veo que define las estructuras que cuelgan de /proc. No quiero mucha floritura, lo que quiero es: dado un proceso que está ejecutándose obtener su pid desde el monitor de procesos, cosa que no he encontrado en el man -s4 proc.

En ese documento todo lo que se puede hacer creo que parte de saber previamente el PID, que es lo que quiero obtener.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Comando ps

Publicado por Tom (27 intervenciones) el 09/04/2007 16:43:25
Claro que lo tienes en el man.
Lo que tienes que hacer, mientras no se le ocurra a alguien otra manera -que no creo-, es examinar todos los pids en /proc, leer su estructura psinfo y comparar pr_fname con el nombre que estás buscando.

De todos modos, quizás te sirva algún otro comando, de los descritos en proc(1)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Comando ps

Publicado por Alvaro Luna (19 intervenciones) el 10/04/2007 11:59:17
Gracias. Hice lo que sugeriste, leer la tabla psinfo. Pero me está dando problemas bien raros, resulta que comparo el pr_fname con el nombre del proceso que quiero monitorizar(sum) en este bucle:
if((strcmp(p.pr_fname, "suma"))==0)
{

printf("Nombre proceso %s\n", p.pr_fname);
printf("Parametros %s, PID %u\n", p.pr_psargs, p.pr_pid);

if(p.pr_pid>10000)
printf("pid mayor de 10000");

}
Primero imprimo el nombre del proceso y los parametros que mas me interesan y luego saco un printf si su pid es mayor de 10000. Pues no me imprime nada. En cambio si pongo entre comentarios la parte del pid sí me saca bien las lineas de los parametros:
printf("Nombre proceso %s\n", p.pr_fname);
printf("Parametros %s, PID %u\n", p.pr_psargs, p.pr_pid);
//if(p.pr_pid>10000)
// printf("pid mayor de 10000");
Y a la inversa, sí me saca bien lo del pid si comento esas 2 lineas:
//printf("Nombre proceso %s\n", p.pr_fname);
//printf("Parametros %s, PID %u\n", p.pr_psargs, p.pr_pid);
if(p.pr_pid>10000)
printf("pid mayor de 10000");

¿Alguna idea? Te lo he puesto en la aplicacion real, pero este otro bucle tampoco imprime nada!!:
if((strcmp(p.pr_fname, "suma"))==0)
{

printf("Nombre proceso %s\n", p.pr_fname);
printf("Parametros %s, PID %u\n", p.pr_psargs, p.pr_pid);

puts("hola");

}

Te pongo el codigo entero:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include<dirent.h>

#include <sys/procfs.h>

main()
{
struct prpsinfo p;
DIR *dirf;
struct dirent *dirp;
int fd;
char parg[50];


if ((dirf = opendir("/proc")) == NULL) {
exit(1);
}
(void) readdir(dirf);

while ((dirp = readdir(dirf)) != NULL)
{

sprintf(parg, "/proc/%s", dirp->d_name);

if ((fd = open(parg, "r")) < 0)
{
continue;
}

ioctl(fd, PIOCPSINFO, (void *) &p);
/*
if (ioctl(fd, PIOCPSINFO, (void *) &p) < 0)
{
close(fd);
}
*/
if((strcmp(p.pr_fname, "suma"))==0)
{

printf("Proceso con parametros %s, PID %u\n", p.pr_psargs, p.pr_pid);
printf("Nombre proceso %s\n", p.pr_fname);


if(p.pr_pid>10000)
printf("es mayor de 10000");

}

close(fd);
}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Comando ps

Publicado por Tom (27 intervenciones) el 10/04/2007 12:31:38
Has hecho una buena investigación, con el tema del ioctl y demás.
Pero, lamentablemente, me temo que no puedes abrir (con open()) el directorio /proc/numero_de_pid.

Lo verás, si pones:

if((fd = open(parg, "r")) < 0) {
perror(parg);
continue;
}

Yo lo que haría es abrir el fichero /proc/pid/psinfo y leer de él la estructura psinfo.

Si tengo un rato, lo pruebo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Esta es la buena.

Publicado por Tom (27 intervenciones) el 10/04/2007 12:49:55
Pues nada, lo cierto es que no parece haber otra forma que llamando al ioctl (el método viejo, pensé que en Solaris 8 ya lo habrían unificado).

De cualquier manera, tu problema está en el open() (mira otra vez el man). Esta función no recibe "r", sino O_RDONLY (sys/fcntl.h).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Otra solución.

Publicado por Tom (27 intervenciones) el 10/04/2007 12:53:29
Investigando un poco más, he encontrado esto:

/*
* This definition is temporary. Structured proc is the preferred API,
* and the older ioctl-based interface will be removed in a future version
* of Solaris. Until then, by default, including <sys/procfs.h> will
* provide the older ioctl-based /proc definitions. To get the structured
* /proc definitions, either include <procfs.h> or define _STRUCTURED_PROC
* to be 1 before including <sys/procfs.h>.
*/

Entonces, la forma de hacerlo es esta (observa el cambio en el include):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/fcntl.h>
#include <procfs.h>

/* */
main() {
psinfo_t p;
DIR *dirf;
struct dirent *dirp;
int fd, i = 0;
char parg[255];

if((dirf = opendir("/proc")) == NULL) {
perror("/proc");
exit(1);
}
while((dirp = readdir(dirf)) != NULL) {
sprintf(parg, "/proc/%s/psinfo", dirp->d_name);
if((fd = open(parg, O_RDONLY)) < 0) {
perror(parg);
continue;
}
if(read(fd, &p, sizeof(p)) < 0) {
perror("read");
} else {
if((strcmp(p.pr_fname, "bash"))==0) {
printf("Proceso con parametros %s, PID %u\n", p.pr_psargs, p.pr_pid);
printf("Nombre proceso %s\n", p.pr_fname);
if(p.pr_pid > 10000)
printf(" es mayor de 10000 \n");
}
}
close(fd);
}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Otra solución.

Publicado por AlvaroLuna (19 intervenciones) el 10/04/2007 13:01:36
Muchas gracias Tom.
Seguía investigando abrir el /proc/pid/psinfo pero estaba teniendo problemas porque dicho fichero no es un fichero ordinario.

El caso es que esta última solucion me funciona perfectamente, asi que seguire con mi tarea.

P.D. Por cierto, anda que no me ha dado la lata cambios-fallos de Solaris 10...

Gracias otra vez
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar