basename C function on HPUX IDS misbehaving
Posted in 2007
Topics: Connectivity: ESQL/C, 4GL & Embedded SQL, Security, Permissions & Auditing
Hi, I am having a problem with migrating some esql code from Informix 10 to Informix 11.10FC1. The OS is HPUX 11i. The code does a lot of file handling tasks & uses the basename function which is in the libgen library. However when rebuilt on 11, this function is behaving strangely. The function takes a string which is the full pathname of a file, & removes the leading directories to leave you with just the file name. When I rebuild programs containing basename under Informix 11, the function does what it is supposed to - returns the filename - but it also actually removes the leading directories from parameter too. I enclose a test program I made which hopefully explains it. #include <stdio.h> #include <libgen.h> $include sqlca; $include sqltypes; int main(argc,argv) int argc; char *argv[]; { char buff1[100]; char buff2[100]; strcpy(buff1, "/full/path/filename"); printf("Before basename Buff1:%s\\ ", buff1); printf("Before basename Buff2:%s\\ ", buff2); strcpy(buff2, basename(buff1)); printf("After basename buff1:%s\\ ", buff1); printf("After basename buff2:%s\\ ", buff2); return(0); } When I build this under Informix 11 it gets built with the following arguments: /usr/informix11/bin/esql -e - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix11/incl/esql -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.ec /bin/cc - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix11/incl/esql -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.c /usr/informix11/bin/esql -o bntest bntest.o +DA2.0W -Wl,+s -L /usr/informix11/lib/esql -L /dev/Lib -L /syssoft/dev/Lib -L /usr/xdposm/xdpos/lib -limage -ltrace -lranda -lgemscommutil -leSQLisv The output of the program when I run it is: Before basename Buff1:/full/path/filename Before basename Buff2: After basename buff1:filename After basename buff2:filename N.B Buff1 has also lost the leading directories which is wrong!! If I export my INFORMIXDIR to be /usr/informix10 & rebuild with: /usr/informix10/bin/esql -e - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix10/incl/esql -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.ec /bin/cc - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix10/incl/esql -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.c /usr/informix10/bin/esql -o bntest bntest.o +DA2.0W -Wl,+s -L /usr/informix10/lib/esql -L /dev/Lib -L /syssoft/dev/Lib -L /usr/xdposm/xdpos/lib -limage -ltrace -lranda -lgemscommutil -leSQLisv and then run it again I get: Before basename Buff1:/full/path/filename Before basename Buff2: After basename buff1:/full/path/filename After basename buff2:filename N.B that buff1 never changed under the informix10 build - correct behaviour. Does any one have any ideas? TIA Johnny
JOHN SIMPSON wrote: > Hi, > > I am having a problem with migrating some esql code from Informix 10 to > Informix 11.10FC1. The OS is HPUX 11i. > The code does a lot of file handling tasks & uses the basename function which > is in the libgen library. However when rebuilt on 11, this function is > behaving strangely. The function takes a string which is the full pathname of > a file, & removes the leading directories to leave you with just the file > name. > When I rebuild programs containing basename under Informix 11, the function > does what it is supposed to - returns the filename - but it also actually > removes the leading directories from parameter too. > > I enclose a test program I made which hopefully explains it. On most platform basename (3) will modify its input argument. have a look under the USAGE or WARNINGS section of the man page, and I bet it will say so. in most cases you pass basename a copy of the string. > > #include <stdio.h> > #include <libgen.h> > $include sqlca; > $include sqltypes; > > int main(argc,argv) > > int argc; > char *argv[]; > > { > > char buff1[100]; > > char buff2[100]; > > strcpy(buff1, "/full/path/filename"); > > printf("Before basename Buff1:%s\\ ", buff1); > > printf("Before basename Buff2:%s\\ ", buff2); > > strcpy(buff2, basename(buff1)); > > printf("After basename buff1:%s\\ ", buff1); > > printf("After basename buff2:%s\\ ", buff2); > > return(0); > } > > When I build this under Informix 11 it gets built with the following > arguments: > > /usr/informix11/bin/esql -e - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z > -I/usr/informix11/incl/esql -I/syssoft/dev/CORE/Include > -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl > -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.ec > > /bin/cc - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix11/incl/esql > -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include > -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.c > > /usr/informix11/bin/esql -o bntest bntest.o +DA2.0W -Wl,+s -L > /usr/informix11/lib/esql -L /dev/Lib -L /syssoft/dev/Lib -L > /usr/xdposm/xdpos/lib -limage -ltrace -lranda -lgemscommutil -leSQLisv > > The output of the program when I run it is: > > Before basename Buff1:/full/path/filename > Before basename Buff2: > After basename buff1:filename > After basename buff2:filename > > N.B Buff1 has also lost the leading directories which is wrong!! > > If I export my INFORMIXDIR to be /usr/informix10 & rebuild with: > > /usr/informix10/bin/esql -e - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z > -I/usr/informix10/incl/esql -I/syssoft/dev/CORE/Include > -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl > -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.ec > > /bin/cc - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix10/incl/esql > -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include > -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.c > > /usr/informix10/bin/esql -o bntest bntest.o +DA2.0W -Wl,+s -L > /usr/informix10/lib/esql -L /dev/Lib -L /syssoft/dev/Lib -L > /usr/xdposm/xdpos/lib -limage -ltrace -lranda -lgemscommutil -leSQLisv > > and then run it again I get: > Before basename Buff1:/full/path/filename > Before basename Buff2: > After basename buff1:/full/path/filename > After basename buff2:filename > > N.B that buff1 never changed under the informix10 build - correct behaviour. > Does any one have any ideas? > > TIA > > Johnny -- Ciao, Marco ______________________________________________________________________________ Marco Greco /UK /IBM Standard disclaimers apply! Structured Query Scripting Language http://www.4glworks.com/sqsl.htm 4glworks http://www.4glworks.com Informix on Linux http://www.4glworks.com/ifmxlinux.htm
Thanks for responding Marco. There aren't any warnings in the HPUX man page about basename modifying its arguments. I do appreciate though that it would have been safer when our code was written to have used temporary variables as arguments. However, we didn't, & the 200 or so occurrences of basename in our code are now going to have to be changed.
On Dec 17, 2007 10:20 AM, JOHN SIMPSON <johnny@squarecross.org.uk> wrote: > Hi, > > I am having a problem with migrating some esql code from Informix 10 to > Informix 11.10FC1. The OS is HPUX 11i. > The code does a lot of file handling tasks & uses the basename function which > is in the libgen library. However when rebuilt on 11, this function is > behaving strangely. The function takes a string which is the full pathname of > a file, & removes the leading directories to leave you with just the file > name. As Marco said, that is the correct behaviour. The basename function is defined in POSIX to return a pointer to the last component of the file name, possibly after deleting trailing slashes. Clearly, it is mandated to modify the input argument; it is not clear that you'd expect it to do such a thorough job of mangling it. > When I rebuild programs containing basename under Informix 11, the function > does what it is supposed to - returns the filename - but it also actually > removes the leading directories from parameter too. > > I enclose a test program I made which hopefully explains it. > > #include <stdio.h> > #include <libgen.h> > $include sqlca; > $include sqltypes; > > int main(argc,argv) > int argc; > char *argv[]; > { > char buff1[100]; > char buff2[100]; > strcpy(buff1, "/full/path/filename"); > printf("Before basename Buff1:%s\\ ", buff1); > printf("Before basename Buff2:%s\\ ", buff2); > strcpy(buff2, basename(buff1)); > printf("After basename buff1:%s\\ ", buff1); > printf("After basename buff2:%s\\ ", buff2); > > return(0); > } > > When I build this under Informix 11 it gets built with the following > arguments: > > /usr/informix11/bin/esql -e - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z > -I/usr/informix11/incl/esql -I/syssoft/dev/CORE/Include > -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl > -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.ec > > /bin/cc - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix11/incl/esql > -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include > -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.c > > /usr/informix11/bin/esql -o bntest bntest.o +DA2.0W -Wl,+s -L > /usr/informix11/lib/esql -L /dev/Lib -L /syssoft/dev/Lib -L > /usr/xdposm/xdpos/lib -limage -ltrace -lranda -lgemscommutil -leSQLisv I don't see '-lgen' here. Does the esql script include it anyway? Have you checked your other libraries to see whether any of them defines a function 'basename'? > The output of the program when I run it is: > > Before basename Buff1:/full/path/filename > Before basename Buff2: > After basename buff1:filename > After basename buff2:filename > > N.B Buff1 has also lost the leading directories which is wrong!! That is certainly not what I'd expect. It would be interesting to print out the address of buff1 and the address returned by basename(), to see whether basename() is returning a point into your input buffer or is returning a pointer to its own storage. The manual page (for POSIX) says that the function returns a pointer to "." if the input is null, so there is no guarantee that it doesn't return a pointer to somewhere outside the input buffer. > If I export my INFORMIXDIR to be /usr/informix10 & rebuild with: > > /usr/informix10/bin/esql -e - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z > -I/usr/informix10/incl/esql -I/syssoft/dev/CORE/Include > -I/syssoft/dev/BOS/Include -I/usr/xdposm/xdpos/incl > -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.ec > > /bin/cc - -g -DTRACEON -DAUDITON -Ae +DA2.0W +z -I/usr/informix10/incl/esql > -I/syssoft/dev/CORE/Include -I/syssoft/dev/BOS/Include > -I/usr/xdposm/xdpos/incl -I/GEMSLIVE/ISV/bose/test/src/include -c bntest.c > /usr/informix10/bin/esql -o bntest bntest.o +DA2.0W -Wl,+s -L > /usr/informix10/lib/esql -L /dev/Lib -L /syssoft/dev/Lib -L > /usr/xdposm/xdpos/lib -limage -ltrace -lranda -lgemscommutil -leSQLisv > > and then run it again I get: > Before basename Buff1:/full/path/filename > Before basename Buff2: > After basename buff1:/full/path/filename > After basename buff2:filename This is what you'd expect. If you had "/full/path/filename////" as the input, you'd expect the trailing slashes to be truncated (overwritten), but... Same questions apply - and what was the C compiler command line? To get the C compiler command line for the linking step, you could use: INFORMIXC=echo in the environment (for that command only). Or you can use "sh -x $INFORMIXDIR/bin/esql ..."... The second generates a lot more output than the first. > N.B that buff1 never changed under the informix10 build - correct behaviour. > Does any one have any ideas? Not if nothing above helps... -- Jonathan Leffler #include <disclaimer.h> Email: jleffler@earthlink.net, jleffler@us.ibm.com Guardian of DBD::Informix v2007.0914 -- http://dbi.perl.org/ NB: Please do not use this email for correspondence. I don't necessarily read it every week, even.