Changeset fa18523 in mainline


Ignore:
Timestamp:
2012-04-25T11:31:10Z (12 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af7e3d3
Parents:
6a3808e
Message:

rtc: move tm_sanity check() from the rtc driver to the date application and make use of mktime() in the
rtc driver to normalize the content of the tm structure.

Location:
uspace
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/date/date.c

    r6a3808e rfa18523  
    4343static int read_time_from_arg(char *wdate, struct tm *t);
    4444static int read_num_from_str(char *str, size_t len, int *n);
     45static int tm_sanity_check(struct tm *t);
     46static bool is_leap_year(int year);
     47
    4548static void usage(void);
     49
     50static int days_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    4651
    4752int
     
    181186                }
    182187
     188                rc = tm_sanity_check(&t);
     189                if (rc != EOK) {
     190                        printf(NAME ": error, invalid date/time\n");
     191                        goto exit;
     192                }
     193
    183194                rc = clock_dev_time_set(sess, &t);
    184195                if (rc != EOK) {
     
    278289}
    279290
     291/** Check if the tm structure contains valid values
     292 *
     293 * @param t     The tm structure to check
     294 *
     295 * @return      EOK on success or EINVAL
     296 */
     297static int
     298tm_sanity_check(struct tm *t)
     299{
     300        int ndays;
     301
     302        if (t->tm_sec < 0 || t->tm_sec > 59)
     303                return EINVAL;
     304        else if (t->tm_min < 0 || t->tm_min > 59)
     305                return EINVAL;
     306        else if (t->tm_hour < 0 || t->tm_hour > 23)
     307                return EINVAL;
     308        else if (t->tm_mday < 1 || t->tm_mday > 31)
     309                return EINVAL;
     310        else if (t->tm_mon < 0 || t->tm_mon > 11)
     311                return EINVAL;
     312        else if (t->tm_year < 0 || t->tm_year > 199)
     313                return EINVAL;
     314
     315        if (t->tm_mon == 1/* FEB */ && is_leap_year(t->tm_year))
     316                ndays = 29;
     317        else
     318                ndays = days_month[t->tm_mon];
     319
     320        if (t->tm_mday > ndays)
     321                return EINVAL;
     322
     323        return EOK;
     324}
     325
     326/** Check if a year is a leap year
     327 *
     328 * @param year   The year to check
     329 *
     330 * @return       true if it is a leap year, false otherwise
     331 */
     332static bool
     333is_leap_year(int year)
     334{
     335        bool r = false;
     336
     337        if (year % 4 == 0) {
     338                if (year % 100 == 0)
     339                        r = year % 400 == 0;
     340                else
     341                        r = true;
     342        }
     343
     344        return r;
     345}
     346
    280347static void
    281348usage(void)
  • uspace/drv/time/cmos-rtc/cmos-rtc.c

    r6a3808e rfa18523  
    9090    ipc_callid_t callid, ipc_call_t *call);
    9191static int rtc_dev_remove(ddf_dev_t *dev);
    92 static int rtc_tm_sanity_check(struct tm *t, int epoch);
    9392static void rtc_register_write(rtc_t *rtc, int reg, int data);
    94 static bool is_leap_year(int year);
    95 
    96 static int days_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    9793
    9894static ddf_dev_ops_t rtc_dev_ops;
     
    287283        bool bcd_mode;
    288284        bool pm_mode = false;
    289         int  epoch = 1900;
    290285        rtc_t *rtc = RTC_FROM_FNODE(fun);
    291286
     
    352347                 * RTC epoch is 2000.
    353348                 */
    354                 epoch = 2000;
    355349                t->tm_year += 100;
    356350        }
     
    358352        fibril_mutex_unlock(&rtc->mutex);
    359353
    360         return rtc_tm_sanity_check(t, epoch);
     354        time_t r = mktime(t);
     355        if (r < 0)
     356                return EINVAL;
     357
     358        return EOK;
    361359}
    362360
     
    371369rtc_time_set(ddf_fun_t *fun, struct tm *t)
    372370{
    373         int  rc;
    374371        bool bcd_mode;
    375372        int  reg_b;
     
    378375        rtc_t *rtc = RTC_FROM_FNODE(fun);
    379376
     377        if (mktime(t) < 0)
     378                return EINVAL;
     379
    380380        fibril_mutex_lock(&rtc->mutex);
    381381
     
    386386                epoch = 1900;
    387387
    388         rc = rtc_tm_sanity_check(t, epoch);
    389         if (rc != EOK) {
     388        if (epoch == 2000 && t->tm_year < 100) {
     389                /* Can't set a year before the epoch */
    390390                fibril_mutex_unlock(&rtc->mutex);
    391                 return rc;
     391                return EINVAL;
    392392        }
    393393
     
    442442        fibril_mutex_unlock(&rtc->mutex);
    443443
    444         return rc;
    445 }
    446 
    447 /** Check if the tm structure contains valid values
    448  *
    449  * @param t     The tm structure to check
    450  * @param epoch The RTC epoch year
    451  *
    452  * @return      EOK on success or EINVAL
    453  */
    454 static int
    455 rtc_tm_sanity_check(struct tm *t, int epoch)
    456 {
    457         int ndays;
    458 
    459         if (t->tm_sec < 0 || t->tm_sec > 59)
    460                 return EINVAL;
    461         else if (t->tm_min < 0 || t->tm_min > 59)
    462                 return EINVAL;
    463         else if (t->tm_hour < 0 || t->tm_hour > 23)
    464                 return EINVAL;
    465         else if (t->tm_mday < 1 || t->tm_mday > 31)
    466                 return EINVAL;
    467         else if (t->tm_mon < 0 || t->tm_mon > 11)
    468                 return EINVAL;
    469         else if (epoch == 2000 && t->tm_year < 100)
    470                 return EINVAL;
    471         else if (t->tm_year < 0 || t->tm_year > 199)
    472                 return EINVAL;
    473 
    474         if (t->tm_mon == 1/* FEB */ && is_leap_year(t->tm_year))
    475                 ndays = 29;
    476         else
    477                 ndays = days_month[t->tm_mon];
    478 
    479         if (t->tm_mday > ndays)
    480                 return EINVAL;
    481 
    482444        return EOK;
    483 }
    484 
    485 /** Check if a year is a leap year
    486  *
    487  * @param year   The year to check
    488  *
    489  * @return       true if it is a leap year, false otherwise
    490  */
    491 static bool
    492 is_leap_year(int year)
    493 {
    494         bool r = false;
    495 
    496         if (year % 4 == 0) {
    497                 if (year % 100 == 0)
    498                         r = year % 400 == 0;
    499                 else
    500                         r = true;
    501         }
    502 
    503         return r;
    504445}
    505446
Note: See TracChangeset for help on using the changeset viewer.