diff options
author | Bram Moolenaar <Bram@vim.org> | 2010-12-17 16:27:16 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2010-12-17 16:27:16 +0100 |
commit | 540fc6fbdb30971955dc40cc05542b5d4f434787 (patch) | |
tree | c1efeca8e355c647e60ff12e8cae8d942d7a3d29 /src/fileio.c | |
parent | 45d9d02d715d8423ed5e786331d6e8970b86bf60 (diff) | |
download | vim-git-540fc6fbdb30971955dc40cc05542b5d4f434787.tar.gz |
updated for version 7.3.083v7.3.083
Problem: When a read() or write() is interrupted by a signal it fails.
Solution: Add read_eintr() and write_eintr().
Diffstat (limited to 'src/fileio.c')
-rw-r--r-- | src/fileio.c | 78 |
1 files changed, 61 insertions, 17 deletions
diff --git a/src/fileio.c b/src/fileio.c index b6127d9dd..2828aa72a 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -918,7 +918,7 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) { /* Read the first line (and a bit more). Immediately rewind to * the start of the file. If the read() fails "len" is -1. */ - len = vim_read(fd, firstline, 80); + len = read_eintr(fd, firstline, 80); lseek(fd, (off_t)0L, SEEK_SET); for (p = firstline; p < firstline + len; ++p) if (*p >= 0x80) @@ -1373,7 +1373,7 @@ retry: /* * Read bytes from the file. */ - size = vim_read(fd, ptr, size); + size = read_eintr(fd, ptr, size); } if (size <= 0) @@ -4000,7 +4000,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, #ifdef HAS_BW_FLAGS write_info.bw_flags = FIO_NOCONVERT; #endif - while ((write_info.bw_len = vim_read(fd, copybuf, + while ((write_info.bw_len = read_eintr(fd, copybuf, BUFSIZE)) > 0) { if (buf_write_bytes(&write_info) == FAIL) @@ -4813,7 +4813,7 @@ restore_backup: #ifdef HAS_BW_FLAGS write_info.bw_flags = FIO_NOCONVERT; #endif - while ((write_info.bw_len = vim_read(fd, smallbuf, + while ((write_info.bw_len = read_eintr(fd, smallbuf, SMBUFSIZE)) > 0) if (buf_write_bytes(&write_info) == FAIL) break; @@ -5330,7 +5330,7 @@ time_differs(t1, t2) /* * Call write() to write a number of bytes to the file. - * Also handles encryption and 'encoding' conversion. + * Handles encryption and 'encoding' conversion. * * Return FAIL for failure, OK otherwise. */ @@ -5702,16 +5702,8 @@ buf_write_bytes(ip) crypt_encode(buf, len, buf); #endif - /* Repeat the write(), it may be interrupted by a signal. */ - while (len > 0) - { - wlen = vim_write(ip->bw_fd, buf, len); - if (wlen <= 0) /* error! */ - return FAIL; - len -= wlen; - buf += wlen; - } - return OK; + wlen = write_eintr(ip->bw_fd, buf, len); + return (wlen < len) ? FAIL : OK; } #ifdef FEAT_MBYTE @@ -6662,8 +6654,8 @@ vim_rename(from, to) return -1; } - while ((n = vim_read(fd_in, buffer, BUFSIZE)) > 0) - if (vim_write(fd_out, buffer, n) != n) + while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0) + if (write_eintr(fd_out, buffer, n) != n) { errmsg = _("E208: Error writing to \"%s\""); break; @@ -10304,3 +10296,55 @@ file_pat_to_reg_pat(pat, pat_end, allow_dirs, no_bslash) } return reg_pat; } + +#if defined(EINTR) || defined(PROTO) +/* + * Version of read() that retries when interrupted by EINTR (possibly + * by a SIGWINCH). + */ + long +read_eintr(fd, buf, bufsize) + int fd; + void *buf; + size_t bufsize; +{ + long ret; + + for (;;) + { + ret = vim_read(fd, buf, bufsize); + if (ret >= 0 || errno != EINTR) + break; + } + return ret; +} + +/* + * Version of write() that retries when interrupted by EINTR (possibly + * by a SIGWINCH). + */ + long +write_eintr(fd, buf, bufsize) + int fd; + void *buf; + size_t bufsize; +{ + long ret = 0; + long wlen; + + /* Repeat the write() so long it didn't fail, other than being interrupted + * by a signal. */ + while (ret < (long)bufsize) + { + wlen = vim_write(fd, buf + ret, bufsize - ret); + if (wlen < 0) + { + if (errno != EINTR) + break; + } + else + ret += wlen; + } + return ret; +} +#endif |