Message ID | 5397C077.1080702@gmail.com |
---|---|
State | New, archived |
Headers |
Received: (qmail 32757 invoked by alias); 11 Jun 2014 02:36:02 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <gdb-patches.sourceware.org> List-Unsubscribe: <mailto:gdb-patches-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:gdb-patches-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 32642 invoked by uid 89); 11 Jun 2014 02:35:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-pa0-f54.google.com Received: from mail-pa0-f54.google.com (HELO mail-pa0-f54.google.com) (209.85.220.54) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 11 Jun 2014 02:35:42 +0000 Received: by mail-pa0-f54.google.com with SMTP id rd3so1368880pab.13 for <multiple recipients>; Tue, 10 Jun 2014 19:35:39 -0700 (PDT) X-Received: by 10.66.162.137 with SMTP id ya9mr9847998pab.31.1402454139639; Tue, 10 Jun 2014 19:35:39 -0700 (PDT) Received: from [192.168.1.23] ([124.127.118.42]) by mx.google.com with ESMTPSA id uj3sm21185929pac.8.2014.06.10.19.35.36 for <multiple recipients> (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 10 Jun 2014 19:35:39 -0700 (PDT) Message-ID: <5397C077.1080702@gmail.com> Date: Wed, 11 Jun 2014 10:35:35 +0800 From: Chen Gang <gang.chen.5i5j@gmail.com> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: Andreas Schwab <schwab@linux-m68k.org> CC: palves@redhat.com, amodra@gmail.com, binutils@sourceware.org, bug-readline@gnu.org, gdb-patches@sourceware.org Subject: [PATCH] readline/histfile.c: Check and retry write() operation in history_truncate_file() Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit |
Commit Message
Chen Gang
June 11, 2014, 2:35 a.m. UTC
For regular file, write() operation may also fail, so check it too. If
write() return 0, can simply wait and try again, it should not suspend
infinitely if environments have no critical issues.
The related warning (cross compile for aarch64-linux):
../../binutils-gdb/readline/histfile.c: In function ‘history_truncate_file’:
../../binutils-gdb/readline/histfile.c:406:13: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused
readline/
* readline/histfile.c (history_truncate_file):
Check and retry write() operation.
Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
readline/ChangeLog.gdb | 5 +++++
readline/histfile.c | 25 +++++++++++++++++++++++--
2 files changed, 28 insertions(+), 2 deletions(-)
Comments
On 6/10/14, 10:35 PM, Chen Gang wrote: > For regular file, write() operation may also fail, so check it too. If > write() return 0, can simply wait and try again, it should not suspend > infinitely if environments have no critical issues. Readline-6.3 checks the return value from write() and returns a non-zero value to the history_truncate_file caller. I really don't think that waiting forever if write continues to return 0 is a great idea; an error return is enough to let the caller deal with it. Chet
On 06/19/2014 04:33 AM, Chet Ramey wrote: > On 6/10/14, 10:35 PM, Chen Gang wrote: >> For regular file, write() operation may also fail, so check it too. If >> write() return 0, can simply wait and try again, it should not suspend >> infinitely if environments have no critical issues. > > Readline-6.3 checks the return value from write() and returns a non-zero > value to the history_truncate_file caller. I really don't think that > waiting forever if write continues to return 0 is a great idea; an error > return is enough to let the caller deal with it. > That sounds fine to me, and I will send patch v2 for it. And excuse me, I have to do some other things today, so I shall try to send it within 2 days (within 2014-06-21) -- if it is too late, please help send it. Thanks.
On 06/19/2014 09:31 AM, Chen Gang wrote: > > > On 06/19/2014 04:33 AM, Chet Ramey wrote: >> On 6/10/14, 10:35 PM, Chen Gang wrote: >>> For regular file, write() operation may also fail, so check it too. If >>> write() return 0, can simply wait and try again, it should not suspend >>> infinitely if environments have no critical issues. >> >> Readline-6.3 checks the return value from write() and returns a non-zero >> value to the history_truncate_file caller. I really don't think that >> waiting forever if write continues to return 0 is a great idea; an error >> return is enough to let the caller deal with it. >> Oh, sorry, after think of again, for me, we have to waiting forever if write() continues to return 0. When this case happens, the file is already truncated, and the left data which is writing to file will be free after return from history_truncate_file(). If return an error code in this case, the caller can not deal with it -- the log data which should be remained, have been lost, can not get them back again. > > That sounds fine to me, and I will send patch v2 for it. And excuse me, > I have to do some other things today, so I shall try to send it within 2 > days (within 2014-06-21) -- if it is too late, please help send it. > Thanks.
On 6/20/14, 4:57 AM, Chen Gang wrote: > On 06/19/2014 09:31 AM, Chen Gang wrote: >> >> >> On 06/19/2014 04:33 AM, Chet Ramey wrote: >>> On 6/10/14, 10:35 PM, Chen Gang wrote: >>>> For regular file, write() operation may also fail, so check it too. If >>>> write() return 0, can simply wait and try again, it should not suspend >>>> infinitely if environments have no critical issues. >>> >>> Readline-6.3 checks the return value from write() and returns a non-zero >>> value to the history_truncate_file caller. I really don't think that >>> waiting forever if write continues to return 0 is a great idea; an error >>> return is enough to let the caller deal with it. >>> > > Oh, sorry, after think of again, for me, we have to waiting forever if > write() continues to return 0. There aren't really any plausible conditions under which write(2) returns 0 instead of -1 when writing a non-zero number of bytes to a regular file. > > When this case happens, the file is already truncated, and the left data > which is writing to file will be free after return from > history_truncate_file(). > > If return an error code in this case, the caller can not deal with it -- > the log data which should be remained, have been lost, can not get them > back again. However, you're right about the data being lost if write fails and returns -1. Since the sequence of operations is open-read-close-open-write-close, I think I will change the code for the next version to use a scheme similar to history_do_write() and restore the original version of the file if the write fails. Chet
On 06/21/2014 05:53 AM, Chet Ramey wrote: > On 6/20/14, 4:57 AM, Chen Gang wrote: >> On 06/19/2014 09:31 AM, Chen Gang wrote: >>> >>> >>> On 06/19/2014 04:33 AM, Chet Ramey wrote: >>>> On 6/10/14, 10:35 PM, Chen Gang wrote: >>>>> For regular file, write() operation may also fail, so check it too. If >>>>> write() return 0, can simply wait and try again, it should not suspend >>>>> infinitely if environments have no critical issues. >>>> >>>> Readline-6.3 checks the return value from write() and returns a non-zero >>>> value to the history_truncate_file caller. I really don't think that >>>> waiting forever if write continues to return 0 is a great idea; an error >>>> return is enough to let the caller deal with it. >>>> >> >> Oh, sorry, after think of again, for me, we have to waiting forever if >> write() continues to return 0. > > There aren't really any plausible conditions under which write(2) returns > 0 instead of -1 when writing a non-zero number of bytes to a regular file. > Hmm... for me, what you said is acceptable. And the function comment need be changed: "Returns 0 on success, errno or -1 on failure" >> >> When this case happens, the file is already truncated, and the left data >> which is writing to file will be free after return from >> history_truncate_file(). >> >> If return an error code in this case, the caller can not deal with it -- >> the log data which should be remained, have been lost, can not get them >> back again. > > However, you're right about the data being lost if write fails and returns > -1. Since the sequence of operations is open-read-close-open-write-close, I > think I will change the code for the next version to use a scheme similar > to history_do_write() and restore the original version of the file if the > write fails. > OK, thanks. And since you will work for it next, is it still necessary to send patch v2 for the temporary fix, at present? Thanks
On 6/20/14, 10:25 PM, Chen Gang wrote: >> There aren't really any plausible conditions under which write(2) returns >> 0 instead of -1 when writing a non-zero number of bytes to a regular file. >> > > Hmm... for me, what you said is acceptable. And the function comment need be > changed: > > "Returns 0 on success, errno or -1 on failure" history_truncate_file will never return -1. > And since you will work for it next, is it still necessary to send patch v2 for > the temporary fix, at present? I will take care of making those changes, thanks. Chet
On 06/22/2014 07:19 AM, Chet Ramey wrote: > On 6/20/14, 10:25 PM, Chen Gang wrote: > >>> There aren't really any plausible conditions under which write(2) returns >>> 0 instead of -1 when writing a non-zero number of bytes to a regular file. >>> >> >> Hmm... for me, what you said is acceptable. And the function comment need be >> changed: >> >> "Returns 0 on success, errno or -1 on failure" > > history_truncate_file will never return -1. > Hmm... do you mean: "for regular file, write() never return 0, if parameter 'count' > 0?" or "if write() return 0, can also return 0 to history_truncate_file()?". >> And since you will work for it next, is it still necessary to send patch v2 for >> the temporary fix, at present? > > I will take care of making those changes, thanks. OK, thanks (I need/shall not send patch v2 for it). Thanks.
On 6/21/14, 10:01 PM, Chen Gang wrote: >> history_truncate_file will never return -1. >> > > Hmm... do you mean: > > "for regular file, write() never return 0, if parameter 'count' > 0?" > > or > > "if write() return 0, can also return 0 to history_truncate_file()?". Both of those things are true, but neither is what I said above.
On 06/23/2014 09:57 PM, Chet Ramey wrote: > On 6/21/14, 10:01 PM, Chen Gang wrote: > >>> history_truncate_file will never return -1. >>> >> >> Hmm... do you mean: >> >> "for regular file, write() never return 0, if parameter 'count' > 0?" >> I am not quite sure whether it is true, in my experience, it should be true, but I have no any proofs for it (if you have, welcome to supply). thank. >> or >> >> "if write() return 0, can also return 0 to history_truncate_file()?". > For me, if write() could return 0, when it happened, we had to process the case within history_truncate_file(), could not only return 0 to indicate all things go on well. > Both of those things are true, but neither is what I said above. > If both of those things are not true, what your originally said above are not true, either. Thanks.
And I guess, we can simply bypass this discussion, because the new fix can process write() well and let history_truncate_file() never return -1. Thanks. On 06/23/2014 10:59 PM, Chen Gang wrote: > On 06/23/2014 09:57 PM, Chet Ramey wrote: >> On 6/21/14, 10:01 PM, Chen Gang wrote: >> >>>> history_truncate_file will never return -1. >>>> >>> >>> Hmm... do you mean: >>> >>> "for regular file, write() never return 0, if parameter 'count' > 0?" >>> > > I am not quite sure whether it is true, in my experience, it should be > true, but I have no any proofs for it (if you have, welcome to supply). > > thank. > >>> or >>> >>> "if write() return 0, can also return 0 to history_truncate_file()?". >> > > For me, if write() could return 0, when it happened, we had to process the > case within history_truncate_file(), could not only return 0 to indicate > all things go on well. > > >> Both of those things are true, but neither is what I said above. >> > > If both of those things are not true, what your originally said above > are not true, either. > > > Thanks. >
diff --git a/readline/ChangeLog.gdb b/readline/ChangeLog.gdb index 1218fd7..f547a90 100644 --- a/readline/ChangeLog.gdb +++ b/readline/ChangeLog.gdb @@ -1,3 +1,8 @@ +2014-06-11 Chen Gang <gang.chen.5i5j@gmail.com> + + * readline/histfile.c (history_truncate_file): + Check and retry write() operation. + 2013-09-24 Pierre Muller <muller@sourceware.org> * readline.c (bind_arrow_keys_internal): diff --git a/readline/histfile.c b/readline/histfile.c index 30a6182..66597a7 100644 --- a/readline/histfile.c +++ b/readline/histfile.c @@ -403,11 +403,32 @@ history_truncate_file (fname, lines) truncate to. */ if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) { - write (file, bp, chars_read - (bp - buffer)); + int chars_write; +#if defined (__BEOS__) + char *orig = bp; +#endif + + do + { + chars_write = write (file, bp, chars_read - (bp - buffer)); + if (chars_write < 0) + { + rv = errno; + close (file); + goto truncate_exit; + } + else if (chars_write == 0) + { + usleep (1000); + continue; + } + bp += chars_write; + } + while (chars_read - (bp - buffer) > 0); #if defined (__BEOS__) /* BeOS ignores O_TRUNC. */ - ftruncate (file, chars_read - (bp - buffer)); + ftruncate (file, chars_read - (orig - buffer)); #endif close (file);