From: root on 11 Aug 2010 07:47 I expect to pay for my mistakes, but sometimes the penalty is all out of proportion. Here is an example I found involving lseek, open, and close. Look at this code segment: int fd; off_t strt=0; fd=open(ptri,"r"); lseek(fd,0L,SEEK_END); fsize=lseek(fd,strt,SEEK_CUR); close(fd); if(fsize==0){ printf("Empty file:%s\n",ptri); } At the start of this code ptri points to a file name. The problem, of course, is that I open the file with mode "r" instead of O_RDONLY. Then penalty is that the contents of the file are erased. This code has worked under every previous version of gcc. Just to make sure *you* haven't made this mistake, go to your source directory and do: grep ' open' *.c|grep '"r"' and see what you get.
From: Eef Hartman on 11 Aug 2010 08:26 root <NoEMail(a)home.org> wrote: > The problem, of course, is that I open the file > with mode "r" instead of O_RDONLY. Then penalty > is that the contents of the file are erased. I'm amazed it ever worked. Modes like "r" and "r+" are for fopen, not open(). O_RDONLY = 0, "r" certainly is NOT (but it does contain the O_RDWR bit, so _if_ the code of open() only tests the lower 2 bits it will see it as O_RDWR, Read/Write mode). But probably now the higher bits are being (ondocumented) used to and thus it doesn't work anymore. PS: as far as I know open() isn't implemented as a macro, so it's not gcc biting you, but the newer libc (/lib/libc-<version>.so). -- ****************************************************************** ** Eef Hartman, Delft University of Technology, dept. SSC/ICT ** ** e-mail: E.J.M.Hartman(a)tudelft.nl - phone: +31-15-27 82525 ** ******************************************************************
From: Lew Pitcher on 11 Aug 2010 13:04 On August 11, 2010 08:26, in alt.os.linux.slackware, E.J.M.Hartman(a)tudelft.nl wrote: > root <NoEMail(a)home.org> wrote: [code fragment restored] >> fd=open(ptri,"r"); >> >> The problem, of course, is that I open the file >> with mode "r" instead of O_RDONLY. Then penalty >> is that the contents of the file are erased. > > I'm amazed it ever worked. > Modes like "r" and "r+" are for fopen, not open(). > O_RDONLY = 0, "r" certainly is NOT (but it does contain > the O_RDWR bit, so _if_ the code of open() only tests the lower 2 > bits it will see it as O_RDWR, Read/Write mode). Not even that. In the call to open(), "r" is a string, and is passed "by value" to open(). /That/ means that open() receives a /pointer/, converted to an int, as it's second argument. And, of course, the value of that pointer (or int), depends entirely on where the compiler /and linker/ put the string constant. To open(), that value would be fairly random. I'm surprised that his original code /ever/ worked consistantly. > But probably now > the higher bits are being (ondocumented) used to and thus it > doesn't work anymore. > > PS: as far as I know open() isn't implemented as a macro, so it's > not gcc biting you, but the newer libc (/lib/libc-<version>.so). -- Lew Pitcher Master Codewright & JOAT-in-training | Registered Linux User #112576 Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/ ---------- Slackware - Because I know what I'm doing. ------
From: root on 11 Aug 2010 14:28 Lew Pitcher <lpitcher(a)teksavvy.com> wrote: > > Not even that. > In the call to open(), "r" is a string, and is passed "by value" to > open(). /That/ means that open() receives a /pointer/, converted to an int, > as it's second argument. And, of course, the value of that pointer (or > int), depends entirely on where the compiler /and linker/ put the string > constant. > > To open(), that value would be fairly random. I'm surprised that his > original code /ever/ worked consistantly. > I can't say the code segment ever worked in that it was not doing anything of value to the program. It was intended only to alert me to a zero length file, for my information only. This segment of the program never did anything more than that. I would not have noticed if it gave me a wrong message, since I didn't follow up on it. The killer here is that this mistake caused the contents of the file to be erased. Every file ended up zero length. My guess is that it is caused by the close() statement without a proper file descriptor. fclose() will seg fault in this case, but close() is more punishing.
From: Jerry Peters on 11 Aug 2010 16:27
root <NoEMail(a)home.org> wrote: > Lew Pitcher <lpitcher(a)teksavvy.com> wrote: >> >> Not even that. >> In the call to open(), "r" is a string, and is passed "by value" to >> open(). /That/ means that open() receives a /pointer/, converted to an int, >> as it's second argument. And, of course, the value of that pointer (or >> int), depends entirely on where the compiler /and linker/ put the string >> constant. >> >> To open(), that value would be fairly random. I'm surprised that his >> original code /ever/ worked consistantly. >> > > I can't say the code segment ever worked in that it > was not doing anything of value to the program. > It was intended only to alert me to a zero length > file, for my information only. This segment of > the program never did anything more than that. > I would not have noticed if it gave me a wrong > message, since I didn't follow up on it. > > The killer here is that this mistake caused the > contents of the file to be erased. Every file > ended up zero length. My guess is that it is > caused by the close() statement without a proper > file descriptor. fclose() will seg fault in this > case, but close() is more punishing. No, as Lew said, it's caused by passing some random address to open instead of an integer flag field. You got unlucky and set O_TRUNC along with O_RDWR. Jerry |