Mercurial > vim
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(); |