2016-11-04 3 views
2

J'essaie d'envelopper la fonction open. Je ne sais pas comment passer le troisième argument optionnel au vrai open. Si je comprends bien il n'y a aucun moyen de valider le va_list, donc le if (mode) n'est pas correct dans l'exemple ci-dessous. Y at-il un moyen d'appeler open avec le bon nombre d'arguments?Envelopper une fonction variadique

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdarg.h> 

extern "C" 
{ 

int shouldWrap = 0; 

int willCallRealOpen(const char * path, int flags, va_list args); 
int __real_open(const char * path, int flags, ...); 

int __wrap_open(const char * path, int flags, ...) { 
    if(shouldWrap != 0){ 
     printf("Fake called\n"); 
     return 0; 
    } 
    else { 
     printf("Real called\n"); 
     va_list args; 
      va_start(args, flags); 
      int res = willCallRealOpen(path, flags, args); 
     va_end(args); 
     return res; 
    } 
} 

int willCallRealOpen(const char * path, int flags, va_list args) { 
    mode_t mode = va_arg(args, mode_t); 
    if (mode) { 
     printf("3 args\n"); 
     return __real_open(path, flags, mode); 
    } 
    else { 
     printf("2 args\n"); 
     return __real_open(path, flags); 
    } 
} 

} 

int main() { 
    //int fd = open("temp.txt", O_CREAT | O_WRONLY, S_IRUSR); 
    int fd = open("temp.txt", O_CREAT | O_WRONLY); 
} 

Répondre

3

La page de manuel pour ouvrir dit: Mode

spécifie les permissions à utiliser dans le cas où un nouveau fichier est créé . Cet argument doit être fourni lorsque O_CREAT ou O_TMPFILE est spécifié dans flags; si ni O_CREAT ni O_TMPFILE n'est spécifié, alors le mode est ignoré.

Je pense que vous devriez faire quelque chose comme:

int willCallRealOpen(const char * path, int flags, va_list args) { 
    if (flags & (O_CREAT | O_TMPFILE)) 
    { 
    mode_t mode = va_arg(args, mode_t); 
    printf("3 args\n"); 
    return __real_open(path, flags, mode); 
    } 
    else { 
    printf("2 args\n"); 
    return __real_open(path, flags); 
    } 
}