1 To: vim_dev@googlegroups.com
4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
11 Problem: When a read() or write() is interrupted by a signal it fails.
12 Solution: Add read_eintr() and write_eintr().
13 Files: src/fileio.c, src/proto/fileio.pro, src/memfile.c, src/memline.c,
14 src/os_unix.c, src/undo.c, src/vim.h
17 *** ../vim-7.3.082/src/fileio.c 2010-08-15 21:57:26.000000000 +0200
18 --- src/fileio.c 2010-12-17 16:04:30.000000000 +0100
22 /* Read the first line (and a bit more). Immediately rewind to
23 * the start of the file. If the read() fails "len" is -1. */
24 ! len = vim_read(fd, firstline, 80);
25 lseek(fd, (off_t)0L, SEEK_SET);
26 for (p = firstline; p < firstline + len; ++p)
30 /* Read the first line (and a bit more). Immediately rewind to
31 * the start of the file. If the read() fails "len" is -1. */
32 ! len = read_eintr(fd, firstline, 80);
33 lseek(fd, (off_t)0L, SEEK_SET);
34 for (p = firstline; p < firstline + len; ++p)
39 * Read bytes from the file.
41 ! size = vim_read(fd, ptr, size);
47 * Read bytes from the file.
49 ! size = read_eintr(fd, ptr, size);
56 write_info.bw_flags = FIO_NOCONVERT;
58 ! while ((write_info.bw_len = vim_read(fd, copybuf,
61 if (buf_write_bytes(&write_info) == FAIL)
64 write_info.bw_flags = FIO_NOCONVERT;
66 ! while ((write_info.bw_len = read_eintr(fd, copybuf,
69 if (buf_write_bytes(&write_info) == FAIL)
73 write_info.bw_flags = FIO_NOCONVERT;
75 ! while ((write_info.bw_len = vim_read(fd, smallbuf,
77 if (buf_write_bytes(&write_info) == FAIL)
81 write_info.bw_flags = FIO_NOCONVERT;
83 ! while ((write_info.bw_len = read_eintr(fd, smallbuf,
85 if (buf_write_bytes(&write_info) == FAIL)
91 * Call write() to write a number of bytes to the file.
92 ! * Also handles encryption and 'encoding' conversion.
94 * Return FAIL for failure, OK otherwise.
99 * Call write() to write a number of bytes to the file.
100 ! * Handles encryption and 'encoding' conversion.
102 * Return FAIL for failure, OK otherwise.
106 crypt_encode(buf, len, buf);
109 ! /* Repeat the write(), it may be interrupted by a signal. */
112 ! wlen = vim_write(ip->bw_fd, buf, len);
113 ! if (wlen <= 0) /* error! */
123 crypt_encode(buf, len, buf);
126 ! wlen = write_eintr(ip->bw_fd, buf, len);
127 ! return (wlen < len) ? FAIL : OK;
136 ! while ((n = vim_read(fd_in, buffer, BUFSIZE)) > 0)
137 ! if (vim_write(fd_out, buffer, n) != n)
139 errmsg = _("E208: Error writing to \"%s\"");
145 ! while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0)
146 ! if (write_eintr(fd_out, buffer, n) != n)
148 errmsg = _("E208: Error writing to \"%s\"");
157 + #if defined(EINTR) || defined(PROTO)
159 + * Version of read() that retries when interrupted by EINTR (possibly
163 + read_eintr(fd, buf, bufsize)
172 + ret = vim_read(fd, buf, bufsize);
173 + if (ret >= 0 || errno != EINTR)
180 + * Version of write() that retries when interrupted by EINTR (possibly
184 + write_eintr(fd, buf, bufsize)
192 + /* Repeat the write() so long it didn't fail, other than being interrupted
194 + while (ret < (long)bufsize)
196 + wlen = vim_write(fd, buf + ret, bufsize - ret);
199 + if (errno != EINTR)
208 *** ../vim-7.3.082/src/proto/fileio.pro 2010-08-15 21:57:28.000000000 +0200
209 --- src/proto/fileio.pro 2010-12-17 15:01:26.000000000 +0100
213 int match_file_pat __ARGS((char_u *pattern, regprog_T *prog, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs));
214 int match_file_list __ARGS((char_u *list, char_u *sfname, char_u *ffname));
215 char_u *file_pat_to_reg_pat __ARGS((char_u *pat, char_u *pat_end, char *allow_dirs, int no_bslash));
216 + long read_eintr __ARGS((int fd, void *buf, size_t bufsize));
217 + long write_eintr __ARGS((int fd, void *buf, size_t bufsize));
218 /* vim: set ft=c : */
219 *** ../vim-7.3.082/src/memfile.c 2010-08-15 21:57:25.000000000 +0200
220 --- src/memfile.c 2010-12-17 16:02:54.000000000 +0100
223 PERROR(_("E294: Seek error in swap file read"));
226 ! if ((unsigned)vim_read(mfp->mf_fd, hp->bh_data, size) != size)
228 PERROR(_("E295: Read error in swap file"));
231 PERROR(_("E294: Seek error in swap file read"));
234 ! if ((unsigned)read_eintr(mfp->mf_fd, hp->bh_data, size) != size)
236 PERROR(_("E295: Read error in swap file"));
243 ! if ((unsigned)vim_write(mfp->mf_fd, data, size) != size)
251 ! if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size)
255 *** ../vim-7.3.082/src/memline.c 2010-12-08 13:16:58.000000000 +0100
256 --- src/memline.c 2010-12-17 15:46:49.000000000 +0100
259 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
262 ! if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
264 if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
267 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
270 ! if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
272 if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
276 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
279 ! if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
282 * If the swapfile has the same directory as the
284 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
287 ! if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
290 * If the swapfile has the same directory as the
291 *** ../vim-7.3.082/src/os_unix.c 2010-10-20 19:17:43.000000000 +0200
292 --- src/os_unix.c 2010-12-17 16:17:43.000000000 +0100
296 while (RealWaitForChar(fromshell_fd, 10L, NULL))
298 ! len = read(fromshell_fd, (char *)buffer
300 + buffer_off, (size_t)(BUFLEN - buffer_off)
304 while (RealWaitForChar(fromshell_fd, 10L, NULL))
306 ! len = read_eintr(fromshell_fd, buffer
308 + buffer_off, (size_t)(BUFLEN - buffer_off)
310 *** ../vim-7.3.082/src/undo.c 2010-11-03 19:32:36.000000000 +0100
311 --- src/undo.c 2010-12-17 15:39:24.000000000 +0100
314 char_u mbuf[UF_START_MAGIC_LEN];
317 ! len = vim_read(fd, mbuf, UF_START_MAGIC_LEN);
319 if (len < UF_START_MAGIC_LEN
320 || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0)
322 char_u mbuf[UF_START_MAGIC_LEN];
325 ! len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN);
327 if (len < UF_START_MAGIC_LEN
328 || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0)
329 *** ../vim-7.3.082/src/vim.h 2010-12-02 16:01:23.000000000 +0100
330 --- src/vim.h 2010-12-17 14:55:04.000000000 +0100
334 # define USE_INPUT_BUF
338 + # define read_eintr(fd, buf, count) vim_read((fd), (buf), (count))
339 + # define write_eintr(fd, buf, count) vim_write((fd), (buf), (count))
343 /* On MS-Windows the third argument isn't size_t. This matters for Win64,
344 * where sizeof(size_t)==8, not 4 */
345 *** ../vim-7.3.082/src/version.c 2010-12-17 12:19:14.000000000 +0100
346 --- src/version.c 2010-12-17 16:10:58.000000000 +0100
350 { /* Add new patch number below this line */
356 How To Keep A Healthy Level Of Insanity:
357 9. As often as possible, skip rather than walk.
359 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
360 /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
361 \\\ an exciting new programming language -- http://www.Zimbu.org ///
362 \\\ help me help AIDS victims -- http://ICCF-Holland.org ///