2010-12-31 11 views
14

Mam program, w którym muszę ustawić uprawnienia do pliku (na przykład /home/hello.t) przy użyciu chmod i muszę odczytać uprawnienia do ustawienia z pliku. W tym celu najpierw odczytałem uprawnienia do tablicy znaków, a następnie spróbowałem zmodyfikować uprawnienia pliku. Ale widzę, że uprawnienia są ustawione w dziwny sposób.Użycie polecenia chmod w programie C

Przykładowy program Pisałem:

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"); 
} 

widzę, że uprawnienia do pliku nie są ustawione na 777. Czy możesz mi pomóc w jaki sposób ustawić uprawnienia dostępu do pliku po przeczytaniu to samo z tablicy znaków.

Odpowiedz

32

Funkcja atoi() tłumaczy tylko dziesiętnie, a nie ósemkowo.

Dla ósemkowej konwersji, użyj strtol() (lub, jak Chris Jester-Young wskazuje strtoul() - choć ważne rozmiary trybów dostępu do pliku dla systemu Unix zmieścić w ciągu 16 bitów, a więc nigdy nie będzie produkować negatywny long tak) z 0 lub 8 jako podstawa. W tym kontekście najlepiej jest podać 8. Umożliwia to zapisanie 777 i uzyskanie poprawnej wartości ósemkowej. Przy podanej podstawie 0 łańcuch 777 jest dziesiętny (ponownie).


Dodatkowo:

  • Nie używaj 'niejawny int' typ zwracanej przez main(); jawnie, jak wymaga tego C99 i użyj int main(void) lub int main(int argc, char **argv).
  • Nie baw się, siekając końcowe znaki zerowe ze sznurka.

    char mode[4] = "0777"; 
    

    Zapobiega C przechowywania terminala null - źle! Użyj:

    char mode[] = "0777"; 
    

    Przydziela 5 bajtów potrzebnych do zapisania ciągu znaków z zakończeniem o wartości NULL.

  • Zgłoś błędy na stderr, a nie stdout.

  • Zgłoś błędy z nowym znakiem na końcu.
  • Dobrą praktyką jest umieszczenie nazwy programu i nazwy pliku w komunikacie o błędzie, a także (jak wskazano CJY), aby na wyjściu uwzględnić numer błędu systemowego i odpowiedni ciąg znaków. Wymaga to nagłówka <string.h> (dla strerror()) i dla errno. Ponadto status wyjścia programu powinien wskazywać awarię w przypadku niepowodzenia operacji chmod().

umieszczenie wszystkich zmian razem plony:

#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); 
} 

być ostrożnym z errno; może się zmienić po wywołaniu funkcji.Jest tutaj wystarczająco bezpieczny, ale w wielu sytuacjach warto przechwycić errno w zmienną lokalną i użyć zmiennej lokalnej w operacjach drukowania itp.

Należy również zauważyć, że kod nie sprawdza błędów w wyniku z strtol(). W tym kontekście jest wystarczająco bezpieczny; jeśli użytkownik podał wartość, byłoby złym pomysłem, aby zaufać im, aby to naprawić.


Ostatni komentarz: ogólnie nie powinieneś używać 777 uprawnień do plików (lub katalogów). W przypadku plików oznacza to, że nie masz nic przeciwko temu, kto zmodyfikuje twój program wykonywalny i jak. Zwykle tak nie jest; nie obchodzi cię (lub nie powinno), kto modyfikuje twoje programy. Zasadniczo nie wolno w ogóle wykonywać plików danych; kiedy pliki są wykonywalne, nie dają publicznego dostępu do zapisu i nie patrzą na askance przy dostępie do zapisu grupowego. W przypadku katalogów publiczne uprawnienie do zapisu oznacza, że ​​nie ma nic przeciwko temu, kto usunie dowolny plik z katalogu (lub doda pliki). Zdarza się, że czasami może to być poprawne ustawienie uprawnień, ale jest bardzo rzadko poprawne. (W przypadku katalogów zwykle dobrym pomysłem jest użycie "bitu" również: na przykład 1777 jest używane na przykład na /tmp, ale nie na MacOS X.)

+0

'strtoul' jest jeszcze lepszy, ponieważ kto poważnie stosuje tryb negatywny? :-P Ponadto, zgłaszaj błędy z włączonym 'errno', np. Używając' perror' lub 'strerror' (lub'% m' w ciągu znaków, jeśli używasz GNU libc). –

+0

Dzięki, działa świetnie. Jeszcze jedno dzięki za poprawienie błędów programowania. – Raghav

+0

Numeryczna wartość errno zwykle nie jest wyświetlana w komunikatach o błędach, ponieważ jest zbędna i może ujawniać niechciane informacje na temat typu systemu operacyjnego. – jilles

Powiązane problemy