J'ai vu d'innombrables exemples et tutoriels qui montrent comment créer un fichier et tous "tricher" en définissant simplement les bits d'autorisation du fichier. Je voudrais savoir/découvrir comment instancier correctement os.FileMode à fournir à un écrivain lors de la création/mise à jour d'un fichier.
Voici un exemple grossier:
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
}
Dans la fonction de base ci-dessus, les bits d'autorisation 0664 sont définis et bien que cela puisse avoir du sens, je préfère parfois avoir un moyen approprié de définir correctement le mode de fichier. Comme vu ci-dessus, un exemple courant serait que l'UID/GID est connu et déjà fourni en tant que valeurs int et les perms étant des chiffres octaux qui ont été précédemment rassemblés et insérés dans une base de données sous forme de chaîne.
FileMode
n'est qu'un uint32. http://golang.org/pkg/os/#FileMode
La définition via des constantes n'est pas de la "tricherie", vous l'utilisez comme les autres valeurs numériques. Si vous n'utilisez pas de constante, vous pouvez utiliser une conversion sur des valeurs numériques valides:
mode := int(0777)
os.FileMode(mode)
Mon correctif a été de définir mes propres constantes car je n'en ai trouvé aucune dans os ou 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
)
Cela me permet alors de spécifier directement mon intention:
// 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)
Je suis sûr que cela pourrait être amélioré en utilisant iota et quelques autres combinaisons d'autorisations, mais cela fonctionne pour moi pour l'instant.