diff options
-rw-r--r-- | src/apoint.c | 29 | ||||
-rw-r--r-- | src/args.c | 10 | ||||
-rw-r--r-- | src/calcurse.h | 23 | ||||
-rw-r--r-- | src/calendar.c | 70 | ||||
-rw-r--r-- | src/event.c | 13 | ||||
-rw-r--r-- | src/interaction.c | 12 | ||||
-rw-r--r-- | src/io.c | 30 | ||||
-rw-r--r-- | src/notify.c | 14 | ||||
-rw-r--r-- | src/pcal.c | 2 | ||||
-rw-r--r-- | src/recur.c | 54 | ||||
-rw-r--r-- | src/utils.c | 81 | ||||
-rw-r--r-- | src/wins.c | 66 |
12 files changed, 244 insertions, 160 deletions
diff --git a/src/apoint.c b/src/apoint.c index 9860038..a756fac 100644 --- a/src/apoint.c +++ b/src/apoint.c @@ -137,39 +137,39 @@ unsigned apoint_inday(struct apoint *i, long *start) void apoint_sec2str(struct apoint *o, long day, char *start, char *end) { - struct tm *lt; + struct tm lt; time_t t; if (o->start < day) strncpy(start, "..:..", 6); else { t = o->start; - lt = localtime(&t); - snprintf(start, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, lt->tm_min); + localtime_r(&t, <); + snprintf(start, HRMIN_SIZE, "%02u:%02u", lt.tm_hour, lt.tm_min); } if (o->start + o->dur > day + DAYINSEC) strncpy(end, "..:..", 6); else { t = o->start + o->dur; - lt = localtime(&t); - snprintf(end, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, lt->tm_min); + localtime_r(&t, <); + snprintf(end, HRMIN_SIZE, "%02u:%02u", lt.tm_hour, lt.tm_min); } } void apoint_write(struct apoint *o, FILE * f) { - struct tm *lt; + struct tm lt; time_t t; t = o->start; - lt = localtime(&t); - fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt->tm_mon + 1, lt->tm_mday, - 1900 + lt->tm_year, lt->tm_hour, lt->tm_min); + localtime_r(&t, <); + fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt.tm_mon + 1, lt.tm_mday, + 1900 + lt.tm_year, lt.tm_hour, lt.tm_min); t = o->start + o->dur; - lt = localtime(&t); - fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u ", lt->tm_mon + 1, lt->tm_mday, - 1900 + lt->tm_year, lt->tm_hour, lt->tm_min); + localtime_r(&t, <); + fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u ", lt.tm_mon + 1, lt.tm_mday, + 1900 + lt.tm_year, lt.tm_hour, lt.tm_min); if (o->note != NULL) fprintf(f, ">%s ", o->note); @@ -186,10 +186,7 @@ struct apoint *apoint_scan(FILE * f, struct tm start, struct tm end, char state, char *note) { char buf[BUFSIZ], *newline; - time_t tstart, tend, t; - - t = time(NULL); - localtime(&t); + time_t tstart, tend; /* Read the appointment description */ if (!fgets(buf, sizeof buf, f)) @@ -270,11 +270,11 @@ static void arg_print_date(long date) { char date_str[BUFSIZ]; time_t t; - struct tm *lt; + struct tm lt; t = date; - lt = localtime(&t); - strftime(date_str, BUFSIZ, conf.output_datefmt, lt); + localtime_r(&t, <); + strftime(date_str, BUFSIZ, conf.output_datefmt, <); fputs(date_str, stdout); fputs(":\n", stdout); } @@ -366,7 +366,7 @@ date_arg(const char *ddate, int add_line, const char *fmt_apt, * to format the output correctly. */ timer = time(NULL); - t = *localtime(&timer); + localtime_r(&timer, &t); display_app(&t, numdays, add_line, fmt_apt, fmt_rapt, fmt_ev, fmt_rev, regex); } else { /* a date was entered */ @@ -412,7 +412,7 @@ date_arg_extended(const char *startday, const char *range, int add_line, numdays = atoi(range); } timer = time(NULL); - t = *localtime(&timer); + localtime_r(&timer, &t); if (startday != NULL) { if (parse_date(startday, conf.input_datefmt, (int *)&t.tm_year, (int *)&t.tm_mon, (int *)&t.tm_mday, NULL)) { diff --git a/src/calcurse.h b/src/calcurse.h index 191dbfd..6a6deaf 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -465,6 +465,22 @@ enum win { #define FLAG_STA (1 << STA) #define FLAG_ALL ((1 << NBWINS) - 1) +#define WINS_NBAR_LOCK \ + pthread_cleanup_push(wins_nbar_cleanup, NULL); \ + wins_nbar_lock(); + +#define WINS_NBAR_UNLOCK \ + wins_nbar_unlock(); \ + pthread_cleanup_pop(0); + +#define WINS_CALENDAR_LOCK \ + pthread_cleanup_push(wins_calendar_cleanup, NULL); \ + wins_calendar_lock(); + +#define WINS_CALENDAR_UNLOCK \ + wins_calendar_unlock(); \ + pthread_cleanup_pop(0); + enum ui_mode { UI_CURSES, UI_CMDLINE, @@ -581,7 +597,6 @@ enum export_type { /* To customize the display when saving data. */ enum save_display { IO_SAVE_DISPLAY_BAR, - IO_SAVE_DISPLAY_MARK, IO_SAVE_DISPLAY_NONE }; @@ -999,6 +1014,12 @@ void vars_init(void); /* wins.c */ extern struct window win[NBWINS]; +unsigned wins_nbar_lock(void); +void wins_nbar_unlock(void); +void wins_nbar_cleanup(void *); +unsigned wins_calendar_lock(void); +void wins_calendar_unlock(void); +void wins_calendar_cleanup(void *); int wins_refresh(void); int wins_wrefresh(WINDOW *); int wins_doupdate(void); diff --git a/src/calendar.c b/src/calendar.c index 61e758b..3d7698e 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -144,15 +144,15 @@ void calendar_stop_date_thread(void) void calendar_set_current_date(void) { time_t timer; - struct tm *tm; + struct tm tm; timer = time(NULL); - tm = localtime(&timer); + localtime_r(&timer, &tm); pthread_mutex_lock(&date_thread_mutex); - today.dd = tm->tm_mday; - today.mm = tm->tm_mon + 1; - today.yyyy = tm->tm_year + 1900; + today.dd = tm.tm_mday; + today.mm = tm.tm_mon + 1; + today.yyyy = tm.tm_year + 1900; pthread_mutex_unlock(&date_thread_mutex); } @@ -306,6 +306,7 @@ draw_monthly_view(struct window *cwin, struct date *current_day, c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L); /* Write the current month and year on top of the calendar */ + WINS_CALENDAR_LOCK; custom_apply_attr(cwin->p, ATTR_HIGHEST); mvwprintw(cwin->p, ofs_y, (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2, @@ -319,6 +320,7 @@ draw_monthly_view(struct window *cwin, struct date *current_day, mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first])); } custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; @@ -348,11 +350,12 @@ draw_monthly_view(struct window *cwin, struct date *current_day, ofs_x = OFFX - day_1_sav - 4 * c_day; } - /* This is today, so print it in yellow. */ + WINS_CALENDAR_LOCK; if (c_day == current_day->dd && current_day->mm == slctd_day.mm && current_day->yyyy == slctd_day.yyyy && current_day->dd != slctd_day.dd) { + /* This is today, so print it in yellow. */ custom_apply_attr(cwin->p, ATTR_LOWEST); mvwprintw(cwin->p, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); @@ -368,10 +371,12 @@ draw_monthly_view(struct window *cwin, struct date *current_day, mvwprintw(cwin->p, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); custom_remove_attr(cwin->p, ATTR_LOW); - } else + } else { /* otherwise, print normal days in black */ mvwprintw(cwin->p, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); + } + WINS_CALENDAR_UNLOCK; } monthly_view_cache_valid = 1; @@ -477,9 +482,11 @@ draw_weekly_view(struct window *cwin, struct date *current_day, /* Print the week number. */ weeknum = ISO8601weeknum(&t); + WINS_CALENDAR_LOCK; custom_apply_attr(cwin->p, ATTR_HIGHEST); mvwprintw(cwin->p, 2, cwin->w - 9, "(# %02d)", weeknum); custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; /* Now draw calendar view. */ for (j = 0; j < WEEKINDAYS; j++) { @@ -511,22 +518,28 @@ draw_weekly_view(struct window *cwin, struct date *current_day, else attr = 0; + WINS_CALENDAR_LOCK; if (attr) custom_apply_attr(cwin->p, attr); mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday); if (attr) custom_remove_attr(cwin->p, attr); + WINS_CALENDAR_UNLOCK; /* Draw slices indicating appointment times. */ memset(slices, 0, DAYSLICESNO * sizeof *slices); if (day_chk_busy_slices(date, DAYSLICESNO, slices)) { for (i = 0; i < DAYSLICESNO; i++) { - if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) + if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) { + WINS_CALENDAR_LOCK; mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2); + WINS_CALENDAR_UNLOCK; + } if (slices[i]) { int highlight; highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0; + WINS_CALENDAR_LOCK; if (highlight) custom_apply_attr(cwin->p, attr); wattron(cwin->p, A_REVERSE); @@ -535,6 +548,7 @@ draw_weekly_view(struct window *cwin, struct date *current_day, wattroff(cwin->p, A_REVERSE); if (highlight) custom_remove_attr(cwin->p, attr); + WINS_CALENDAR_UNLOCK; } } } @@ -544,11 +558,13 @@ draw_weekly_view(struct window *cwin, struct date *current_day, } /* Draw marks to indicate midday on the sides of the calendar. */ + WINS_CALENDAR_LOCK; custom_apply_attr(cwin->p, ATTR_HIGHEST); mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1); mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX + WCALWIDTH - 3, ACS_S9, 1); custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; #undef DAYSLICESNO } @@ -560,8 +576,12 @@ void calendar_update_panel(struct window *cwin) unsigned sunday_first; calendar_store_current_date(¤t_day); + + WINS_CALENDAR_LOCK; erase_window_part(cwin->p, 1, 3, cwin->w - 2, cwin->h - 2); mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2); + WINS_CALENDAR_UNLOCK; + sunday_first = calendar_week_begins_on_monday()? 0 : 1; draw_calendar[calendar_view] (cwin, ¤t_day, sunday_first); @@ -707,16 +727,16 @@ void calendar_move(enum move move, int count) long calendar_start_of_year(void) { time_t timer; - struct tm *tm; + struct tm tm; timer = time(NULL); - tm = localtime(&timer); - tm->tm_mon = 0; - tm->tm_mday = 1; - tm->tm_hour = 0; - tm->tm_min = 0; - tm->tm_sec = 0; - timer = mktime(tm); + localtime_r(&timer, &tm); + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + timer = mktime(&tm); return (long)timer; } @@ -724,17 +744,17 @@ long calendar_start_of_year(void) long calendar_end_of_year(void) { time_t timer; - struct tm *tm; + struct tm tm; timer = time(NULL); - tm = localtime(&timer); - tm->tm_mon = 0; - tm->tm_mday = 1; - tm->tm_hour = 0; - tm->tm_min = 0; - tm->tm_sec = 0; - tm->tm_year++; - timer = mktime(tm); + localtime_r(&timer, &tm); + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_year++; + timer = mktime(&tm); return (long)(timer - 1); } diff --git a/src/event.c b/src/event.c index 561c299..dca6820 100644 --- a/src/event.c +++ b/src/event.c @@ -107,13 +107,13 @@ unsigned event_inday(struct event *i, long *start) /* Write to file the event in user-friendly format */ void event_write(struct event *o, FILE * f) { - struct tm *lt; + struct tm lt; time_t t; t = o->day; - lt = localtime(&t); - fprintf(f, "%02u/%02u/%04u [%d] ", lt->tm_mon + 1, lt->tm_mday, - 1900 + lt->tm_year, o->id); + localtime_r(&t, <); + fprintf(f, "%02u/%02u/%04u [%d] ", lt.tm_mon + 1, lt.tm_mday, + 1900 + lt.tm_year, o->id); if (o->note != NULL) fprintf(f, ">%s ", o->note); fprintf(f, "%s\n", o->mesg); @@ -123,10 +123,7 @@ void event_write(struct event *o, FILE * f) struct event *event_scan(FILE * f, struct tm start, int id, char *note) { char buf[BUFSIZ], *nl; - time_t tstart, t; - - t = time(NULL); - localtime(&t); + time_t tstart; /* Read the event description */ if (!fgets(buf, sizeof buf, f)) diff --git a/src/interaction.c b/src/interaction.c index 2d6830e..635f78a 100644 --- a/src/interaction.c +++ b/src/interaction.c @@ -234,7 +234,7 @@ static void update_rept(struct rpt **rpt, const long start) newuntil = 0; date_entered = 1; } else { - struct tm *lt; + struct tm lt; time_t t; struct date new_date; int newmonth, newday, newyear; @@ -242,11 +242,11 @@ static void update_rept(struct rpt **rpt, const long start) if (parse_date(timstr, conf.input_datefmt, &newyear, &newmonth, &newday, calendar_get_slctd_day())) { t = start; - lt = localtime(&t); + localtime_r(&t, <); new_date.dd = newday; new_date.mm = newmonth; new_date.yyyy = newyear; - newuntil = date2sec(new_date, lt->tm_hour, lt->tm_min); + newuntil = date2sec(new_date, lt.tm_hour, lt.tm_min); if (newuntil < start) { status_mesg(msg_wrong_time, msg_enter); wgetch(win[STA].p); @@ -704,7 +704,7 @@ void interact_todo_pipe(void) */ void interact_day_item_repeat(void) { - struct tm *lt; + struct tm lt; time_t t; int date_entered = 0; int year = 0, month = 0, day = 0; @@ -789,11 +789,11 @@ void interact_day_item_repeat(void) if (parse_date(user_input, conf.input_datefmt, &year, &month, &day, calendar_get_slctd_day())) { t = p->start; - lt = localtime(&t); + localtime_r(&t, <); until_date.dd = day; until_date.mm = month; until_date.yyyy = year; - until = date2sec(until_date, lt->tm_hour, lt->tm_min); + until = date2sec(until_date, lt.tm_hour, lt.tm_min); if (until < p->start) { status_mesg(mesg_older, wrong_type_2); wgetch(win[STA].p); @@ -306,23 +306,6 @@ void io_extract_data(char *dst_data, const char *org, int len) *dst_data = '\0'; } -static void display_mark(void) -{ - const int DISPLAY_TIME = 1; - WINDOW *mwin; - - mwin = newwin(1, 2, 1, col - 3); - - custom_apply_attr(mwin, ATTR_HIGHEST); - mvwaddstr(mwin, 0, 0, "**"); - wins_wrefresh(mwin); - sleep(DISPLAY_TIME); - mvwaddstr(mwin, 0, 0, " "); - wins_wrefresh(mwin); - delwin(mwin); - wins_doupdate(); -} - static pthread_mutex_t io_save_mutex = PTHREAD_MUTEX_INITIALIZER; /* @@ -416,8 +399,6 @@ void io_save_cal(enum save_display display) if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_BAR && conf.progress_bar) show_bar = 1; - else if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_MARK) - display_mark(); if (show_bar) progress_bar(PROGRESS_BAR_SAVE, PROGRESS_BAR_CONF); @@ -440,8 +421,7 @@ void io_save_cal(enum save_display display) ERROR_MSG("%s", access_pb); /* Print a message telling data were saved */ - if (ui_mode == UI_CURSES && conf.system_dialogs - && display != IO_SAVE_DISPLAY_MARK) { + if (ui_mode == UI_CURSES && conf.system_dialogs) { status_mesg(save_success, enter); wgetch(win[STA].p); } @@ -458,7 +438,7 @@ void io_load_app(void) { FILE *data_file; int c, is_appointment, is_event, is_recursive; - struct tm start, end, until, *lt; + struct tm start, end, until, lt; llist_t exc; time_t t; int id = 0; @@ -467,8 +447,8 @@ void io_load_app(void) char note[MAX_NOTESIZ + 1], *notep; t = time(NULL); - lt = localtime(&t); - start = end = until = *lt; + localtime_r(&t, <); + start = end = until = lt; data_file = fopen(path_apts, "r"); EXIT_IF(data_file == NULL, _("failed to open appointment file")); @@ -1133,7 +1113,7 @@ static void *io_psave_thread(void *arg) for (;;) { sleep(delay * MININSEC); - io_save_cal(IO_SAVE_DISPLAY_MARK); + io_save_cal(IO_SAVE_DISPLAY_NONE); } } diff --git a/src/notify.c b/src/notify.c index a057c2f..ebc9728 100644 --- a/src/notify.c +++ b/src/notify.c @@ -240,11 +240,13 @@ void notify_update_bar(void) app_pos = file_pos + strlen(notify.apts_file) + 2 + space; txt_max_len = col - (app_pos + 12 + space); + WINS_NBAR_LOCK; custom_apply_attr(notify.win, ATTR_HIGHEST); wattron(notify.win, A_UNDERLINE | A_REVERSE); mvwhline(notify.win, 0, 0, ACS_HLINE, col); mvwprintw(notify.win, 0, date_pos, "[ %s | %s ]", notify.date, notify.time); mvwprintw(notify.win, 0, file_pos, "(%s)", notify.apts_file); + WINS_NBAR_UNLOCK; pthread_mutex_lock(¬ify_app.mutex); if (notify_app.got_app) { @@ -271,6 +273,7 @@ void notify_update_bar(void) else blinking = 0; + WINS_NBAR_LOCK; if (blinking) wattron(notify.win, A_BLINK); if (too_long) @@ -281,6 +284,7 @@ void notify_update_bar(void) hours_left, minutes_left, notify_app.txt); if (blinking) wattroff(notify.win, A_BLINK); + WINS_NBAR_UNLOCK; if (blinking) notify_launch_cmd(); @@ -295,8 +299,10 @@ void notify_update_bar(void) } pthread_mutex_unlock(¬ify_app.mutex); + WINS_NBAR_LOCK; wattroff(notify.win, A_UNDERLINE | A_REVERSE); custom_remove_attr(notify.win, ATTR_HIGHEST); + WINS_NBAR_UNLOCK; wins_wrefresh(notify.win); pthread_mutex_unlock(¬ify.mutex); @@ -310,18 +316,18 @@ static void *notify_main_thread(void *arg) const unsigned check_app = MININSEC; int elapse = 0; int got_app; - struct tm *ntime; + struct tm ntime; time_t ntimer; elapse = 0; for (;;) { ntimer = time(NULL); - ntime = localtime(&ntimer); + localtime_r(&ntimer, &ntime); pthread_mutex_lock(¬ify.mutex); pthread_mutex_lock(&nbar.mutex); - strftime(notify.time, NOTIFY_FIELD_LENGTH, nbar.timefmt, ntime); - strftime(notify.date, NOTIFY_FIELD_LENGTH, nbar.datefmt, ntime); + strftime(notify.time, NOTIFY_FIELD_LENGTH, nbar.timefmt, &ntime); + strftime(notify.date, NOTIFY_FIELD_LENGTH, nbar.datefmt, &ntime); pthread_mutex_unlock(&nbar.mutex); pthread_mutex_unlock(¬ify.mutex); notify_update_bar(); @@ -64,7 +64,7 @@ foreach_date_dump(const long date_end, struct rpt *rpt, llist_t * exc, time_t t; t = item_first_date; - lt = *localtime(&t); + localtime_r(&t, <); lt.tm_hour = lt.tm_min = lt.tm_sec = 0; lt.tm_isdst = -1; date = mktime(<); diff --git a/src/recur.c b/src/recur.c index 3338017..1c593c2 100644 --- a/src/recur.c +++ b/src/recur.c @@ -300,17 +300,17 @@ int recur_char2def(char type) static void recur_write_exc(llist_t * lexc, FILE * f) { llist_item_t *i; - struct tm *lt; + struct tm lt; time_t t; int st_mon, st_day, st_year; LLIST_FOREACH(lexc, i) { struct excp *exc = LLIST_GET_DATA(i); t = exc->st; - lt = localtime(&t); - st_mon = lt->tm_mon + 1; - st_day = lt->tm_mday; - st_year = lt->tm_year + 1900; + localtime_r(&t, <); + st_mon = lt.tm_mon + 1; + st_day = lt.tm_mday; + st_year = lt.tm_year + 1900; fprintf(f, " !%02u/%02u/%04u", st_mon, st_day, st_year); } } @@ -397,27 +397,27 @@ struct recur_event *recur_event_scan(FILE * f, struct tm start, int id, /* Writting of a recursive appointment into file. */ void recur_apoint_write(struct recur_apoint *o, FILE * f) { - struct tm *lt; + struct tm lt; time_t t; t = o->start; - lt = localtime(&t); - fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt->tm_mon + 1, lt->tm_mday, - 1900 + lt->tm_year, lt->tm_hour, lt->tm_min); + localtime_r(&t, <); + fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt.tm_mon + 1, lt.tm_mday, + 1900 + lt.tm_year, lt.tm_hour, lt.tm_min); t = o->start + o->dur; - lt = localtime(&t); - fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u", lt->tm_mon + 1, lt->tm_mday, - 1900 + lt->tm_year, lt->tm_hour, lt->tm_min); + localtime_r(&t, <); + fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u", lt.tm_mon + 1, lt.tm_mday, + 1900 + lt.tm_year, lt.tm_hour, lt.tm_min); t = o->rpt->until; if (t == 0) { /* We have an endless recurrent appointment. */ fprintf(f, " {%d%c", o->rpt->freq, recur_def2char(o->rpt->type)); } else { - lt = localtime(&t); + localtime_r(&t, <); fprintf(f, " {%d%c -> %02u/%02u/%04u", o->rpt->freq, - recur_def2char(o->rpt->type), lt->tm_mon + 1, lt->tm_mday, - 1900 + lt->tm_year); + recur_def2char(o->rpt->type), lt.tm_mon + 1, lt.tm_mday, + 1900 + lt.tm_year); } recur_write_exc(&o->exc, f); fputs("} ", f); @@ -433,25 +433,25 @@ void recur_apoint_write(struct recur_apoint *o, FILE * f) /* Writting of a recursive event into file. */ void recur_event_write(struct recur_event *o, FILE * f) { - struct tm *lt; + struct tm lt; time_t t; int st_mon, st_day, st_year; int end_mon, end_day, end_year; t = o->day; - lt = localtime(&t); - st_mon = lt->tm_mon + 1; - st_day = lt->tm_mday; - st_year = lt->tm_year + 1900; + localtime_r(&t, <); + st_mon = lt.tm_mon + 1; + st_day = lt.tm_mday; + st_year = lt.tm_year + 1900; t = o->rpt->until; if (t == 0) { /* We have an endless recurrent event. */ fprintf(f, "%02u/%02u/%04u [%d] {%d%c", st_mon, st_day, st_year, o->id, o->rpt->freq, recur_def2char(o->rpt->type)); } else { - lt = localtime(&t); - end_mon = lt->tm_mon + 1; - end_day = lt->tm_mday; - end_year = lt->tm_year + 1900; + localtime_r(&t, <); + end_mon = lt.tm_mon + 1; + end_day = lt.tm_mday; + end_year = lt.tm_year + 1900; fprintf(f, "%02u/%02u/%04u [%d] {%d%c -> %02u/%02u/%04u", st_mon, st_day, st_year, o->id, o->rpt->freq, recur_def2char(o->rpt->type), end_mon, end_day, end_year); @@ -563,10 +563,10 @@ recur_item_find_occurrence(long item_start, long item_dur, llist_t * item_exc, return 0; t = day_start; - lt_day = *localtime(&t); + localtime_r(&t, <_day); t = item_start; - lt_item = *localtime(&t); + localtime_r(&t, <_item); lt_item_day = lt_item; lt_item_day.tm_sec = lt_item_day.tm_min = lt_item_day.tm_hour = 0; @@ -614,7 +614,7 @@ recur_item_find_occurrence(long item_start, long item_dur, llist_t * item_exc, if (rpt_until != 0 && t > rpt_until) return 0; - lt_item_day = *localtime(&t); + localtime_r(&t, <_item_day); diff = diff_days(lt_item_day, lt_day); if (diff <= span) { diff --git a/src/utils.c b/src/utils.c index 2ca35de..60b0278 100644 --- a/src/utils.c +++ b/src/utils.c @@ -337,18 +337,26 @@ long get_item_time(long date) int get_item_hour(long date) { - return (localtime((time_t *) & date))->tm_hour; + struct tm lt; + + localtime_r((time_t *)&date, <); + return lt.tm_hour; } int get_item_min(long date) { - return (localtime((time_t *) & date))->tm_min; + struct tm lt; + + localtime_r((time_t *)&date, <); + return lt.tm_min; } long date2sec(struct date day, unsigned hour, unsigned min) { time_t t = now(); - struct tm start = *(localtime(&t)); + struct tm start; + + localtime_r(&t, &start); start.tm_mon = day.mm - 1; start.tm_mday = day.dd; @@ -367,14 +375,14 @@ long date2sec(struct date day, unsigned hour, unsigned min) /* Return a string containing the date, given a date in seconds. */ char *date_sec2date_str(long sec, const char *datefmt) { - struct tm *lt; + struct tm lt; char *datestr = (char *)mem_calloc(BUFSIZ, sizeof(char)); if (sec == 0) strncpy(datestr, "0", BUFSIZ); else { - lt = localtime((time_t *) & sec); - strftime(datestr, BUFSIZ, datefmt, lt); + localtime_r((time_t *)&sec, <); + strftime(datestr, BUFSIZ, datefmt, <); } return datestr; @@ -389,8 +397,9 @@ void date_sec2date_fmt(long sec, const char *fmt, char *datef) setlocale (LC_ALL, "C"); #endif - struct tm *lt = localtime((time_t *)&sec); - strftime(datef, BUFSIZ, fmt, lt); + struct tm lt; + localtime_r((time_t *)&sec, <); + strftime(datef, BUFSIZ, fmt, <); #if ENABLE_NLS setlocale (LC_ALL, locale_old); @@ -403,15 +412,15 @@ void date_sec2date_fmt(long sec, const char *fmt, char *datef) */ long date_sec_change(long date, int delta_month, int delta_day) { - struct tm *lt; + struct tm lt; time_t t; t = date; - lt = localtime(&t); - lt->tm_mon += delta_month; - lt->tm_mday += delta_day; - lt->tm_isdst = -1; - t = mktime(lt); + localtime_r(&t, <); + lt.tm_mon += delta_month; + lt.tm_mday += delta_day; + lt.tm_isdst = -1; + t = mktime(<); EXIT_IF(t == -1, _("failure in mktime")); return t; @@ -423,14 +432,14 @@ long date_sec_change(long date, int delta_month, int delta_day) */ long update_time_in_date(long date, unsigned hr, unsigned mn) { - struct tm *lt; + struct tm lt; time_t t, new_date; t = date; - lt = localtime(&t); - lt->tm_hour = hr; - lt->tm_min = mn; - new_date = mktime(lt); + localtime_r(&t, <); + lt.tm_hour = hr; + lt.tm_min = mn; + new_date = mktime(<); EXIT_IF(new_date == -1, _("error in mktime")); return new_date; @@ -442,7 +451,7 @@ long update_time_in_date(long date, unsigned hr, unsigned mn) */ long get_sec_date(struct date date) { - struct tm *ptrtime; + struct tm ptrtime; time_t timer; long long_date; char current_day[] = "dd "; @@ -451,10 +460,10 @@ long get_sec_date(struct date date) if (date.yyyy == 0 && date.mm == 0 && date.dd == 0) { timer = time(NULL); - ptrtime = localtime(&timer); - strftime(current_day, strlen(current_day), "%d", ptrtime); - strftime(current_month, strlen(current_month), "%m", ptrtime); - strftime(current_year, strlen(current_year), "%Y", ptrtime); + localtime_r(&timer, &ptrtime); + strftime(current_day, strlen(current_day), "%d", &ptrtime); + strftime(current_month, strlen(current_month), "%m", &ptrtime); + strftime(current_year, strlen(current_year), "%Y", &ptrtime); date.mm = atoi(current_month); date.dd = atoi(current_day); date.yyyy = atoi(current_year); @@ -518,16 +527,16 @@ item_in_popup(const char *a_start, const char *a_end, const char *msg, /* Returns the beginning of current day in seconds from 1900. */ long get_today(void) { - struct tm *lt; + struct tm lt; time_t current_time; long current_day; struct date day; current_time = time(NULL); - lt = localtime(¤t_time); - day.mm = lt->tm_mon + 1; - day.dd = lt->tm_mday; - day.yyyy = lt->tm_year + 1900; + localtime_r(¤t_time, <); + day.mm = lt.tm_mon + 1; + day.dd = lt.tm_mday; + day.yyyy = lt.tm_year + 1900; current_day = date2sec(day, 0, 0); return current_day; @@ -541,10 +550,12 @@ long now(void) char *nowstr(void) { + struct tm lt; static char buf[BUFSIZ]; time_t t = now(); - strftime(buf, sizeof buf, "%a %b %d %T %Y", localtime(&t)); + localtime_r(&t, <); + strftime(buf, sizeof buf, "%a %b %d %T %Y", <); return buf; } @@ -1185,15 +1196,17 @@ static void print_date(long date, long day, const char *extformat) printf("%ld", date); else { time_t t = date; - struct tm *lt = localtime((time_t *) & t); + struct tm lt; + + localtime_r((time_t *)&t, <); if (extformat[0] == '\0' || !strcmp(extformat, "default")) { if (date >= day && date <= day + DAYINSEC) - strftime(buf, BUFSIZ, "%H:%M", lt); + strftime(buf, BUFSIZ, "%H:%M", <); else - strftime(buf, BUFSIZ, "..:..", lt); + strftime(buf, BUFSIZ, "..:..", <); } else { - strftime(buf, BUFSIZ, extformat, lt); + strftime(buf, BUFSIZ, extformat, <); } printf("%s", buf); @@ -40,6 +40,14 @@ #include "calcurse.h" +#define SCREEN_ACQUIRE \ + pthread_cleanup_push(screen_cleanup, (void *)NULL); \ + screen_acquire(); + +#define SCREEN_RELEASE \ + screen_release(); \ + pthread_cleanup_pop(0); + /* Variables to handle calcurse windows. */ struct window win[NBWINS]; @@ -76,14 +84,54 @@ static void screen_release(void) pthread_mutex_unlock(&screen_mutex); } +static void screen_cleanup(void *arg) +{ + screen_release(); +} + +/* + * FIXME: The following functions currently lock the whole screen. Use both + * window-level and screen-level mutexes (or use use_screen() and use_window(), + * see curs_threads(3)) to avoid locking too much. + */ + +unsigned wins_nbar_lock(void) +{ + return screen_acquire(); +} + +void wins_nbar_unlock(void) +{ + screen_release(); +} + +void wins_nbar_cleanup(void *arg) +{ + wins_nbar_unlock(); +} + +unsigned wins_calendar_lock(void) +{ + return screen_acquire(); +} + +void wins_calendar_unlock(void) +{ + screen_release(); +} + +void wins_calendar_cleanup(void *arg) +{ + wins_calendar_unlock(); +} + int wins_refresh(void) { int rc; - if (!screen_acquire()) - return ERR; + SCREEN_ACQUIRE; rc = refresh(); - screen_release(); + SCREEN_RELEASE; return rc; } @@ -92,10 +140,11 @@ int wins_wrefresh(WINDOW * win) { int rc; - if (!win || !screen_acquire()) + if (!win) return ERR; + SCREEN_ACQUIRE; rc = wrefresh(win); - screen_release(); + SCREEN_RELEASE; return rc; } @@ -104,10 +153,9 @@ int wins_doupdate(void) { int rc; - if (!screen_acquire()) - return ERR; + SCREEN_ACQUIRE; rc = doupdate(); - screen_release(); + SCREEN_RELEASE; return rc; } @@ -475,10 +523,12 @@ static void border_nocolor(WINDOW * window) void wins_update_border(int flags) { if (flags & FLAG_CAL) { + WINS_CALENDAR_LOCK; if (slctd_win == CAL) border_color(win[CAL].p); else border_nocolor(win[CAL].p); + WINS_CALENDAR_UNLOCK; } if (flags & FLAG_APP) { if (slctd_win == APP) |