2010-12-31 26 views
14

Tengo un programa donde necesito configurar los permisos de un archivo (digamos /home/hello.t) usando chmod y tengo que leer los permisos para establecer desde un archivo. Para esto, primero leo los permisos en una matriz de caracteres y luego trato de modificar los permisos del archivo. Pero veo que los permisos se establecen de una manera extraña.Usando chmod en un programa C

un programa de ejemplo que he escrito:

main() 
{ 
    char mode[4]="0777"; 
    char buf[100]="/home/hello.t"; 
    int i; 
    i = atoi(mode); 
    if (chmod (buf,i) < 0) 
     printf("error in chmod"); 
} 

veo que los permisos del archivo no se establecen en 777. Puede usted por favor me ayude a cabo sobre cómo configurar los permisos del archivo después de leer el lo mismo desde una matriz de caracteres.

Respuesta

32

La función atoi() solo traduce decimal, no octal.

Para la conversión octal, utilice strtol() (o, como Chris Jester-Young señala, strtoul() - aunque los tamaños válidos de los modos de permisos de archivo para todos Unix encajan dentro de 16 bits, por lo que nunca va a producir un negativo long de todos modos) con 0 o 8 como la base. En realidad, en este contexto, especificar 8 es lo mejor. Permite a las personas escribir 777 y obtener el valor octal correcto. Con una base de 0 especificada, la cadena 777 es decimal (nuevamente).


Además:

  • No utilizar 'int implícito' Tipo de cambio de main(); ser explícito según lo requerido por C99 y usar int main(void) o int main(int argc, char **argv).
  • No juegue al cortar los nulos del hilo.

    char mode[4] = "0777"; 
    

    Esto impide C de almacenar un valor nulo de terminal - mal! Uso:

    char mode[] = "0777"; 
    

    Esto asigna los 5 bytes necesarios para almacenar la cadena con un terminador nulo.

  • Informe de errores en stderr, no stdout.

  • Informe de errores con una nueva línea al final.
  • Es una buena práctica incluir el nombre del programa y el nombre del archivo en el mensaje de error, y también (como señaló CJY) incluir el número de error del sistema y la cadena correspondiente en la salida. Eso requiere el encabezado <string.h> (para strerror()) y <errno.h> para errno. Además, el estado de salida del programa debe indicar un error cuando la operación chmod() falla.

poner todos los cambios juntos rendimientos:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <sys/stat.h> 

int main(int argc, char **argv) 
{ 
    char mode[] = "0777"; 
    char buf[100] = "/home/hello.t"; 
    int i; 
    i = strtol(mode, 0, 8); 
    if (chmod (buf,i) < 0) 
    { 
     fprintf(stderr, "%s: error in chmod(%s, %s) - %d (%s)\n", 
       argv[0], buf, mode, errno, strerror(errno)); 
     exit(1); 
    } 
    return(0); 
} 

tener cuidado con errno; puede cambiar cuando se llaman las funciones.Aquí es lo suficientemente seguro, pero en muchos escenarios, es una buena idea capturar errno en una variable local y usar la variable local en las operaciones de impresión, etc.

Tenga en cuenta también que el código no verifica errores en el resultado de strtol(). En este contexto, es lo suficientemente seguro; si el usuario proporcionó el valor, sería una mala idea confiar en que lo haga bien.


Un último comentario: en general, no debe usar el permiso 777 en archivos (o directorios). Para los archivos, significa que no te importa quién modificará tu programa ejecutable, o cómo. Usualmente este no es el caso; a usted le importa (o debería importar) quién modifica sus programas. En general, no haga que los archivos de datos sean ejecutables; cuando los archivos son ejecutables, no otorgue acceso de escritura pública y mire de reojo al acceso de escritura grupal. Para los directorios, el permiso de escritura pública significa que no le importa quién elimina alguno de los archivos en el directorio (o agrega archivos). De nuevo, ocasionalmente, esta puede ser la configuración de permiso correcta para usar, pero rara vez es correcta. (Para los directorios, generalmente también es una buena idea usar el 'bit adhesivo': el permiso 1777 es el que normalmente se usa en /tmp, por ejemplo, pero no en MacOS X.)

+0

'strtoul' es aún mejor, porque ¿Quién usa modos negativos, en serio? :-P Además, informe errores con 'errno' incluido, como por ejemplo usando' perror' o 'strerror' (o'% m' en la cadena de formato, si usa GNU libc). –

+0

Gracias, funciona genial. Y una más gracias por corregir mis errores de programación. – Raghav

+0

El valor de errno numérico no se muestra convencionalmente en los mensajes de error, ya que es redundante y puede revelar información no deseada sobre el tipo de sistema operativo. – jilles