mah454
mah454

Reputation: 1919

C++ JNI open /dev/rtc result invalid argument

I try to open /dev/rtc or /dev/rtc0 .

# ls -l /dev/rtc* 
lrwxrwxrwx 1 root root      4 Aug 11 05:59 /dev/rtc -> rtc0
crw------- 1 root root 248, 0 Aug 11 05:59 /dev/rtc0   

this is my JNI code (C++):

using namespace std; 

void get_system_dt(struct tm tm) {                                                                                                                                                                                                                                 
    time_t t = time(NULL);                                                                                                                                                                                                                                         
    tm = *localtime(&t) ;                                                                                                                                                                                                                                          
}                                                                                                                                                                                                                                                                  
   
int set_hardware_dt() {                                                                                                                                                                                                                                            
    struct tm tm ;                                                                                                                                                                                                                                              
    get_system_dt(tm);                                                                                                                                                                                                                                          
    struct rtc_time rt ;                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                   
    rt.tm_year = tm.tm_year ;                                                                                                                                                                                                                                   
    rt.tm_min = tm.tm_mon ;                                                                                                                                                                                                                                     
    rt.tm_yday = tm.tm_yday ;                                                                                                                                                                                                                                   
    rt.tm_mday = tm.tm_mday ;                                                                                                                                                                                                                                   
    rt.tm_hour = tm.tm_hour ;                                                                                                                                                                                                                                   
    rt.tm_wday = tm.tm_wday ;                                                                                                                                                                                                                                   
    rt.tm_min = tm.tm_min ;                                                                                                                                                                                                                                     
    rt.tm_sec = tm.tm_sec ;                                                                                                                                                                                                                                     
    rt.tm_isdst = tm.tm_isdst ;                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                   
    int fd = open ("/dev/rtc0",O_RDONLY); <-- Problem this line                                                                                                                                                                                                                          
    cout << fd << endl;                                                                                                                                                                                                                                            
    if (fd != 3) {                                                                                                                                                                                                                                              
        perror("SET_HW_DT");                                                                                                                                                                                                                                    
        return 1;                                                                                                                                                                                                                                               
    }                                                                                                                                                                                                                                                           
    int r = ioctl(fd,RTC_SET_TIME,&rt);    
    if (r != 0) {
        perror("ioctl");
        return 1;                                                                                                                                                                                                                                            
    }
    close(fd);                                                                                                                                                                                                                                                     
    return 0 ;                                                                                                                                                                                                                                                     
} 

JNIEXPORT void JNICALL Java_ir_moke_jsysbox_time_JDateTime_syncSystemToHardware (JNIEnv *env, jclass clazz) {                                                                                                                                                      
    int r = set_hardware_dt();                                                                                                                                                                                                                                     
    if (r != 0) throwException(env,"Failed to sync system to hardware");                                                                                                                                                                                           
} 

and this output :

6
SET_HW_DT: Invalid argument     

I can not understand why this code result Invalid argumnt !
that code with simple main do work without any problem :

int main(int argc, char *argv[])
{
        set_hardware_dt(); 
        return 0;
}

output : 
3
SET_HW_DT: Success

What is problem ?

Upvotes: 0

Views: 112

Answers (1)

Botje
Botje

Reputation: 30807

Your code has several problems. From top to bottom:

void get_system_dt(struct tm tm)

will never modify the tm you pass in in set_hardware_dt. You need to pass a struct tm& tm for that code to work.

Next, a typo:

rt.tm_min = tm.tm_mon ;                                                                                                                                                                                                                                     

Finally, your "problem this line" is not actually the problem. Instead, this line is:

if (fd != 3) {                                                                                                                                                                                                                                              

This assumes that the freshly-allocated file descriptor will be number 3. This is typically only the case in small programs that did not open or close any file descriptors before your code runs.

Instead, you should check whether fd is negative, as that is the error signal from open.

Upvotes: 2

Related Questions