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.)
'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). –
Dzięki, działa świetnie. Jeszcze jedno dzięki za poprawienie błędów programowania. – Raghav
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