comparison src/os_unix.c @ 29245:b12fd2b3be63 v8.2.5141

patch 8.2.5141: using "volatile int" in a signal handler might be wrong Commit: https://github.com/vim/vim/commit/155f2d1451949d1124bfd6ba9c55be6bd74bab75 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jun 20 13:38:33 2022 +0100 patch 8.2.5141: using "volatile int" in a signal handler might be wrong Problem: Using "volatile int" in a signal handler might be wrong. Solution: Use "volatile sig_atomic_t".
author Bram Moolenaar <Bram@vim.org>
date Mon, 20 Jun 2022 14:45:03 +0200
parents c7aa0c46acd5
children 8175cd4c8fdd
comparison
equal deleted inserted replaced
29244:95a64cfeb60f 29245:b12fd2b3be63
8249 #if defined(FEAT_RELTIME) || defined(PROTO) 8249 #if defined(FEAT_RELTIME) || defined(PROTO)
8250 # if defined(HAVE_TIMER_CREATE) || defined(PROTO) 8250 # if defined(HAVE_TIMER_CREATE) || defined(PROTO)
8251 /* 8251 /*
8252 * Implement timeout with timer_create() and timer_settime(). 8252 * Implement timeout with timer_create() and timer_settime().
8253 */ 8253 */
8254 static volatile int timeout_flag = FALSE; 8254 static volatile sig_atomic_t timeout_flag = FALSE;
8255 static timer_t timer_id; 8255 static timer_t timer_id;
8256 static int timer_created = FALSE; 8256 static int timer_created = FALSE;
8257 8257
8258 /* 8258 /*
8259 * Callback for when the timer expires. 8259 * Callback for when the timer expires.
8260 */ 8260 */
8261 static void 8261 static void
8294 * safely dereferenced. 8294 * safely dereferenced.
8295 * 8295 *
8296 * This function is not expected to fail, but if it does it will still return a 8296 * This function is not expected to fail, but if it does it will still return a
8297 * valid flag pointer; the flag will remain stuck as FALSE . 8297 * valid flag pointer; the flag will remain stuck as FALSE .
8298 */ 8298 */
8299 volatile int * 8299 volatile sig_atomic_t *
8300 start_timeout(long msec) 8300 start_timeout(long msec)
8301 { 8301 {
8302 struct itimerspec interval = { 8302 struct itimerspec interval = {
8303 {0, 0}, // Do not repeat. 8303 {0, 0}, // Do not repeat.
8304 {msec / 1000, (msec % 1000) * 1000000}}; // Timeout interval 8304 {msec / 1000, (msec % 1000) * 1000000}}; // Timeout interval
8345 timer_delete(timer_id); 8345 timer_delete(timer_id);
8346 timer_created = FALSE; 8346 timer_created = FALSE;
8347 } 8347 }
8348 } 8348 }
8349 8349
8350 # else 8350 # else // HAVE_TIMER_CREATE
8351 8351
8352 /* 8352 /*
8353 * Implement timeout with setitimer() 8353 * Implement timeout with setitimer()
8354 */ 8354 */
8355 static struct itimerval prev_interval; 8355 static struct sigaction prev_sigaction;
8356 static struct sigaction prev_sigaction; 8356 static volatile sig_atomic_t timeout_flag = FALSE;
8357 static volatile int timeout_flag = FALSE; 8357 static int timer_active = FALSE;
8358 static int timer_active = FALSE; 8358 static int timer_handler_active = FALSE;
8359 static int timer_handler_active = FALSE; 8359 static volatile sig_atomic_t alarm_pending = FALSE;
8360 static int alarm_pending = FALSE;
8361 8360
8362 /* 8361 /*
8363 * Handle SIGALRM for a timeout. 8362 * Handle SIGALRM for a timeout.
8364 */ 8363 */
8365 static void 8364 static void
8381 int ret; 8380 int ret;
8382 8381
8383 if (timer_active) 8382 if (timer_active)
8384 { 8383 {
8385 timer_active = FALSE; 8384 timer_active = FALSE;
8386 ret = setitimer(ITIMER_REAL, &disarm, &prev_interval); 8385 ret = setitimer(ITIMER_REAL, &disarm, NULL);
8387 if (ret < 0) 8386 if (ret < 0)
8388 // Should only get here as a result of coding errors. 8387 // Should only get here as a result of coding errors.
8389 semsg(_(e_could_not_clear_timeout_str), strerror(errno)); 8388 semsg(_(e_could_not_clear_timeout_str), strerror(errno));
8390 } 8389 }
8391 8390
8396 if (ret < 0) 8395 if (ret < 0)
8397 // Should only get here as a result of coding errors. 8396 // Should only get here as a result of coding errors.
8398 semsg(_(e_could_not_reset_handler_for_timeout_str), 8397 semsg(_(e_could_not_reset_handler_for_timeout_str),
8399 strerror(errno)); 8398 strerror(errno));
8400 } 8399 }
8401 timeout_flag = 0; 8400 timeout_flag = FALSE;
8402 } 8401 }
8403 8402
8404 /* 8403 /*
8405 * Start the timeout timer. 8404 * Start the timeout timer.
8406 * 8405 *
8410 * safely dereferenced. 8409 * safely dereferenced.
8411 * 8410 *
8412 * This function is not expected to fail, but if it does it will still return a 8411 * This function is not expected to fail, but if it does it will still return a
8413 * valid flag pointer; the flag will remain stuck as FALSE . 8412 * valid flag pointer; the flag will remain stuck as FALSE .
8414 */ 8413 */
8415 volatile int * 8414 volatile sig_atomic_t *
8416 start_timeout(long msec) 8415 start_timeout(long msec)
8417 { 8416 {
8418 struct itimerval interval = { 8417 struct itimerval interval = {
8419 {0, 0}, // Do not repeat. 8418 {0, 0}, // Do not repeat.
8420 {msec / 1000, (msec % 1000) * 1000}}; // Timeout interval 8419 {msec / 1000, (msec % 1000) * 1000}}; // Timeout interval
8459 return &timeout_flag; 8458 return &timeout_flag;
8460 } 8459 }
8461 timer_handler_active = TRUE; 8460 timer_handler_active = TRUE;
8462 8461
8463 // Set up the interval timer once the alarm handler is in place. 8462 // Set up the interval timer once the alarm handler is in place.
8464 ret = setitimer(ITIMER_REAL, &interval, &prev_interval); 8463 ret = setitimer(ITIMER_REAL, &interval, NULL);
8465 if (ret < 0) 8464 if (ret < 0)
8466 { 8465 {
8467 // Should only get here as a result of coding errors. 8466 // Should only get here as a result of coding errors.
8468 semsg(_(e_could_not_set_timeout_str), strerror(errno)); 8467 semsg(_(e_could_not_set_timeout_str), strerror(errno));
8469 stop_timeout(); 8468 stop_timeout();