Bienvenido(a), Visitante. Favor de ingresar o registrarse.
Diciembre 02, 2008, 01:52:57
Inicio Ayuda Buscar Ingresar Registrarse
Noticias: Foro de Java, C++ y más.

Nuevo foro de Control de versiones.

+  Foros Java y C/Linux
|-+  Programación
| |-+  C/C++ linux
| | |-+  Dudas sobre plstat
« anterior próximo »
Páginas: [1] 2 Enviar tema Imprimir
Autor Tema: Dudas sobre plstat  (Leído 1267 veces)
manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email


« en: Noviembre 21, 2007, 07:40:18 »

Hola, soy manuzafra@hotmail.com, no se si se te acordaras, me dijiste
que planteara mis dudas en el foro y aqui estoy. Muchas gracias ante todo.
Empiezo ya, intentare seguir un orden para que no nos perdamos.

Parece un poco largo pero creo que me he explicado bien y no creo que te sea
dificil contestarme

Dudas sobre el fichero Plstat.c:

1.-En la funcion escribeInfoFichero practicamente
lo primero que haces es lo siguiente:
   /*
    * Comprobación del parámetro de entrada
    */
   if (nombreFichero == NULL)
      return;
La primera pregunta es cual es el funcionamiento de esta parte de codigo
ya que no la entiendo muy bien. Yo creo que es para el caso en que se llame
a la funcion sin pasarle ningun parametro. Es esto cierto? Y si esta no es la
funcion, como puedo hacer lo que yo digo?

2.-Lo siguiente que haces es:

printf ("El fichero %s --> ", nombreFichero);

Vale entiendo lo que hace. Este programa Plstat esta diseñado para
que a la funcion se le pase como parametro un archivo pero que pasa
si estoy en otro directorio y le quiero pasar una ruta entera. Para que
me entiendas cuando digo una ruta me refiero a algo del tipo
home/alumno/plstat.c por ejemplo.

3.- siguiente: para comprobar el tipo de archivo q es el idem q le has pasao
como parametro a tu funcion tu lo haces asi

   if (S_ISREG(datosFichero.st_mode))

en la practica que tenemos que hacer nos dicen que lo hagamos asi
   
   if((datosFichero.st_mode & S_IFMT)==S_ISREG)

aqui la duda que tengo es cual es la diferencia entre los dos (entiendo
que el resultado sera el mismo) y si sabes por qué para saber el tipo
de archivo hay que ejecutar la operación AND sobre la constante S_IFMT
y el campo st_mode de la estructura stat?

4.- Viendo el Mils.c veo que lo de liberar memoria es bastante importante
Y mi pregunta es si cuando usemos lstat, la struct stat que tu has llamado
   
   struct stat datosFichero;

guarda mucha informacion en memoria, habria que liberarla tambien??

5.- En otro apartado debemos mostrar informacion del archivo que le hemos
pasado como parametro al lstat, y bueno seria tan sencillo como acceder al
apartado donde se guarda esa informacion y hacer un printf pero como te digo
si mi objetivo es pasarle como parametro una ruta la duda que tengo es como
separar la ruta el nombre del archivo y presentarlos por separado, Por si no
me entiendes si tengo la ruta home/alumno/plstat.c
presentar la info por pantalla de la siguiente manera:

   Nombre del archivo plstat.c

[vale acabo de darme cuenta que en la practica dice ruta completa lo que
incluiria tb el nombre del archivo, lo preguntare al profesor a ver cual
de las dos formas siguientes es]

   Ruta completa1: home/alumno/
   Ruta completa2: home/alumno/plstat.c
   
6.- Por ultimo mi objetivo es hacer un archivo ejecutable al que se le puedan
pasar no solo una ruta o un fichero si no mas de uno. Lo tengo hecho para que
sea el main el que reciba los parametros. Pero no se como implementar el resto.
Supongo que una manera seria almacenarlos en una matriz y hacer un bucle
do{}while hasta que hiciera el lstat con todos los parametros que le he pasado.
Pero me pierdo en el como hacer esto, en pasarle parametros al main.

Aver si puedes ayudarme, te lo agradeceria mucho.

quizas si te paso el texto de mi practica entenderias mejor mis dudas.
lo dejo para la proxima.
Tengo que realizar un makefile tambien voy a ponerme ahora mismo y
no dudes que te preguntare.

Un saludo


En línea
chuidiang
Administrator
Hero Member
*****
Mensajes: 1974



Ver Perfil WWW Email
« Respuesta #1 en: Noviembre 21, 2007, 08:02:07 »

Hola:

1. Efectivamente, es para ver si te pasan un fichero y si no te lo pasan, no hacer nada.

2. Simplemente pasa la ruta entera. Los home van con / delante.  /home/alumno/plstat.c

3. Supongo que son equivalentes, no me he metido por dentro del código de linux. S_ISREG(...) es posiblemente una macro que hace algo parecido por dentro a lo que te indican que tienes que hacer. El motivo de los AND es que datosFichero.st_mode es posiblemente un entero en el que cada bit individual significa algo concreto. Por ejemplo, el primer bit a uno indica que es un link, el segundo bit a 1 indica que es un directorio, etc. Los AND se hacen para ver un bit o grupo de bits concretos sin fijarse en los demas.

4. Las estructuras solo se liberan si se crean previamente con un alloc(). - o new en C++-. Algunas funciones hacen internamente el alloc() y devuelven la estructura dejándote a tí el trabajo de liberarla cuando no la necesites. Normalmente el man de la función suele indicar que necesitas hacer el free de la estructura devuelta.

5. ...

6. En el main, argc contendrá el número de ficheros que has pasado más uno y argv[1], argv[2], etc contendrán esos ficheros. Te basta con hacer un bucle desde 1 hasta argc.

Se bueno.
En línea

manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email
« Respuesta #2 en: Noviembre 21, 2007, 08:41:27 »

Entonces si la funcion lstat es de la siguiente manera
int lstat(char *nombreFichero, struct stat *datosfichero); 

y yo hago por ejemplo lstat /home/alumno/plstat.c

nombreFichero en este caso seria la ruta entera no? es decir si hiciera un
printf("%S", nombreFichero) me presentaria por pantalla
la ruta completa /home/alumno/plstat.c.

Y si yo quiero que me presente por pantalla solo el nombre del fichero
sin la ruta.

Respecto al punto 6 recuerdo que el profesor nos dijo que el main fuera de la siguiente manera

nt main (int argc, char *argv[]);

como dices el argc almacena el numero de parametros y pero argv que hace?, es una matriz, almacenaria solo la primera ruta que yo le meta, no?
y que pasaria con las siguientes?

Entonces; yo a mi archivo lo tengo que llamar info
entoces yo llamare al archivo de la siguiente manera
info /home/alumno/pstat.c
no le he pasao ningun numero entero.
tengo que pasarselo?
el solo sabe que le pasado una cadena de caracteres y la manda directamente al argv.

Otras dudas:
7. Para llamar a lstat tu usas en pstat.c
lstat(nombreFichero, &datosFichero) pero el man de lstat nos dice que la funcion es lstat(char *nombreFichero, struct stat *datosfichero);
¿cual es la funcion del &?

8. En el archivo Mils.c para presentar por pantalla los nombres de todas las entradas usas dentro del bucle:  printf ("%s\n", entradas->d_name);

Entiendo que al llamar a la funcion scandir se crea una struct dirent de nombre entradas que tiene un campo que se llama d_name que es donde se guardan los nombres de las entradas. Es esto correcto?
Pero no entiendo la funcion de la flecha, nunca la habia visto, cual es??

9. Mirando el man del lstat veo que existe la posibilidad de mirar las fechas de de la ultima modificacion, el ultimo acceso y el ultimo cambio (¿? diferencia entre cambio y modificacion??) pero no existe la fecha de creacion.
Existe este apartado en lstat? o se hace mediante otra funcion?


Muchisimas gracias de nuevo
[/i]
« Última modificación: Noviembre 21, 2007, 08:44:07 por manuzafra » En línea
chuidiang
Administrator
Hero Member
*****
Mensajes: 1974



Ver Perfil WWW Email
« Respuesta #3 en: Noviembre 21, 2007, 11:04:16 »

Hola:

La función basename() quita la parte del path y deja sólo el fichero.

argv contiene los parámetros que se pasan, en donde argv[0] sería el nombre del programa -en tu caso info- y argv[1] en adelante, los parámetros en sí.

No tienes que pasar ningún entero. Linux sabe contar para rellenar argc por tí.

Para lo del &, el * y las -> revisa cualquier tutorial de C sobre punteros. Sería demasiado largo contarlo aquí.

No hay fecha de creación. Acceso es lectura y modificación es escritura o cambio.

Se bueno.

En línea

manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email
« Respuesta #4 en: Noviembre 22, 2007, 01:02:29 »

Genial muchas gracias. esto va viento en popa..

8. En el archivo Mils.c para presentar por pantalla los nombres de todas las entradas usas dentro del bucle:  printf ("%s\n", entradas->d_name);

Entiendo que al llamar a la funcion scandir se crea una struct dirent de nombre entradas que tiene un campo que se llama d_name que es donde se guardan los nombres de las entradas. Es esto correcto?
Pero no entiendo la funcion de la flecha, nunca la habia visto, cual es??

Sabes alguna pagina de internet donde venga el man de la mayoria de las
funciones, en español. He visto por ejemplo maconlinux.net pero tiene poca informacion en algunas.

Por ultimo, respecto a lo que te pregunte sobre saber la fecha de creacion de un fichero que opinas de la funcion ctime, podria ayudarme?? en el man no dice nada de si la fecha que presenta es la de creacion, modificacion o acceso.

Muchas gracias de nuevo
« Última modificación: Noviembre 22, 2007, 01:13:41 por manuzafra » En línea
chuidiang
Administrator
Hero Member
*****
Mensajes: 1974



Ver Perfil WWW Email
« Respuesta #5 en: Noviembre 22, 2007, 05:53:21 »

Hola:

Insisto, lo de la ->, el * y el & es cosa de punteros, dale un repaso a cualquier tutorial. Si tienes una estructura, la forma de acceder a sus campos en con punto estructura.campo. Sin embargo, si tienes un puntero a una estructura, la forma de acceder a sus campos es con la flecha estructura->campo.

Casi todas las distribuciones de linux vienen con posibilidad de poner en man en español. Si usas uno parecido a ubuntu, busca en el gestor de paquetes synaptic manpages-es

ctime() convierte a cadena de texto la fecha que tú le digas. No da la fecha de creación del fichero. Que yo sepa, esa fecha de creación del fichero no se puede obtener.

Se bueno.
En línea

manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email
« Respuesta #6 en: Noviembre 22, 2007, 12:18:20 »

Ah vale, lo de la flecha no lo habia entendido pero ya si.

Y lo de la fecha de creacion, digo yo que se podra porque si el profesor nos la ha pedido. Cuando lo sepa, te lo comento.

Muchas gracias
En línea
manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email
« Respuesta #7 en: Diciembre 05, 2007, 06:07:21 »

Hola ya estoy aqui otra vez.

Efectivamente no existia ninguna funcion capaz de decirme la fecha de creacion del archivo como me habias comentado. El profesor reconocio que se habia equivocado y que se referia a la de cambio.

1.-Ahora una pregunta, ese numero que me sale como lo convierto en fecha??

2.-Ademas tengo un duda, para llamar al ejecutable que tenemos que crear, lo tenemos que hacer mediante ./info ruta1 ruta2 ... ruta n y despues presentara toda la informacion que nos pide de cada una de las rutas.

El caso es que toma ./info como la primera de las rutas, es decir como el primero de los parametros. Lo he solucionado empezando el bucle for en el 1 en vez de en el cero que seria el ./info para que asi se lo salte, pero me queda la duda.

Es eso normal?? estoy haciendo algo mal??

3.-He visto que para demostrar el funcionamiento lstat creas en el mismo programilla plstat un directorio, un fichero normal un link y un link simbolico.

El correcto funcionamiento de mi practica, implica diferenciar entre fichero normal, directorio, link simbolico, dispositivo de E/S por bloques, dispositivo de E/S por caracteres, y tuberia.

Como se crean estos 3 ulitmos para pasarselos como parametros y comprobar que todo esta correcto??

Ah una ultima cosa, en la presentacion nos pide que el entreguemos el codigo con las tabulaciones correctas.En palabras textuales: "Como se deben presentar todos los codigos de programa de toda la vida". ¿?
Entiendo que es metiendole un tabulador cada vez que habramos una llave del tipo {. Pero el cabron no me lo quiere decir. Como si hubiera entregado programas de estos en el colegio. pss

Bueno un saludo y por supuesto, muchas gracias de nuevo.
« Última modificación: Diciembre 05, 2007, 06:11:13 por manuzafra » En línea
chuidiang
Administrator
Hero Member
*****
Mensajes: 1974



Ver Perfil WWW Email
« Respuesta #8 en: Diciembre 05, 2007, 06:37:21 »

Hola:

1. Para convertir ese número a una fecha normal tienes que usar funciones como mktime(), ctime(), asctime(), etc. Cada una de ellas admite un parámetro en un formato y lo devuelve en otro. Revisa a ver cual te vale.

2. Es normal. argv[0] siempre es el nombre del programa, en tu caso "./info"

3. Los dispositivos de caracteres y de bloques es dificil crearlos. Puedes pasar uno de los ficheros del sistema que encontrarás en el directorio /dev. Si haces un ls -l, son los que en las letras de permisos empiezan por c o por b. En cuanto al de tubería, no estoy muy seguro, pero quizás puedas crear uno con un socket tipo AF_UNIX, aunque me parece un poco complejo para el ejemplo que estais haciendo.

Ultima cosa. La tabulación correcta depende un poco de gustos y hay varias normativas/recomendaciones al respecto. Una variante dice que se abren las llaves al final de la línea, luego se sengra con tres espacios y la llave se cierra al final en una línea nueva y sin sangrado. Los sangrados se van incrementando según añades llaves. Por ejemplo

Código:
void funcion (int parametro) {
   linea1;
   if (condicion) {
      linea2;
   }
   linea3;
}

Otras normativas dicen que la llave se abre en una línea nueva. Habitualmente no se usan los tabuladores, sino que se ponen los espacios.

Echa un ojo a este enlace http://es.wikipedia.org/wiki/Estilo_de_programaci%C3%B3n que es un ejemplo. Busca también "code beautifiers" que son programas que cogen los fuentes y automáticamente arreglan los sangrados. Linux debe tener alguno instalado o fácilmente instalable, como bcpp.

Se bueno.

En línea

manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email
« Respuesta #9 en: Diciembre 08, 2007, 07:39:09 »

Genial esta ultima respuesta, me ha venido de perlas.

Ahora si me permites te voy a repetir una pregunta que ya te hice porque necesito una respuesta mas amplia.

En la practica tenemos que comprobar el tipo de fichero que estamos examinando de la siguiente manera
   
   if((datosFichero.st_mode & S_IFMT)==S_ISREG)

Respecto a mi pregunta:

¿sabes porque para determinar el tipo de un archivo será necesario acceder al campo st_mode de la estructura stat y aplicarle la constante S_IFMT mediante una operación de AND a nivel de bits?

Tu respuesta: "El motivo de los AND es que datosFichero.st_mode es posiblemente un entero en el que cada bit individual significa algo concreto. Por ejemplo, el primer bit a uno indica que es un link, el segundo bit a 1 indica que es un directorio, etc. Los AND se hacen para ver un bit o grupo de bits concretos sin fijarse en los demas.";  fue bastante esclarecedora en su momento pero necesito dar una respuesta basante mas amplia.

Se, bueno, sabemos, que comparando el resultado de esta operación con las constantes asociadas a los distintos tipos de fichero se puede saber si se trata de un archivo normal, un dispositivo de tipo carácter o de tipo bloque, un directorio o un archivo de tipo FIFO

1.Sabrias decirma algo, donde puedo mirar para conseguirla??

2. Este es mi fichero makefile para compilar

CC=gcc
CFLAGS= -Wall -g
ORIGEN = info.c
OBJETO = info.o
EJECUTABLE = info

$(EJECUTABLE): $(OBJETO)
   $(CC) $(OBJETO) -o $(EJECUTABLE)
$(OBJETO): $(ORIGEN)
   $(CC) –c $(ORIGEN) –o $(OBJETO)

Lo ves correcto? algo que comentar, cualquier cosa seria de gran ayuda.

3. La siguiente practica me pide implementar un comando ejecutar, que reciba como parametros un comando de linux (ls, man, etc cualquiera) y todas las rutas que se quiera. y aplique el comando sobre todas las rutas.

Alguna idea para comenzar???

Muchas gracias de nuevo.
En línea
chuidiang
Administrator
Hero Member
*****
Mensajes: 1974



Ver Perfil WWW Email
« Respuesta #10 en: Diciembre 08, 2007, 09:02:50 »

Hola:

Un pequeño truco. Para todo esto de constantes y cosas raras, lo mejor es irse al directorio /usr/include que es donde suelen estar los .h que incluimos en nuestro código, y a los subdirectorios por debajo.

Haciendo un comando egrep, podemos buscar algo dentro de todos los ficheros .h, en mi caso he probado

cd /usr/include
egrep S_IFMT *.h
egrep S_IFMT */*.h

y he obtenido, que dentro de /usr/include/linux/stat.h hay esto

#define S_IFMT  00170000
#define S_IFSOCK 0140000
#define S_IFLNK    0120000
#define S_IFREG  0100000
#define S_IFBLK  0060000
#define S_IFDIR  0040000
#define S_IFCHR  0020000
#define S_IFIFO  0010000
#define S_ISUID  0004000
#define S_ISGID  0002000
#define S_ISVTX  0001000

Supongo que esas son las constantes a las que te refieres, aunque hay que "intuir" que es cada cosa

Se bueno.
En línea

manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email
« Respuesta #11 en: Diciembre 09, 2007, 02:22:32 »

De hecho esa informacion incluso mas extensa se obtiene con el man de lstat, donde a esos valores se les denomina banderas de campo

Copiado:

Se definen las siguientes banderas para el campo st_mode:

S_IFMT   0017000   mascara de bits para los campos de bit del tipo de fichero (no POSIX)
S_IFSOCK 0140000   enchufe (no POSIX)
S_IFLNK   0120000   enlace simbolico (no POSIX)
S_IFREG   0100000   fichero regular (no POSIX)
S_IFBLK   0060000   dispositivo de bloques (no POSIX)
S_IFDIR   0040000   directorio (no POSIX)
S_IFCHR   0020000   dispositivo de caracteres (no POSIX)
S_IFIFO   0010000   fifo o tuberia nombrada (no POSIX)
.
.
.
.
.
 y asi muchas mas.

Asi supongo que no hay que buscarle mas trascendencia y la respuesta es bastante sencilla.

Lo que no se lo que es todavia es lo de POSIX o no POSIX, buscare info por ahi.

¿que me dices sobres las otras dos cuestionas, el makefile y el comando ejecutar?

Gracias de nuevo.

En línea
chuidiang
Administrator
Hero Member
*****
Mensajes: 1974



Ver Perfil WWW Email
« Respuesta #12 en: Diciembre 09, 2007, 05:11:39 »

Hola:

El makefile me parece bien, sin embargo, muchas de las opciones que pones suelen venir por defecto. Deberías intentar reaprovecharlas. De hecho, si tu fichero en info.c, posiblemente el comando

make info

sepa construir un ejecutable info a partir de info.c sin necesidad de fichero Makefile.

En cuanto a lo del comando, con los argc y argv del main puedes sacar lo necesario. De todas formas, en plan "trampa", con un par de líneas de código tienes hecho el programa. Echale un ojo a la función system().

Se bueno.
En línea

manuzafra
Newbie
*
Mensajes: 33


Ver Perfil Email
« Respuesta #13 en: Diciembre 09, 2007, 08:50:51 »

Hola de nuevo.

A ver, no entiendo a que te refieres con lo de en plan trampa, quizas te refieras a una manera rapida y facil de implementar el comando, pero ... podrias explicarte mejor.

Entiendo tu opinion sobre el makefile, de hecho ya lo suponia pues es bastante logico, lo que pasa es que no me queda mas remedio, porque me lo piden, forma parte de la practica.

Respecto a la funcion system() he consultado esta pagina que es la que suelo usar para buscar info sobre funciones.

http://www.maconlinux.net/linux-man-pages/es/system.3.html

Como puedes ver, dice que: "Que la version de system() en libc no haga caso de las interrupciones hace imposible interrumpir los programas que la llaman desde un bucle. Lo cual significa que para tales propositos uno no deberi­a utilizar system() sino una version privada" y presenta un codigo-ejemplo como variante aunque tambien dice que no esta probado.

¿Que hable de la version de system() en "libc" implica que dara fallos siempre o solo en ese "libc".?

No se.

Esta claro que la forma mas facil y comoda de implementar el comando al que se le deben poder pasar muchos valores es mediante un bucle.

¿¿¿¿Alguna alternativa a system()Huh

A ver que opinas de esa informacion y del codigo que viene como variante.

« Última modificación: Diciembre 09, 2007, 09:04:39 por manuzafra » En línea
chuidiang
Administrator
Hero Member
*****
Mensajes: 1974



Ver Perfil WWW Email
« Respuesta #14 en: Diciembre 09, 2007, 11:24:41 »

Hola:

system() funciona bien, salvo que la llamada a system no se puede interrumpir. En general, para un ejemplo sencillo como puede ser el tuyo, no debería ser importante. De todas formas, en le mismo link que me pasas tiene la alternativa, la función my_system() que se basa en la función execve().

Se bueno.
En línea

Páginas: [1] 2 Enviar tema Imprimir 
« anterior próximo »
Ir a:  


Ingresar con nombre de usuario, contraseña y duración de la sesión

Powered by MySQL Powered by PHP Powered by SMF 1.1.5 | SMF © 2006-2007, Simple Machines LLC XHTML 1.0 válido! CSS válido!