diff options
| author | Joakim Verona | 2013-01-19 00:03:30 +0100 |
|---|---|---|
| committer | Joakim Verona | 2013-01-19 00:03:30 +0100 |
| commit | 19ea867b2ed4dca4e460d1f347a4ff39d31705f1 (patch) | |
| tree | fbc1bfd2714bd7fff8d3cb5d0d2295f6f8902c9d | |
| parent | 9206508b76f73ceeb87c72496d1c40cec83dac21 (diff) | |
| parent | b117094709e34befa5a9486584f870d3e84d8f38 (diff) | |
| download | emacs-19ea867b2ed4dca4e460d1f347a4ff39d31705f1.tar.gz emacs-19ea867b2ed4dca4e460d1f347a4ff39d31705f1.zip | |
auto upstream
| -rw-r--r-- | lisp/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 3 | ||||
| -rw-r--r-- | src/ChangeLog | 22 | ||||
| -rw-r--r-- | src/fileio.c | 218 |
4 files changed, 112 insertions, 135 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c2a58265ffd..0905c20381a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2013-01-18 Leo Liu <sdl.web@gmail.com> | ||
| 2 | |||
| 3 | * progmodes/js.el: Tweak autoload cookie for alias. | ||
| 4 | |||
| 1 | 2013-01-17 Michael Albinus <michael.albinus@gmx.de> | 5 | 2013-01-17 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 6 | ||
| 3 | * autorevert.el (auto-revert-notify-watch-descriptor): Make it | 7 | * autorevert.el (auto-revert-notify-watch-descriptor): Make it |
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 96e6039a8c2..5f76cb4bbc5 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el | |||
| @@ -3405,8 +3405,7 @@ If one hasn't been set, or if it's stale, prompt for a new one." | |||
| 3405 | ;; calls to syntax-propertize wherever it's really needed. | 3405 | ;; calls to syntax-propertize wherever it's really needed. |
| 3406 | (syntax-propertize (point-max))) | 3406 | (syntax-propertize (point-max))) |
| 3407 | 3407 | ||
| 3408 | ;;;###autoload | 3408 | ;;;###autoload (defalias 'javascript-mode 'js-mode) |
| 3409 | (defalias 'javascript-mode 'js-mode) | ||
| 3410 | 3409 | ||
| 3411 | (eval-after-load 'folding | 3410 | (eval-after-load 'folding |
| 3412 | '(when (fboundp 'folding-add-to-marks-list) | 3411 | '(when (fboundp 'folding-add-to-marks-list) |
diff --git a/src/ChangeLog b/src/ChangeLog index c85e0a789ea..a7b8ab7855b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,25 @@ | |||
| 1 | 2013-01-18 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Fix crash when inserting data from non-regular files. See | ||
| 4 | http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00406.html | ||
| 5 | for the error description produced by valgrind. | ||
| 6 | * fileio.c (read_non_regular): Rename to read_contents. | ||
| 7 | Free Lisp_Save_Value object used to pass parameters. | ||
| 8 | (read_non_regular_quit): Rename to read_contents_quit. | ||
| 9 | (Finsert_file_contents): Redesign internal file reading loop to adjust | ||
| 10 | gap and end positions after each read and so help make_gap to work | ||
| 11 | properly. Do not signal an I/O error too early and so do not leave | ||
| 12 | not yet decoded characters in a buffer, which was the reason of | ||
| 13 | redisplay crash. Use list2 to build return value. Adjust comments. | ||
| 14 | |||
| 15 | 2013-01-17 Paul Eggert <eggert@cs.ucla.edu> | ||
| 16 | |||
| 17 | Close a race when statting and reading files (Bug#13149). | ||
| 18 | * fileio.c (Finsert_file_contents): Use open+fstat, not stat+open. | ||
| 19 | This avoids a race if the file is renamed between stat and open. | ||
| 20 | This race is not the problem originally noted in Bug#13149; | ||
| 21 | see <http://bugs.gnu.org/13149#73> and later messages in the thread. | ||
| 22 | |||
| 1 | 2013-01-17 Dmitry Antipov <dmantipov@yandex.ru> | 23 | 2013-01-17 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 24 | ||
| 3 | * lisp.h (toplevel): Add comment about using Lisp_Save_Value | 25 | * lisp.h (toplevel): Add comment about using Lisp_Save_Value |
diff --git a/src/fileio.c b/src/fileio.c index 8d711e8e6bf..4c54fd822ae 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -3408,13 +3408,13 @@ decide_coding_unwind (Lisp_Object unwind_data) | |||
| 3408 | return Qnil; | 3408 | return Qnil; |
| 3409 | } | 3409 | } |
| 3410 | 3410 | ||
| 3411 | /* Read from a non-regular file. STATE is a Lisp_Save_Value | 3411 | /* Check quit and read from the file. STATE is a Lisp_Save_Value |
| 3412 | object where slot 0 is the file descriptor, slot 1 specifies | 3412 | object where slot 0 is the file descriptor, slot 1 specifies |
| 3413 | an offset to put the read bytes, and slot 2 is the maximum | 3413 | an offset to put the read bytes, and slot 2 is the maximum |
| 3414 | amount of bytes to read. Value is the number of bytes read. */ | 3414 | amount of bytes to read. Value is the number of bytes read. */ |
| 3415 | 3415 | ||
| 3416 | static Lisp_Object | 3416 | static Lisp_Object |
| 3417 | read_non_regular (Lisp_Object state) | 3417 | read_contents (Lisp_Object state) |
| 3418 | { | 3418 | { |
| 3419 | int nbytes; | 3419 | int nbytes; |
| 3420 | 3420 | ||
| @@ -3425,15 +3425,15 @@ read_non_regular (Lisp_Object state) | |||
| 3425 | + XSAVE_INTEGER (state, 1)), | 3425 | + XSAVE_INTEGER (state, 1)), |
| 3426 | XSAVE_INTEGER (state, 2)); | 3426 | XSAVE_INTEGER (state, 2)); |
| 3427 | immediate_quit = 0; | 3427 | immediate_quit = 0; |
| 3428 | /* Fast recycle this object for the likely next call. */ | ||
| 3429 | free_misc (state); | ||
| 3428 | return make_number (nbytes); | 3430 | return make_number (nbytes); |
| 3429 | } | 3431 | } |
| 3430 | 3432 | ||
| 3431 | 3433 | /* Condition-case handler used when reading files in insert-file-contents. */ | |
| 3432 | /* Condition-case handler used when reading from non-regular files | ||
| 3433 | in insert-file-contents. */ | ||
| 3434 | 3434 | ||
| 3435 | static Lisp_Object | 3435 | static Lisp_Object |
| 3436 | read_non_regular_quit (Lisp_Object ignore) | 3436 | read_contents_quit (Lisp_Object ignore) |
| 3437 | { | 3437 | { |
| 3438 | return Qnil; | 3438 | return Qnil; |
| 3439 | } | 3439 | } |
| @@ -3492,7 +3492,6 @@ by calling `format-decode', which see. */) | |||
| 3492 | (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) | 3492 | (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) |
| 3493 | { | 3493 | { |
| 3494 | struct stat st; | 3494 | struct stat st; |
| 3495 | int file_status; | ||
| 3496 | EMACS_TIME mtime; | 3495 | EMACS_TIME mtime; |
| 3497 | int fd; | 3496 | int fd; |
| 3498 | ptrdiff_t inserted = 0; | 3497 | ptrdiff_t inserted = 0; |
| @@ -3506,7 +3505,7 @@ by calling `format-decode', which see. */) | |||
| 3506 | Lisp_Object p; | 3505 | Lisp_Object p; |
| 3507 | ptrdiff_t total = 0; | 3506 | ptrdiff_t total = 0; |
| 3508 | bool not_regular = 0; | 3507 | bool not_regular = 0; |
| 3509 | int save_errno = 0; | 3508 | int save_errno = 0, read_errno = 0; |
| 3510 | char read_buf[READ_BUF_SIZE]; | 3509 | char read_buf[READ_BUF_SIZE]; |
| 3511 | struct coding_system coding; | 3510 | struct coding_system coding; |
| 3512 | char buffer[1 << 14]; | 3511 | char buffer[1 << 14]; |
| @@ -3554,26 +3553,9 @@ by calling `format-decode', which see. */) | |||
| 3554 | orig_filename = filename; | 3553 | orig_filename = filename; |
| 3555 | filename = ENCODE_FILE (filename); | 3554 | filename = ENCODE_FILE (filename); |
| 3556 | 3555 | ||
| 3557 | fd = -1; | 3556 | fd = emacs_open (SSDATA (filename), O_RDONLY, 0); |
| 3558 | 3557 | if (fd < 0) | |
| 3559 | #ifdef WINDOWSNT | ||
| 3560 | { | ||
| 3561 | Lisp_Object tem = Vw32_get_true_file_attributes; | ||
| 3562 | |||
| 3563 | /* Tell stat to use expensive method to get accurate info. */ | ||
| 3564 | Vw32_get_true_file_attributes = Qt; | ||
| 3565 | file_status = stat (SSDATA (filename), &st); | ||
| 3566 | Vw32_get_true_file_attributes = tem; | ||
| 3567 | } | ||
| 3568 | #else | ||
| 3569 | file_status = stat (SSDATA (filename), &st); | ||
| 3570 | #endif /* WINDOWSNT */ | ||
| 3571 | |||
| 3572 | if (file_status == 0) | ||
| 3573 | mtime = get_stat_mtime (&st); | ||
| 3574 | else | ||
| 3575 | { | 3558 | { |
| 3576 | badopen: | ||
| 3577 | save_errno = errno; | 3559 | save_errno = errno; |
| 3578 | if (NILP (visit)) | 3560 | if (NILP (visit)) |
| 3579 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); | 3561 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); |
| @@ -3585,6 +3567,17 @@ by calling `format-decode', which see. */) | |||
| 3585 | goto notfound; | 3567 | goto notfound; |
| 3586 | } | 3568 | } |
| 3587 | 3569 | ||
| 3570 | /* Replacement should preserve point as it preserves markers. */ | ||
| 3571 | if (!NILP (replace)) | ||
| 3572 | record_unwind_protect (restore_point_unwind, Fpoint_marker ()); | ||
| 3573 | |||
| 3574 | record_unwind_protect (close_file_unwind, make_number (fd)); | ||
| 3575 | |||
| 3576 | if (fstat (fd, &st) != 0) | ||
| 3577 | report_file_error ("Getting input file status", | ||
| 3578 | Fcons (orig_filename, Qnil)); | ||
| 3579 | mtime = get_stat_mtime (&st); | ||
| 3580 | |||
| 3588 | /* This code will need to be changed in order to work on named | 3581 | /* This code will need to be changed in order to work on named |
| 3589 | pipes, and it's probably just not worth it. So we should at | 3582 | pipes, and it's probably just not worth it. So we should at |
| 3590 | least signal an error. */ | 3583 | least signal an error. */ |
| @@ -3600,17 +3593,6 @@ by calling `format-decode', which see. */) | |||
| 3600 | build_string ("not a regular file"), orig_filename); | 3593 | build_string ("not a regular file"), orig_filename); |
| 3601 | } | 3594 | } |
| 3602 | 3595 | ||
| 3603 | if (fd < 0) | ||
| 3604 | if ((fd = emacs_open (SSDATA (filename), O_RDONLY, 0)) < 0) | ||
| 3605 | goto badopen; | ||
| 3606 | |||
| 3607 | /* Replacement should preserve point as it preserves markers. */ | ||
| 3608 | if (!NILP (replace)) | ||
| 3609 | record_unwind_protect (restore_point_unwind, Fpoint_marker ()); | ||
| 3610 | |||
| 3611 | record_unwind_protect (close_file_unwind, make_number (fd)); | ||
| 3612 | |||
| 3613 | |||
| 3614 | if (!NILP (visit)) | 3596 | if (!NILP (visit)) |
| 3615 | { | 3597 | { |
| 3616 | if (!NILP (beg) || !NILP (end)) | 3598 | if (!NILP (beg) || !NILP (end)) |
| @@ -4213,88 +4195,72 @@ by calling `format-decode', which see. */) | |||
| 4213 | Fcons (orig_filename, Qnil)); | 4195 | Fcons (orig_filename, Qnil)); |
| 4214 | } | 4196 | } |
| 4215 | 4197 | ||
| 4216 | /* In the following loop, HOW_MUCH contains the total bytes read so | 4198 | /* In the following loop, HOW_MUCH contains the total bytes read |
| 4217 | far for a regular file, and not changed for a special file. But, | 4199 | so far for a regular file, and not changed for a special file. */ |
| 4218 | before exiting the loop, it is set to a negative value if I/O | ||
| 4219 | error occurs. */ | ||
| 4220 | how_much = 0; | 4200 | how_much = 0; |
| 4221 | 4201 | ||
| 4222 | /* Total bytes inserted. */ | 4202 | /* Total bytes inserted. */ |
| 4223 | inserted = 0; | 4203 | inserted = 0; |
| 4224 | 4204 | ||
| 4225 | /* Here, we don't do code conversion in the loop. It is done by | 4205 | /* Here we don't do code conversion in the loop. It is done by |
| 4226 | decode_coding_gap after all data are read into the buffer. */ | 4206 | decode_coding_gap after all data are read into the buffer, or |
| 4227 | { | 4207 | reading loop is interrupted with quit or due to I/O error. */ |
| 4228 | ptrdiff_t gap_size = GAP_SIZE; | ||
| 4229 | |||
| 4230 | while (how_much < total) | ||
| 4231 | { | ||
| 4232 | /* try is reserved in some compilers (Microsoft C) */ | ||
| 4233 | ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE); | ||
| 4234 | ptrdiff_t this; | ||
| 4235 | |||
| 4236 | if (not_regular) | ||
| 4237 | { | ||
| 4238 | Lisp_Object nbytes; | ||
| 4239 | |||
| 4240 | /* Maybe make more room. */ | ||
| 4241 | if (gap_size < trytry) | ||
| 4242 | { | ||
| 4243 | make_gap (total - gap_size); | ||
| 4244 | gap_size = GAP_SIZE; | ||
| 4245 | } | ||
| 4246 | |||
| 4247 | /* Read from the file, capturing `quit'. When an | ||
| 4248 | error occurs, end the loop, and arrange for a quit | ||
| 4249 | to be signaled after decoding the text we read. */ | ||
| 4250 | nbytes = internal_condition_case_1 | ||
| 4251 | (read_non_regular, | ||
| 4252 | make_save_value ("iii", (ptrdiff_t) fd, inserted, trytry), | ||
| 4253 | Qerror, read_non_regular_quit); | ||
| 4254 | |||
| 4255 | if (NILP (nbytes)) | ||
| 4256 | { | ||
| 4257 | read_quit = 1; | ||
| 4258 | break; | ||
| 4259 | } | ||
| 4260 | |||
| 4261 | this = XINT (nbytes); | ||
| 4262 | } | ||
| 4263 | else | ||
| 4264 | { | ||
| 4265 | /* Allow quitting out of the actual I/O. We don't make text | ||
| 4266 | part of the buffer until all the reading is done, so a C-g | ||
| 4267 | here doesn't do any harm. */ | ||
| 4268 | immediate_quit = 1; | ||
| 4269 | QUIT; | ||
| 4270 | this = emacs_read (fd, | ||
| 4271 | ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE | ||
| 4272 | + inserted), | ||
| 4273 | trytry); | ||
| 4274 | immediate_quit = 0; | ||
| 4275 | } | ||
| 4276 | 4208 | ||
| 4277 | if (this <= 0) | 4209 | while (how_much < total) |
| 4278 | { | 4210 | { |
| 4279 | how_much = this; | 4211 | ptrdiff_t nread, maxread = min (total - how_much, READ_BUF_SIZE); |
| 4280 | break; | 4212 | Lisp_Object result; |
| 4281 | } | 4213 | |
| 4282 | 4214 | /* For a special file, gap is enlarged as we read, | |
| 4283 | gap_size -= this; | 4215 | so GAP_SIZE should be checked every time. */ |
| 4216 | if (not_regular && (GAP_SIZE < maxread)) | ||
| 4217 | make_gap (maxread - GAP_SIZE); | ||
| 4218 | |||
| 4219 | /* Read from the file, capturing `quit'. */ | ||
| 4220 | result = internal_condition_case_1 | ||
| 4221 | (read_contents, | ||
| 4222 | make_save_value ("iii", (ptrdiff_t) fd, inserted, maxread), | ||
| 4223 | Qerror, read_contents_quit); | ||
| 4224 | if (NILP (result)) | ||
| 4225 | { | ||
| 4226 | /* Quit is signaled. End the loop and arrange | ||
| 4227 | real quit after decoding the text we read. */ | ||
| 4228 | read_quit = 1; | ||
| 4229 | break; | ||
| 4230 | } | ||
| 4231 | nread = XINT (result); | ||
| 4232 | if (nread <= 0) | ||
| 4233 | { | ||
| 4234 | /* End of file or I/O error. End the loop and | ||
| 4235 | save error code in case of I/O error. */ | ||
| 4236 | if (nread < 0) | ||
| 4237 | read_errno = errno; | ||
| 4238 | break; | ||
| 4239 | } | ||
| 4284 | 4240 | ||
| 4285 | /* For a regular file, where TOTAL is the real size, | 4241 | /* Adjust gap and end positions. */ |
| 4286 | count HOW_MUCH to compare with it. | 4242 | GAP_SIZE -= nread; |
| 4287 | For a special file, where TOTAL is just a buffer size, | 4243 | GPT += nread; |
| 4288 | so don't bother counting in HOW_MUCH. | 4244 | ZV += nread; |
| 4289 | (INSERTED is where we count the number of characters inserted.) */ | 4245 | Z += nread; |
| 4290 | if (! not_regular) | 4246 | GPT_BYTE += nread; |
| 4291 | how_much += this; | 4247 | ZV_BYTE += nread; |
| 4292 | inserted += this; | 4248 | Z_BYTE += nread; |
| 4293 | } | 4249 | if (GAP_SIZE > 0) |
| 4294 | } | 4250 | *(GPT_ADDR) = 0; |
| 4251 | |||
| 4252 | /* For a regular file, where TOTAL is the real size, count HOW_MUCH to | ||
| 4253 | compare with it. For a special file, where TOTAL is just a buffer | ||
| 4254 | size, don't bother counting in HOW_MUCH, but always accumulate the | ||
| 4255 | number of bytes read in INSERTED. */ | ||
| 4256 | if (!not_regular) | ||
| 4257 | how_much += nread; | ||
| 4258 | inserted += nread; | ||
| 4259 | } | ||
| 4295 | 4260 | ||
| 4296 | /* Now we have read all the file data into the gap. | 4261 | /* Now we have either read all the file data into the gap, |
| 4297 | If it was empty, undo marking the buffer modified. */ | 4262 | or stop reading on I/O error or quit. If nothing was |
| 4263 | read, undo marking the buffer modified. */ | ||
| 4298 | 4264 | ||
| 4299 | if (inserted == 0) | 4265 | if (inserted == 0) |
| 4300 | { | 4266 | { |
| @@ -4307,28 +4273,11 @@ by calling `format-decode', which see. */) | |||
| 4307 | else | 4273 | else |
| 4308 | Vdeactivate_mark = Qt; | 4274 | Vdeactivate_mark = Qt; |
| 4309 | 4275 | ||
| 4310 | /* Make the text read part of the buffer. */ | ||
| 4311 | GAP_SIZE -= inserted; | ||
| 4312 | GPT += inserted; | ||
| 4313 | GPT_BYTE += inserted; | ||
| 4314 | ZV += inserted; | ||
| 4315 | ZV_BYTE += inserted; | ||
| 4316 | Z += inserted; | ||
| 4317 | Z_BYTE += inserted; | ||
| 4318 | |||
| 4319 | if (GAP_SIZE > 0) | ||
| 4320 | /* Put an anchor to ensure multi-byte form ends at gap. */ | ||
| 4321 | *GPT_ADDR = 0; | ||
| 4322 | |||
| 4323 | emacs_close (fd); | 4276 | emacs_close (fd); |
| 4324 | 4277 | ||
| 4325 | /* Discard the unwind protect for closing the file. */ | 4278 | /* Discard the unwind protect for closing the file. */ |
| 4326 | specpdl_ptr--; | 4279 | specpdl_ptr--; |
| 4327 | 4280 | ||
| 4328 | if (how_much < 0) | ||
| 4329 | error ("IO error reading %s: %s", | ||
| 4330 | SDATA (orig_filename), emacs_strerror (errno)); | ||
| 4331 | |||
| 4332 | notfound: | 4281 | notfound: |
| 4333 | 4282 | ||
| 4334 | if (NILP (coding_system)) | 4283 | if (NILP (coding_system)) |
| @@ -4617,14 +4566,17 @@ by calling `format-decode', which see. */) | |||
| 4617 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); | 4566 | report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); |
| 4618 | } | 4567 | } |
| 4619 | 4568 | ||
| 4569 | /* There was an error reading file. */ | ||
| 4570 | if (read_errno) | ||
| 4571 | error ("IO error reading %s: %s", | ||
| 4572 | SDATA (orig_filename), emacs_strerror (read_errno)); | ||
| 4573 | |||
| 4574 | /* Quit was signaled. */ | ||
| 4620 | if (read_quit) | 4575 | if (read_quit) |
| 4621 | Fsignal (Qquit, Qnil); | 4576 | Fsignal (Qquit, Qnil); |
| 4622 | 4577 | ||
| 4623 | /* ??? Retval needs to be dealt with in all cases consistently. */ | ||
| 4624 | if (NILP (val)) | 4578 | if (NILP (val)) |
| 4625 | val = Fcons (orig_filename, | 4579 | val = list2 (orig_filename, make_number (inserted)); |
| 4626 | Fcons (make_number (inserted), | ||
| 4627 | Qnil)); | ||
| 4628 | 4580 | ||
| 4629 | RETURN_UNGCPRO (unbind_to (count, val)); | 4581 | RETURN_UNGCPRO (unbind_to (count, val)); |
| 4630 | } | 4582 | } |