From: Michael R. <mi...@re...> - 2010-02-04 09:39:03
|
Applied! Thanks! Claas Hilbrecht schrieb: > Hello, > > here is a very small fix (against current svn) for the plugin_fifo. You > need to clear errno after creating the FIFO. Without clearing the errno > variable you will get an error in fiforead() like this: > > [FIFO] Error 2: No such file or directory > > > babel@eisler:~/tmp/lcd4linux$ svn diff plugin_fifo.c > Index: plugin_fifo.c > =================================================================== > --- plugin_fifo.c (Revision 1097) > +++ plugin_fifo.c (Arbeitskopie) > @@ -110,6 +110,8 @@ > error("Couldn't create FIFO \"%s\": %s\n", fd.path, > strerror(errno)); > return -1; > } > + /* clear errno */ > + errno = 0; > fd.created = 1; > return 0; > } > > Mit freundlichem Gruss > Claas Hilbrecht > > > ------------------------------------------------------------------------------ > The Planet: dedicated and managed hosting, cloud storage, colocation > Stay online with enterprise data centers and the best network in the business > Choose flexible plans and management services without long-term contracts > Personal 24x7 support from experience hosting pros just a phone call away. > http://p.sf.net/sfu/theplanet-com > _______________________________________________ > Lcd4linux-devel mailing list > Lcd...@li... > https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel > > -- Michael Reinelt <mi...@re...> http://home.pages.at/reinelt GPG-Key 0xDF13BA50 ICQ #288386781 |
From: Michael R. <mi...@re...> - 2010-02-04 14:31:42
|
Hi Mattia, thanks a bunch for pointing this out! I didn't read the code that careful (fortunately you did!), but I'm afraid even if I did I would have missed this... as you already provided a clean solution, could you please check it in? TIA, Michael Mattia Jona-Lasinio schrieb: > Hi Claas, Michael and The List! > > IMHO explicitely clearing the errno variable is generally a _VEEEEERY_ > bad idea and should never be done. > errno should be treated like a read only variable that one must assume > to be completely undefined before a function that is allowed to modify > it, is actually called. This means that its value must not be checked > before calling the function that might change it, is actually called. > And in any case the errno value must be checked only after checking > the return value of the called function. > Unfortunately in plugin_fifo.c, line 191 > > while (bytes > 0 && errno != EINTR) { > bytes = read(fd.input, buf, FIFO_BUFFER_SIZE); > } > > the value of errno is checked BEFORE the very first call to read. Then > a previous function call might had set its value to EINTR and we are > not going to read anything just because errno was spuriously set. In > any case this piece of code is buggy because errno is set by read only > if bytes < 0 OR 0 <= bytes < FIFO_BUFFER_SIZE, but is untouched > (therefore still undefined) if bytes == FIFO_BUFFER_SIZE. > > But the solution is not clearing errno, but rather changing the code > above to fix this bug. Something like > > while ((bytes = read(fd.input, buf, FIFO_BUFFER_SIZE)) > 0) { > if (bytes < FIFO_BUFFER_SIZE && errno == EINTR) > break; > } > > so that the bytes = 1 initialization is not necessary. > > At this point the subsequent test > > if (bytes < 0 || (errno > 0 && errno != EAGAIN)) { > error("[FIFO] Error %i: %s", errno, strerror(errno)); > } > > becomes meaningful but one has to distinguish the cases "bytes < 0" > (read returned an error) from "bytes < FIFO_BUFFER_SIZE" (there was > just a "short" read), so that it should be something like > > if (bytes < 0 || (bytes < FIFO_BUFFER_SIZE && errno > 0 && errno != EAGAIN)) { > error("[FIFO] Error %i: %s", errno, strerror(errno)); > } > > > What do you think about all this? > > > Bye! > > > Mattia > > > > On Thu, Feb 4, 2010 at 10:38 AM, Michael Reinelt <mi...@re...> wrote: >> Applied! Thanks! >> >> Claas Hilbrecht schrieb: >>> Hello, >>> >>> here is a very small fix (against current svn) for the plugin_fifo. You >>> need to clear errno after creating the FIFO. Without clearing the errno >>> variable you will get an error in fiforead() like this: >>> >>> [FIFO] Error 2: No such file or directory >>> >>> >>> babel@eisler:~/tmp/lcd4linux$ svn diff plugin_fifo.c >>> Index: plugin_fifo.c >>> =================================================================== >>> --- plugin_fifo.c (Revision 1097) >>> +++ plugin_fifo.c (Arbeitskopie) >>> @@ -110,6 +110,8 @@ >>> error("Couldn't create FIFO \"%s\": %s\n", fd.path, >>> strerror(errno)); >>> return -1; >>> } >>> + /* clear errno */ >>> + errno = 0; >>> fd.created = 1; >>> return 0; >>> } >>> >>> Mit freundlichem Gruss >>> Claas Hilbrecht >>> >>> >>> ------------------------------------------------------------------------------ >>> The Planet: dedicated and managed hosting, cloud storage, colocation >>> Stay online with enterprise data centers and the best network in the business >>> Choose flexible plans and management services without long-term contracts >>> Personal 24x7 support from experience hosting pros just a phone call away. >>> http://p.sf.net/sfu/theplanet-com >>> _______________________________________________ >>> Lcd4linux-devel mailing list >>> Lcd...@li... >>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>> >>> >> -- >> Michael Reinelt <mi...@re...> >> http://home.pages.at/reinelt >> GPG-Key 0xDF13BA50 >> ICQ #288386781 >> >> ------------------------------------------------------------------------------ >> The Planet: dedicated and managed hosting, cloud storage, colocation >> Stay online with enterprise data centers and the best network in the business >> Choose flexible plans and management services without long-term contracts >> Personal 24x7 support from experience hosting pros just a phone call away. >> http://p.sf.net/sfu/theplanet-com >> _______________________________________________ >> Lcd4linux-devel mailing list >> Lcd...@li... >> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >> > > ------------------------------------------------------------------------------ > The Planet: dedicated and managed hosting, cloud storage, colocation > Stay online with enterprise data centers and the best network in the business > Choose flexible plans and management services without long-term contracts > Personal 24x7 support from experience hosting pros just a phone call away. > http://p.sf.net/sfu/theplanet-com > _______________________________________________ > Lcd4linux-devel mailing list > Lcd...@li... > https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel > > -- Michael Reinelt <mi...@re...> http://home.pages.at/reinelt GPG-Key 0xDF13BA50 ICQ #288386781 |
From: Mattia Jona-L. <mat...@gm...> - 2010-02-04 14:42:30
|
Hi Michael, I tried my solution but it does not solve completely the problem. I'm working on it and when I find an elegant solution, I will commit it. For the moment let's keep the errno = 0 patch. Bye, Mattia On Thu, Feb 4, 2010 at 3:31 PM, Michael Reinelt <mi...@re...> wrote: > Hi Mattia, > > thanks a bunch for pointing this out! I didn't read the code that careful (fortunately you did!), but I'm afraid even if > I did I would have missed this... > > as you already provided a clean solution, could you please check it in? > > > > TIA, Michael > > Mattia Jona-Lasinio schrieb: >> Hi Claas, Michael and The List! >> >> IMHO explicitely clearing the errno variable is generally a _VEEEEERY_ >> bad idea and should never be done. >> errno should be treated like a read only variable that one must assume >> to be completely undefined before a function that is allowed to modify >> it, is actually called. This means that its value must not be checked >> before calling the function that might change it, is actually called. >> And in any case the errno value must be checked only after checking >> the return value of the called function. >> Unfortunately in plugin_fifo.c, line 191 >> >> while (bytes > 0 && errno != EINTR) { >> bytes = read(fd.input, buf, FIFO_BUFFER_SIZE); >> } >> >> the value of errno is checked BEFORE the very first call to read. Then >> a previous function call might had set its value to EINTR and we are >> not going to read anything just because errno was spuriously set. In >> any case this piece of code is buggy because errno is set by read only >> if bytes < 0 OR 0 <= bytes < FIFO_BUFFER_SIZE, but is untouched >> (therefore still undefined) if bytes == FIFO_BUFFER_SIZE. >> >> But the solution is not clearing errno, but rather changing the code >> above to fix this bug. Something like >> >> while ((bytes = read(fd.input, buf, FIFO_BUFFER_SIZE)) > 0) { >> if (bytes < FIFO_BUFFER_SIZE && errno == EINTR) >> break; >> } >> >> so that the bytes = 1 initialization is not necessary. >> >> At this point the subsequent test >> >> if (bytes < 0 || (errno > 0 && errno != EAGAIN)) { >> error("[FIFO] Error %i: %s", errno, strerror(errno)); >> } >> >> becomes meaningful but one has to distinguish the cases "bytes < 0" >> (read returned an error) from "bytes < FIFO_BUFFER_SIZE" (there was >> just a "short" read), so that it should be something like >> >> if (bytes < 0 || (bytes < FIFO_BUFFER_SIZE && errno > 0 && errno != EAGAIN)) { >> error("[FIFO] Error %i: %s", errno, strerror(errno)); >> } >> >> >> What do you think about all this? >> >> >> Bye! >> >> >> Mattia >> >> >> >> On Thu, Feb 4, 2010 at 10:38 AM, Michael Reinelt <mi...@re...> wrote: >>> Applied! Thanks! >>> >>> Claas Hilbrecht schrieb: >>>> Hello, >>>> >>>> here is a very small fix (against current svn) for the plugin_fifo. You >>>> need to clear errno after creating the FIFO. Without clearing the errno >>>> variable you will get an error in fiforead() like this: >>>> >>>> [FIFO] Error 2: No such file or directory >>>> >>>> >>>> babel@eisler:~/tmp/lcd4linux$ svn diff plugin_fifo.c >>>> Index: plugin_fifo.c >>>> =================================================================== >>>> --- plugin_fifo.c (Revision 1097) >>>> +++ plugin_fifo.c (Arbeitskopie) >>>> @@ -110,6 +110,8 @@ >>>> error("Couldn't create FIFO \"%s\": %s\n", fd.path, >>>> strerror(errno)); >>>> return -1; >>>> } >>>> + /* clear errno */ >>>> + errno = 0; >>>> fd.created = 1; >>>> return 0; >>>> } >>>> >>>> Mit freundlichem Gruss >>>> Claas Hilbrecht >>>> >>>> >>>> ------------------------------------------------------------------------------ >>>> The Planet: dedicated and managed hosting, cloud storage, colocation >>>> Stay online with enterprise data centers and the best network in the business >>>> Choose flexible plans and management services without long-term contracts >>>> Personal 24x7 support from experience hosting pros just a phone call away. >>>> http://p.sf.net/sfu/theplanet-com >>>> _______________________________________________ >>>> Lcd4linux-devel mailing list >>>> Lcd...@li... >>>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>>> >>>> >>> -- >>> Michael Reinelt <mi...@re...> >>> http://home.pages.at/reinelt >>> GPG-Key 0xDF13BA50 >>> ICQ #288386781 >>> >>> ------------------------------------------------------------------------------ >>> The Planet: dedicated and managed hosting, cloud storage, colocation >>> Stay online with enterprise data centers and the best network in the business >>> Choose flexible plans and management services without long-term contracts >>> Personal 24x7 support from experience hosting pros just a phone call away. >>> http://p.sf.net/sfu/theplanet-com >>> _______________________________________________ >>> Lcd4linux-devel mailing list >>> Lcd...@li... >>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>> >> >> ------------------------------------------------------------------------------ >> The Planet: dedicated and managed hosting, cloud storage, colocation >> Stay online with enterprise data centers and the best network in the business >> Choose flexible plans and management services without long-term contracts >> Personal 24x7 support from experience hosting pros just a phone call away. >> http://p.sf.net/sfu/theplanet-com >> _______________________________________________ >> Lcd4linux-devel mailing list >> Lcd...@li... >> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >> >> > > -- > Michael Reinelt <mi...@re...> > http://home.pages.at/reinelt > GPG-Key 0xDF13BA50 > ICQ #288386781 > |
From: Mattia Jona-L. <mat...@gm...> - 2010-02-08 11:33:03
Attachments:
plugin_fifo.c
|
Hi List! Ok, it seems that concerning the read(n) function, n being the number of bytes to read, a lot of things can happen. This is what I found in the docs. errno is a variable that specifies the type of error occured. This means that for errno to be meaningful there MUST be an error. If everything is fine then errno is undefined. read(n) is a function returning -1 in case of error or returning the number of bytes that were read, if any (this number can be zero). It is NOT considered an error if this number is less than n. Maybe we reached the end of file or we were interrupted by the system. What you can count on is the following. If read(n) returns -1 then errno is set accordingly, to specify the error. If read(n) returns n then everything went fine and errno is undefined. Here comes the "funny" part. If errno == EINTR then we were interrupted by the system BUT it is unspecified (POSIX allows for both behaviors) whether read must return the number of bytes actually read or -1. And in the latter case it is unspecified whether the file position is incremented or not so we don't know whether we will reread the same data twice or we will read new data. This is a killer!!! Anyway. As far as I know the Linux implementation in case of an interruption by the system is to return the bytes that were read and to set errno to EINTR, so we don't have to worry about the file position but we cannot rely on read(n) < n to assume errno is valid because, for example, if we are not interrupted but simply we have a short read then read(n) < n but errno is not set (undefined). So, to make a long story short we have three possible cases: if read(n) == -1 then errno is valid. if 0 <= read(n) < n then errno MIGHT be valid and set to EINTR. But in the end who cares? Even if it were the case we also have the number of bytes actually read and we have to treat them. So the errno == EINTR case does not deserve a special treatment in the end. We might spot this case by explicitely clearing errno (horrible! :) ) before calling read, but then what? In any case we will be called again by the main routine of lcd4linux. if read(n) == n then errno is invalid. Since I heavily rewrote most of the code in a (to me) more rational and better way, I send the complete plugin_fifo.c file instead of a diff file. And before committing it I'd like to have some feedback on it, to be sure that the plugin has the intended behavior. Of course I'm open to suggestions, improvements, criticisms, etc etc ;) Bye! Mattia On Thu, Feb 4, 2010 at 3:42 PM, Mattia Jona-Lasinio <mat...@gm...> wrote: > Hi Michael, > > I tried my solution but it does not solve completely the problem. I'm > working on it and when I find an elegant solution, I will commit it. > For the moment let's keep the errno = 0 patch. > > Bye, > > Mattia > > On Thu, Feb 4, 2010 at 3:31 PM, Michael Reinelt <mi...@re...> wrote: >> Hi Mattia, >> >> thanks a bunch for pointing this out! I didn't read the code that careful (fortunately you did!), but I'm afraid even if >> I did I would have missed this... >> >> as you already provided a clean solution, could you please check it in? >> >> >> >> TIA, Michael >> >> Mattia Jona-Lasinio schrieb: >>> Hi Claas, Michael and The List! >>> >>> IMHO explicitely clearing the errno variable is generally a _VEEEEERY_ >>> bad idea and should never be done. >>> errno should be treated like a read only variable that one must assume >>> to be completely undefined before a function that is allowed to modify >>> it, is actually called. This means that its value must not be checked >>> before calling the function that might change it, is actually called. >>> And in any case the errno value must be checked only after checking >>> the return value of the called function. >>> Unfortunately in plugin_fifo.c, line 191 >>> >>> while (bytes > 0 && errno != EINTR) { >>> bytes = read(fd.input, buf, FIFO_BUFFER_SIZE); >>> } >>> >>> the value of errno is checked BEFORE the very first call to read. Then >>> a previous function call might had set its value to EINTR and we are >>> not going to read anything just because errno was spuriously set. In >>> any case this piece of code is buggy because errno is set by read only >>> if bytes < 0 OR 0 <= bytes < FIFO_BUFFER_SIZE, but is untouched >>> (therefore still undefined) if bytes == FIFO_BUFFER_SIZE. >>> >>> But the solution is not clearing errno, but rather changing the code >>> above to fix this bug. Something like >>> >>> while ((bytes = read(fd.input, buf, FIFO_BUFFER_SIZE)) > 0) { >>> if (bytes < FIFO_BUFFER_SIZE && errno == EINTR) >>> break; >>> } >>> >>> so that the bytes = 1 initialization is not necessary. >>> >>> At this point the subsequent test >>> >>> if (bytes < 0 || (errno > 0 && errno != EAGAIN)) { >>> error("[FIFO] Error %i: %s", errno, strerror(errno)); >>> } >>> >>> becomes meaningful but one has to distinguish the cases "bytes < 0" >>> (read returned an error) from "bytes < FIFO_BUFFER_SIZE" (there was >>> just a "short" read), so that it should be something like >>> >>> if (bytes < 0 || (bytes < FIFO_BUFFER_SIZE && errno > 0 && errno != EAGAIN)) { >>> error("[FIFO] Error %i: %s", errno, strerror(errno)); >>> } >>> >>> >>> What do you think about all this? >>> >>> >>> Bye! >>> >>> >>> Mattia >>> >>> >>> >>> On Thu, Feb 4, 2010 at 10:38 AM, Michael Reinelt <mi...@re...> wrote: >>>> Applied! Thanks! >>>> >>>> Claas Hilbrecht schrieb: >>>>> Hello, >>>>> >>>>> here is a very small fix (against current svn) for the plugin_fifo. You >>>>> need to clear errno after creating the FIFO. Without clearing the errno >>>>> variable you will get an error in fiforead() like this: >>>>> >>>>> [FIFO] Error 2: No such file or directory >>>>> >>>>> >>>>> babel@eisler:~/tmp/lcd4linux$ svn diff plugin_fifo.c >>>>> Index: plugin_fifo.c >>>>> =================================================================== >>>>> --- plugin_fifo.c (Revision 1097) >>>>> +++ plugin_fifo.c (Arbeitskopie) >>>>> @@ -110,6 +110,8 @@ >>>>> error("Couldn't create FIFO \"%s\": %s\n", fd.path, >>>>> strerror(errno)); >>>>> return -1; >>>>> } >>>>> + /* clear errno */ >>>>> + errno = 0; >>>>> fd.created = 1; >>>>> return 0; >>>>> } >>>>> >>>>> Mit freundlichem Gruss >>>>> Claas Hilbrecht >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> The Planet: dedicated and managed hosting, cloud storage, colocation >>>>> Stay online with enterprise data centers and the best network in the business >>>>> Choose flexible plans and management services without long-term contracts >>>>> Personal 24x7 support from experience hosting pros just a phone call away. >>>>> http://p.sf.net/sfu/theplanet-com >>>>> _______________________________________________ >>>>> Lcd4linux-devel mailing list >>>>> Lcd...@li... >>>>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>>>> >>>>> >>>> -- >>>> Michael Reinelt <mi...@re...> >>>> http://home.pages.at/reinelt >>>> GPG-Key 0xDF13BA50 >>>> ICQ #288386781 >>>> >>>> ------------------------------------------------------------------------------ >>>> The Planet: dedicated and managed hosting, cloud storage, colocation >>>> Stay online with enterprise data centers and the best network in the business >>>> Choose flexible plans and management services without long-term contracts >>>> Personal 24x7 support from experience hosting pros just a phone call away. >>>> http://p.sf.net/sfu/theplanet-com >>>> _______________________________________________ >>>> Lcd4linux-devel mailing list >>>> Lcd...@li... >>>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>>> >>> >>> ------------------------------------------------------------------------------ >>> The Planet: dedicated and managed hosting, cloud storage, colocation >>> Stay online with enterprise data centers and the best network in the business >>> Choose flexible plans and management services without long-term contracts >>> Personal 24x7 support from experience hosting pros just a phone call away. >>> http://p.sf.net/sfu/theplanet-com >>> _______________________________________________ >>> Lcd4linux-devel mailing list >>> Lcd...@li... >>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>> >>> >> >> -- >> Michael Reinelt <mi...@re...> >> http://home.pages.at/reinelt >> GPG-Key 0xDF13BA50 >> ICQ #288386781 >> > |
From: Mattia Jona-L. <mat...@gm...> - 2010-02-11 16:59:46
|
Hi The new plugin fifo is now in the repository with some bugfixes and improvements. The main differences are: - all static memory allocations are now dynamical - the plugin tries to match the internal buffer size with the number of display columns; if it fails then it can use a parameter supplied in the configuration file; if this parameter is absent then it uses a built in constant value - some off-by-one memory overflows have been fixed or avoided Bye! Mattia On Mon, Feb 8, 2010 at 12:32 PM, Mattia Jona-Lasinio <mat...@gm...> wrote: > Hi List! > > Ok, it seems that concerning the read(n) function, n being the number > of bytes to read, a lot of things can happen. This is what I found in > the docs. > > errno is a variable that specifies the type of error occured. This > means that for errno to be meaningful there MUST be an error. If > everything is fine then errno is undefined. > > read(n) is a function returning -1 in case of error or returning the > number of bytes that were read, if any (this number can be zero). It > is NOT considered an error if this number is less than n. Maybe we > reached the end of file or we were interrupted by the system. > > What you can count on is the following. > > If read(n) returns -1 then errno is set accordingly, to specify the error. > If read(n) returns n then everything went fine and errno is undefined. > > Here comes the "funny" part. > If errno == EINTR then we were interrupted by the system BUT it is > unspecified (POSIX allows for both behaviors) whether read must return > the number of bytes actually read or -1. And in the latter case it is > unspecified whether the file position is incremented or not so we > don't know whether we will reread the same data twice or we will read > new data. This is a killer!!! Anyway. As far as I know the Linux > implementation in case of an interruption by the system is to return > the bytes that were read and to set errno to EINTR, so we don't have > to worry about the file position but we cannot rely on read(n) < n to > assume errno is valid because, for example, if we are not interrupted > but simply we have a short read then read(n) < n but errno is not set > (undefined). > > So, to make a long story short we have three possible cases: > if read(n) == -1 then errno is valid. > if 0 <= read(n) < n then errno MIGHT be valid and set to EINTR. But in > the end who cares? Even if it were the case we also have the number of > bytes actually read and we have to treat them. So the errno == EINTR > case does not deserve a special treatment in the end. We might spot > this case by explicitely clearing errno (horrible! :) ) before calling > read, but then what? In any case we will be called again by the main > routine of lcd4linux. > if read(n) == n then errno is invalid. > > Since I heavily rewrote most of the code in a (to me) more rational > and better way, I send the complete plugin_fifo.c file instead of a > diff file. > And before committing it I'd like to have some feedback on it, to be > sure that the plugin has the intended behavior. Of course I'm open to > suggestions, improvements, criticisms, etc etc ;) > > Bye! > > Mattia > > On Thu, Feb 4, 2010 at 3:42 PM, Mattia Jona-Lasinio > <mat...@gm...> wrote: >> Hi Michael, >> >> I tried my solution but it does not solve completely the problem. I'm >> working on it and when I find an elegant solution, I will commit it. >> For the moment let's keep the errno = 0 patch. >> >> Bye, >> >> Mattia >> >> On Thu, Feb 4, 2010 at 3:31 PM, Michael Reinelt <mi...@re...> wrote: >>> Hi Mattia, >>> >>> thanks a bunch for pointing this out! I didn't read the code that careful (fortunately you did!), but I'm afraid even if >>> I did I would have missed this... >>> >>> as you already provided a clean solution, could you please check it in? >>> >>> >>> >>> TIA, Michael >>> >>> Mattia Jona-Lasinio schrieb: >>>> Hi Claas, Michael and The List! >>>> >>>> IMHO explicitely clearing the errno variable is generally a _VEEEEERY_ >>>> bad idea and should never be done. >>>> errno should be treated like a read only variable that one must assume >>>> to be completely undefined before a function that is allowed to modify >>>> it, is actually called. This means that its value must not be checked >>>> before calling the function that might change it, is actually called. >>>> And in any case the errno value must be checked only after checking >>>> the return value of the called function. >>>> Unfortunately in plugin_fifo.c, line 191 >>>> >>>> while (bytes > 0 && errno != EINTR) { >>>> bytes = read(fd.input, buf, FIFO_BUFFER_SIZE); >>>> } >>>> >>>> the value of errno is checked BEFORE the very first call to read. Then >>>> a previous function call might had set its value to EINTR and we are >>>> not going to read anything just because errno was spuriously set. In >>>> any case this piece of code is buggy because errno is set by read only >>>> if bytes < 0 OR 0 <= bytes < FIFO_BUFFER_SIZE, but is untouched >>>> (therefore still undefined) if bytes == FIFO_BUFFER_SIZE. >>>> >>>> But the solution is not clearing errno, but rather changing the code >>>> above to fix this bug. Something like >>>> >>>> while ((bytes = read(fd.input, buf, FIFO_BUFFER_SIZE)) > 0) { >>>> if (bytes < FIFO_BUFFER_SIZE && errno == EINTR) >>>> break; >>>> } >>>> >>>> so that the bytes = 1 initialization is not necessary. >>>> >>>> At this point the subsequent test >>>> >>>> if (bytes < 0 || (errno > 0 && errno != EAGAIN)) { >>>> error("[FIFO] Error %i: %s", errno, strerror(errno)); >>>> } >>>> >>>> becomes meaningful but one has to distinguish the cases "bytes < 0" >>>> (read returned an error) from "bytes < FIFO_BUFFER_SIZE" (there was >>>> just a "short" read), so that it should be something like >>>> >>>> if (bytes < 0 || (bytes < FIFO_BUFFER_SIZE && errno > 0 && errno != EAGAIN)) { >>>> error("[FIFO] Error %i: %s", errno, strerror(errno)); >>>> } >>>> >>>> >>>> What do you think about all this? >>>> >>>> >>>> Bye! >>>> >>>> >>>> Mattia >>>> >>>> >>>> >>>> On Thu, Feb 4, 2010 at 10:38 AM, Michael Reinelt <mi...@re...> wrote: >>>>> Applied! Thanks! >>>>> >>>>> Claas Hilbrecht schrieb: >>>>>> Hello, >>>>>> >>>>>> here is a very small fix (against current svn) for the plugin_fifo. You >>>>>> need to clear errno after creating the FIFO. Without clearing the errno >>>>>> variable you will get an error in fiforead() like this: >>>>>> >>>>>> [FIFO] Error 2: No such file or directory >>>>>> >>>>>> >>>>>> babel@eisler:~/tmp/lcd4linux$ svn diff plugin_fifo.c >>>>>> Index: plugin_fifo.c >>>>>> =================================================================== >>>>>> --- plugin_fifo.c (Revision 1097) >>>>>> +++ plugin_fifo.c (Arbeitskopie) >>>>>> @@ -110,6 +110,8 @@ >>>>>> error("Couldn't create FIFO \"%s\": %s\n", fd.path, >>>>>> strerror(errno)); >>>>>> return -1; >>>>>> } >>>>>> + /* clear errno */ >>>>>> + errno = 0; >>>>>> fd.created = 1; >>>>>> return 0; >>>>>> } >>>>>> >>>>>> Mit freundlichem Gruss >>>>>> Claas Hilbrecht >>>>>> >>>>>> >>>>>> ------------------------------------------------------------------------------ >>>>>> The Planet: dedicated and managed hosting, cloud storage, colocation >>>>>> Stay online with enterprise data centers and the best network in the business >>>>>> Choose flexible plans and management services without long-term contracts >>>>>> Personal 24x7 support from experience hosting pros just a phone call away. >>>>>> http://p.sf.net/sfu/theplanet-com >>>>>> _______________________________________________ >>>>>> Lcd4linux-devel mailing list >>>>>> Lcd...@li... >>>>>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>>>>> >>>>>> >>>>> -- >>>>> Michael Reinelt <mi...@re...> >>>>> http://home.pages.at/reinelt >>>>> GPG-Key 0xDF13BA50 >>>>> ICQ #288386781 >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> The Planet: dedicated and managed hosting, cloud storage, colocation >>>>> Stay online with enterprise data centers and the best network in the business >>>>> Choose flexible plans and management services without long-term contracts >>>>> Personal 24x7 support from experience hosting pros just a phone call away. >>>>> http://p.sf.net/sfu/theplanet-com >>>>> _______________________________________________ >>>>> Lcd4linux-devel mailing list >>>>> Lcd...@li... >>>>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>>>> >>>> >>>> ------------------------------------------------------------------------------ >>>> The Planet: dedicated and managed hosting, cloud storage, colocation >>>> Stay online with enterprise data centers and the best network in the business >>>> Choose flexible plans and management services without long-term contracts >>>> Personal 24x7 support from experience hosting pros just a phone call away. >>>> http://p.sf.net/sfu/theplanet-com >>>> _______________________________________________ >>>> Lcd4linux-devel mailing list >>>> Lcd...@li... >>>> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >>>> >>>> >>> >>> -- >>> Michael Reinelt <mi...@re...> >>> http://home.pages.at/reinelt >>> GPG-Key 0xDF13BA50 >>> ICQ #288386781 >>> >> > |
From: Mattia Jona-L. <mat...@gm...> - 2010-02-04 11:37:28
|
Hi Claas, Michael and The List! IMHO explicitely clearing the errno variable is generally a _VEEEEERY_ bad idea and should never be done. errno should be treated like a read only variable that one must assume to be completely undefined before a function that is allowed to modify it, is actually called. This means that its value must not be checked before calling the function that might change it, is actually called. And in any case the errno value must be checked only after checking the return value of the called function. Unfortunately in plugin_fifo.c, line 191 while (bytes > 0 && errno != EINTR) { bytes = read(fd.input, buf, FIFO_BUFFER_SIZE); } the value of errno is checked BEFORE the very first call to read. Then a previous function call might had set its value to EINTR and we are not going to read anything just because errno was spuriously set. In any case this piece of code is buggy because errno is set by read only if bytes < 0 OR 0 <= bytes < FIFO_BUFFER_SIZE, but is untouched (therefore still undefined) if bytes == FIFO_BUFFER_SIZE. But the solution is not clearing errno, but rather changing the code above to fix this bug. Something like while ((bytes = read(fd.input, buf, FIFO_BUFFER_SIZE)) > 0) { if (bytes < FIFO_BUFFER_SIZE && errno == EINTR) break; } so that the bytes = 1 initialization is not necessary. At this point the subsequent test if (bytes < 0 || (errno > 0 && errno != EAGAIN)) { error("[FIFO] Error %i: %s", errno, strerror(errno)); } becomes meaningful but one has to distinguish the cases "bytes < 0" (read returned an error) from "bytes < FIFO_BUFFER_SIZE" (there was just a "short" read), so that it should be something like if (bytes < 0 || (bytes < FIFO_BUFFER_SIZE && errno > 0 && errno != EAGAIN)) { error("[FIFO] Error %i: %s", errno, strerror(errno)); } What do you think about all this? Bye! Mattia On Thu, Feb 4, 2010 at 10:38 AM, Michael Reinelt <mi...@re...> wrote: > Applied! Thanks! > > Claas Hilbrecht schrieb: >> Hello, >> >> here is a very small fix (against current svn) for the plugin_fifo. You >> need to clear errno after creating the FIFO. Without clearing the errno >> variable you will get an error in fiforead() like this: >> >> [FIFO] Error 2: No such file or directory >> >> >> babel@eisler:~/tmp/lcd4linux$ svn diff plugin_fifo.c >> Index: plugin_fifo.c >> =================================================================== >> --- plugin_fifo.c (Revision 1097) >> +++ plugin_fifo.c (Arbeitskopie) >> @@ -110,6 +110,8 @@ >> error("Couldn't create FIFO \"%s\": %s\n", fd.path, >> strerror(errno)); >> return -1; >> } >> + /* clear errno */ >> + errno = 0; >> fd.created = 1; >> return 0; >> } >> >> Mit freundlichem Gruss >> Claas Hilbrecht >> >> >> ------------------------------------------------------------------------------ >> The Planet: dedicated and managed hosting, cloud storage, colocation >> Stay online with enterprise data centers and the best network in the business >> Choose flexible plans and management services without long-term contracts >> Personal 24x7 support from experience hosting pros just a phone call away. >> http://p.sf.net/sfu/theplanet-com >> _______________________________________________ >> Lcd4linux-devel mailing list >> Lcd...@li... >> https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel >> >> > > -- > Michael Reinelt <mi...@re...> > http://home.pages.at/reinelt > GPG-Key 0xDF13BA50 > ICQ #288386781 > > ------------------------------------------------------------------------------ > The Planet: dedicated and managed hosting, cloud storage, colocation > Stay online with enterprise data centers and the best network in the business > Choose flexible plans and management services without long-term contracts > Personal 24x7 support from experience hosting pros just a phone call away. > http://p.sf.net/sfu/theplanet-com > _______________________________________________ > Lcd4linux-devel mailing list > Lcd...@li... > https://lists.sourceforge.net/lists/listinfo/lcd4linux-devel > |