2015-03-10 16 views
11

Widziałem niezliczone przykłady i samouczki, które pokazują, jak utworzyć plik i wszystkie z nich "oszukiwać", po prostu ustawiając bity uprawnień pliku. Chciałbym wiedzieć/dowiedzieć się, jak prawidłowo utworzyć plik os.FileMode, aby dostarczyć go podczas tworzenia/aktualizowania pliku.Golang poprawnie stwórz os.FileMode

Surowy przykładem jest to poniżej:

func FileWrite(path string, r io.Reader, uid, gid int, perms string) (int64, error){ 
    w, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0664) 
    if err != nil { 
     if path == "" { 
      w = os.Stdout 
     } else { 
      return 0, err 
     } 
    } 
    defer w.Close() 

    size, err := io.Copy(w, r) 

    if err != nil { 
     return 0, err 
    } 
    return size, err 
} 

W funkcji podstawowej powyżej 0664 bitów uprawnień jest ustawiona, a mimo to może mieć sens czasami wolę mieć odpowiedni sposób ustawiania FileMode poprawnie. Jak widać powyżej, typowym przykładem jest to, że identyfikator UID/GID jest znany i już dostarczony jako wartość int, a perms to cyfry ósemkowe, które zostały wcześniej zebrane i wstawione do db jako ciągu.

Odpowiedz

16

FileMode to tylko uint32. http://golang.org/pkg/os/#FileMode

Ustawienie za pomocą stałych nie "oszukuje", używa się go jak innych wartości numerycznych. Jeśli nie używasz stałą, można użyć konwersji na ważnych wartościach liczbowych:

mode := int(0777) 
os.FileMode(mode) 
+0

Dzięki Jim, zawsze pomocna! –

+3

O ile się nie mylę, nie jest to przydatne, jeśli próbujesz mieć jakieś pliki, które można zapisać, a inne nie. Można mieć lub na (na przykład) 0200, aby włączyć zapisywalny użytkownik, ale to ułatwiłoby odczyt kodu, gdyby istniała stała os o kontrolowaniu tego. Tak, oczekuję, że każdy programista warty swojej soli będzie znał pozwolenie na ośmiokrotne unix, ale wciąż jest złe programowanie do używania magicznej wartości, kiedy można użyć opisowej nazwy. O ile mogę powiedzieć, że brakuje standardowych bibliotek, to po prostu oczekuj, że wszyscy będą zapamiętywać stałe uprawnienia do pliku Unix. –

7

Moja poprawka została zdefiniować własne stałe, bo nie mógł znaleźć żadnego w OS lub syscall:

const (
     OS_READ = 04 
     OS_WRITE = 02 
     OS_EX = 01 
     OS_USER_SHIFT = 6 
     OS_GROUP_SHIFT = 3 
     OS_OTH_SHIFT = 0 

     OS_USER_R = OS_READ<<OS_USER_SHIFT 
     OS_USER_W = OS_WRITE<<OS_USER_SHIFT 
     OS_USER_X = OS_EX<<OS_USER_SHIFT 
     OS_USER_RW = OS_USER_R | OS_USER_W 
     OS_USER_RWX = OS_USER_RW | OS_USER_X 

     OS_GROUP_R = OS_READ<<OS_GROUP_SHIFT 
     OS_GROUP_W = OS_WRITE<<OS_GROUP_SHIFT 
     OS_GROUP_X = OS_EX<<OS_GROUP_SHIFT 
     OS_GROUP_RW = OS_GROUP_R | OS_GROUP_W 
     OS_GROUP_RWX = OS_GROUP_RW | OS_GROUP_X 

     OS_OTH_R = OS_READ<<OS_OTH_SHIFT 
     OS_OTH_W = OS_WRITE<<OS_OTH_SHIFT 
     OS_OTH_X = OS_EX<<OS_OTH_SHIFT 
     OS_OTH_RW = OS_OTH_R | OS_OTH_W 
     OS_OTH_RWX = OS_OTH_RW | OS_OTH_X 

     OS_ALL_R = OS_USER_R | OS_GROUP_R | OS_OTH_R 
     OS_ALL_W = OS_USER_W | OS_GROUP_W | OS_OTH_W 
     OS_ALL_X = OS_USER_X | OS_GROUP_X | OS_OTH_X 
     OS_ALL_RW = OS_ALL_R | OS_ALL_W 
     OS_ALL_RWX = OS_ALL_RW | OS_GROUP_X 
) 

to wtedy pozwala mi określić moją intencję bezpośrednio:

 // Create any directories needed to put this file in them 
     var dir_file_mode os.FileMode 
     dir_file_mode = os.ModeDir | (OS_USER_RWX | OS_ALL_R) 
     os.MkdirAll(dir_str, dir_file_mode) 

Jestem pewien, że to może być poprawiona przez zastosowanie jota, a niektóre więcej kombinacjach uprawnieniami, ale to działa na mnie teraz.

+1

Chris to jest naprawdę użyteczne, a fakt, że to dwuletnie i stare pytanie wciąż jest obserwowane/aktualizowane pokazuje, że stałe muszą być dostępne w stdlib. –