Soy un principiante en la programación de Unix y C y tengo dos preguntas con respecto a struct stat y su campo st_mode :
Al acceder al campo st_mode como se muestra a continuación, ¿qué tipo de número se devuelve (octal, decimal, etc.)?
struct stat file; stat( someFilePath, &file); printf("%d", file.st_mode ); Pensé que el número estaba en octal, pero cuando ejecuté este código obtuve el valor 33188 . ¿Cuál es la base?
st_mode codifica un número binario de 16 bits que representa el tipo de archivo y los permisos del archivo. ¿Cómo obtengo el número de 16 bits de la salida anterior (especialmente cuando no parece estar en octal)? ¿Y qué partes del dígito de 16 bits codifican qué información?Gracias por cualquier ayuda.
Creo que estás mezclando conceptos aquí.
En la memoria, los valores enteros siempre están en binario, llamémoslo formato nativo . st_mode es de tipo mode_t y ese tipo es un tipo entero no especificado, probablemente int .
El concepto de base , que es decimal, octal o hexadecimal, es útil solo cuando convierte el número en memoria en formato nativo a una representación de texto (o viceversa).
Por ejemplo:
int x = 42; asigna el número 42 a la variable entera. Dado que el código fuente es texto, el 42 se ingresa como texto y sabemos que es un valor decimal (sin prefijo). Pero observe cómo no especificamos una base para la variable: no tiene una. Este otro código:
int x = 0x2A; es exactamente equivalente. En lugar de la constante decimal 42 , usa la constante hexadecimal 0x2A , pero es idéntica y x tiene el mismo valor en ambos casos. Igualmente:
int x = 052;también es equivalente, pero con una constante octal.
Ahora a tu código. Cuando tu lo hagas:
printf("%d", file.st_mode); 33188 le dices al programa que genere el valor de esa variable como un número decimal. Recuerde que printf convierte el número de formato nativo a texto, por lo que la base de ese texto es importante. Si prefiere ver el valor como octal, simplemente escriba:
printf("%o", file.st_mode); 100644O en hexadecimal:
printf("%x", file.st_mode); 81A4Lo bueno de octal es que representa exactamente 3 bits por dígito octal (4 bits por dígito para hexadecimal), así que con un poco de práctica puedes ver los bits sin cálculos.
Por ejemplo, su st_mode es 33188 en decimal o 0100644 en octal. El decimal no me dice nada, pero el octal si significa algo, porque recuerdo que los últimos 9 bits (3 dígitos octales) son los permisos: 3 bits para el dueño, 3 bits para el grupo, 3 bits para otros. Asi que:
* Owner: 6 that is rw- * Group: 4 that is r-- * Other: 4 that is r--Por cierto, el último 1 es esta constante:
#define S_IFREG 0100000eso solo significa que es un archivo normal.
El número es un conjunto a un valor. En printf() puede usar "%d" para imprimirlo en forma decimal (como lo hizo), o usar "%o" (o "%lo" ) para imprimirlo en forma octal.
Verifique la estadística del hombre 2 sobre cómo se representa cada información. Luego, puede usar una máscara de bits para extraer la información que necesita. Hay un ejemplo que lo demuestra en la página de manual.
Lo imprimiste como decimal, así que obtuviste decimal. Si lo hubiera impreso como octal, habría obtenido octal; ídem para hexadecimal.
El campo st_mode se entiende más fácilmente cuando se imprime como octal.
printf("mode = %07o\n", file.st_mode); Los últimos tres dígitos son los permisos familiares (644, por ejemplo) para chmod , etc. El cuarto dígito desde la derecha suele ser 0, pero no será cero para archivos o directorios set-UID, set-GID o sticky-bit. Los dígitos restantes identifican el tipo de archivo.
Puede usar las macros de <sys/stat.h> para diseccionar la información.