2016-11-04 96 views
2

我想包裝open功能。我不知道如何將可選的第三個參數傳遞給真正的open。據我所知,沒有辦法驗證va_list,所以if (mode)是不正確的在他下面的例子。有沒有辦法用適當數量的參數調用open包裝可變功能

#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); 
} 

回答

3

的手冊頁開說:

模式指定權限的情況下,使用一個新的文件被創建 。當在標誌中指定O_CREAT或O_TMPFILE 時,必須提供此參數;如果既沒有指定O_CREAT也沒有指定O_TMPFILE,則 則忽略該模式。

所以我認爲你應該做的是這樣的:

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); 
    } 
}