ENUNCIADO
Como primera práctica (que no hay que entregar), hay que realizar
un programa que admita el nombre de un fichero como argumento.
El programa debe cambiar el grupo al que pertenece el fichero
al grupo cuyo identificador de grupo es el 666. El programa
debe detectar e imprimir las codiciones de error y devolver
0 al sistema operativo si no se produjeron errores y 1 en caso
contrario. Notas: en caso de que el fichero sea un enlace
simbólico, debe cambiar el grupo del propio enlace, no de
aquello a lo que apunta. El propietario del fichero debe
permanecer inalterado.
COMENTARIOS
La práctica con 0.25 es la de Goku y Son Gohan:
#define _HPUX_SOURCE
#include <stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
/* Es normal verificar que los argumentos pasados son correctos */
if (argc != 2)
{ /* Los errores, por el canal de errores. */
fprintf(stderr,"\n\nUso: %s <fichero>\n\n",argv[0]);
return 1; /* Al incluir argv[0], si cambio el nombre del programa, el mensaje sigue siendo válido. */
}
if (lchown(argv[1],UID_NO_CHANGE,666)==-1)
{ /* Bastaría con el perror, pero así se sabe qué fichero falla. */
fprintf(stderr,"\nNo se ha podido cambiar el grupo del ");
fprintf(stderr,"grupo del fichero: %s\n\n",argv[1]);
perror("lchown");
return 2;
}
return 0; /* No olvidar el código de retorno de éxito. */
}
Fijaros en el estilo de la práctica para las próximas que mandéis.
Nada de comentarios ni código innecesario. Los comentarios en rojo
son míos. Si no aparece vuestra práctica, no quiere decir que esté
mal, sino que puede que llegara más tarde.
MENCIONES ESPECIALES
LPEs
- Inauguramos la sección de cosas que hay que evitar no con
un error, sino con un estilo de programación que se debe evitar:
if(argc != 2)
{
printf("\nSintaxis: cam_grp [fichero].\n");
return 1;
}
else
{
if(lchown(argv[1], getuid(), 666) == -1)
{
sprintf(etiqueta, "%s: chown: %s", argv[0], argv[1]);
perror(etiqueta);
return 1;
}
else return 0;
}
Consiste en un anidamiento innecesario de bloques
if-else
. No aporta nada al código y hace que el
programa se desplace innecesariamente a la derecha. El mismo
código se puede escribir más claramente haciendo lo mismo así:
if(argc != 2)
{
printf("\nSintaxis: cam_grp [fichero].\n");
return 1;
}
if(lchown(argv[1], getuid(), 666) == -1)
{
sprintf(etiqueta, "%s: chown: %s", argv[0], argv[1]);
perror(etiqueta);
return 1;
}
return 0;
- Observad esta línea:
res=lchown(argv[1],UID_NO_CHANGE,0666);
Ese inocente cero (0) que aparece delante del 666 hace que la
práctica no se comporte como se desea. ¿Es que hay diferencia
entre 666 y 0666? Pues en C, sí. Cuando se antepone un cero
a un número en C significa que dicho número está escrito en
base 8. Así que 0666 equivale a 6+8*6+8*8*6=438. Lo que ocurre
es que cuando se manejan permisos de fichero es más cómodo
trabajar en octal pues cada dígito corresponde con un tipo de
permiso (propietario, grupo o todos los demás).
© 2000 Guillermo González Talaván.