Quindi, in pratica, quello che vuoi è avere un descrittore di file e in pratica aprire di nuovo lo stesso file per ottenere una posizione, condivisione, modalità, ecc. Separate. E vuoi farlo su Windows (dove il "descrittore di file" è fondamentalmente un oggetto estraneo, non qualcosa utilizzato direttamente dal sistema operativo o la libreria di runtime a tutti.
abbastanza sorprendentemente, c'è è un modo per farlo, almeno con MS VC++. Tutti tranne due passaggi utilizzano solo l'API Win32, quindi il porting su altri compilatori/librerie dovrebbe essere abbastanza ragionevole (penso che la maggior parte delle versioni di fornitura di queste due funzioni) .Questi sono per convertire un descrittore di file in stile Unix in un Win3 nativo L'handle di 2 file e la conversione di un file Win32 nativo vengono gestiti in un descrittore di file in stile Unix.
- Converti descrittori di file per file handle nativa con _get_osfhandle()
- ottenere un nome per il file con GetFileInformationByHandleEx (FILE_NAME_INFO)
- Usa CreateFile per aprire una nuova maniglia a tale file
- creare un descrittore di file per quella maniglia con _open_osfhandle()
Et voilà, abbiamo un nuovo descrittore di file riferimento suona allo stesso file, ma con le sue autorizzazioni, posizione, ecc.
Verso la fine della tua domanda, fai sembrare che tu voglia anche i "permessi", ma che non sembra fare alcun reale senso - le autorizzazioni si collegano al file stesso, non al modo in cui il file viene aperto, quindi l'apertura o la riapertura del file non ha alcun effetto sulle autorizzazioni del file. Se vuoi davvero conoscerlo, puoi ottenerlo con GetFileInformationByHandle, ma ricorda che i permessi dei file in Windows sono un po 'diversi dai permessi dei file (tradizionali) in Unix. Unix ha permessi di proprietario/gruppo/mondo su tutti i file, e molti sistemi hanno anche ACL (anche se ci sono più variazioni nel modo in cui funzionano). Windows non ha alcuna autorizzazione (ad es. File su FAT o FAT32) o usa ACL (ad es. File su NTFS), ma nulla che sia realmente equivalente ai permessi di proprietario/gruppo/mondo tradizionali a cui molte persone sono abituate su Unix.
Forse si sta utilizzando "autorizzazioni" per indicare se il file era aperto per la lettura, la scrittura o entrambi. Ottenere questo è considerevolmente più brutto di uno qualsiasi dei precedenti. Il problema è che la maggior parte di esso è nella libreria, non in Win32, quindi probabilmente non c'è modo di farlo che sia anche vicino al portatile tra i compilatori. Con MS VC++ 9.0 SP1 (non garantito per qualsiasi altro compilatore) si può fare questo:
#include <stdio.h>
int get_perms(int fd) {
int i;
FILE * base = __iob_func();
for (i=0; i<_IOB_ENTRIES; i++)
if (base[i]._file == fd)
return base[i]._flag; // we've found our file
return 0; // file wasn't found.
}
Dal momento che questo ha coinvolto alcuni speleologia, ho scritto un test rapido per verificare che potrebbe effettivamente funzionare:
#ifdef TEST
#include <io.h>
void show_perms(int perms, char const *caption) {
printf("File opened for %s\n", caption);
printf("Read permission = %d\n", (perms & _IOREAD)!=0);
printf("Write permission = %d\n", (perms & _IOWRT)!=0);
}
int main(int argc, char **argv) {
FILE *file1, *file2;
int perms1, perms2;
file1=fopen(argv[1], "w");
perms1 = get_perms(_fileno(file1));
fclose(file1);
file2=fopen(argv[1], "r");
perms2 = get_perms(_fileno(file2));
fclose(file2);
show_perms(perms1, "writing");
show_perms(perms2, "reading");
return 0;
}
#endif
e i risultati sembrano indicare il successo:
File opened for writing
Read permission = 0
Write permission = 1
File opened for reading
Read permission = 1
Write permission = 0
Sarà quindi possibile testare che ha restituito bandiera contro _IOREAD, _IOWRT, e _IORW, che sono definito in stdio.h. Nonostante i miei precedenti avvertimenti, dovrei probabilmente sottolineare che sospetto (anche se certamente non posso garantire) che questa parte della biblioteca sia abbastanza stabile, quindi le reali possibilità di grandi cambiamenti sono probabilmente abbastanza minime.
Nella direzione opposta, tuttavia, non c'è praticamente nessuna possibilità su tutti che funzionerà con qualsiasi altra libreria. Si può (ma certamente non è garantito) lavorare con gli altri compilatori che usano la libreria MS, come Intel, MinGW o Comeau che usano MS VC++ come back-end. Di quelli, direi che il più probabile a lavorare sarebbe Comeau, e il meno probabile MinGW (ma è solo una supposizione, c'è una buona possibilità che non funzioni con nessuno di loro).
- Richiede l'ridistribuibile Win32 FileID API Library
un'ottima risposta. Non ero a conoscenza del fatto che l'apertura di un file impediva che venisse scollegato o rinominato, anche se la piena condivisione era abilitata. ciò significa che il recupero del nome del file appartiene a un handle è perfettamente sicuro, in quanto non può cambiare fintanto che un descrittore di file o 'HANDLE' rimane aperto su quel percorso. –
Come posso fare lo stesso su Linux? grazie – alaamh
@alaamh: hai guardato tra le altre risposte? Un paio di loro parlano di come fare lo stesso genere di cose su Linux. –