From: "John M. Aldrich" Newsgroups: comp.os.msdos.djgpp Subject: Re: why won't my .exe program run properly until I set env var? Date: Wed, 28 Jan 1998 19:35:15 -0500 Organization: Two pounds of chaos and a pinch of salt. Lines: 123 Message-ID: <34CFCEC3.6C89@cs.com> References: NNTP-Posting-Host: ppp213.cs.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk Zippy wrote: > > I am new to DJGPP, so this might be a dumb q, but here it goes... > > I run DJGPP within a DOS window in Windows95. I've got a batch file which > sets the path and the environment var. So the procedure I take to use > DJGPP is > 1. Start up a DOS window from windows95 > 2. Run the batch file (which has > set djgpp=c:\djgpp\djgpp.env > set path=c:\djgpp\bin;%path%) > 3. Start programming This is silly. If you plan to do a lot of programming in DJGPP, you should set the environment variables in your autoexec.bat so they always exist. I can't think of any possible reason why this wouldn't work better. > OK, I wrote a very short program that renames a file. > > #include > > main(int argc, char *argv[]) > { > char *d, *p, *n, *e; > int dummy = fnsplit(argv[1], d, p, n, e); > /* This splits a filename into drive, path, name and extension. */ > > dummy = rename("oldname.txt", strcat(n, ".txt")); > } You've got one serious problem right here: you never allocate memory for any of those pointers. Since they are uninitialized, fnsplit() and strcat() attempt to write to any old random memory locations and almost certainly crash as a result. This is basic C here, not a DJGPP-specific question. Pointers are not the easiest concept of C to grasp, but I don't understand why you thought they were needed in the first place. The following would have worked: char d[MAXDRIVE], p[MAXDIR], n[FILENAME_MAX], e[MAXEXT]; If you'd looked at the documentation for fnsplit() a bit more carefully, you'd have noticed that it says specifically that you need to provide buffers to store the data, and it even provides the above constants to use for the sizes. (Actually, FILENAME_MAX is defined by stdio.h, but you need to use it because MAXFILE might not be long enough to hold the filename plus the extension.) Also, it looks like the only item from fnsplit() that you are actually using is the filename itself, so why even bother with the other parameters? fnsplit( argv[1], NULL, NULL, n, NULL ); This works just as well and makes the purpose of the program clearer. Another style issue: it's not necessary to store the return value of a function if you don't need it. 'dummy' in your program is not only worthless (since you never check it), but it makes the program less clear. > The idea was to pass the new filename to the .exe program and rename the > file "oldname.txt" into the new one. > > I compiled the program by typing in > > gcc nameit.c -o nameit.exe Try adding the '-Wall', '-O', and '-g' switches to your command line. The additional warning and debugging information they provide can be priceless. For example, here's the output that resulted when I compiled your program: [WIN] D:\TEMP>gcc -Wall -O -g -o temp.exe temp.c temp.c:4: warning: return-type defaults to `int' temp.c: In function `main': temp.c:6: warning: implicit declaration of function `fnsplit' temp.c:9: warning: implicit declaration of function `strcat' temp.c:9: warning: passing arg 2 of `rename' makes pointer from integer without a cast temp.c:5: warning: `d' might be used uninitialized in this function temp.c:5: warning: `p' might be used uninitialized in this function temp.c:5: warning: `n' might be used uninitialized in this function temp.c:5: warning: `e' might be used uninitialized in this function temp.c:10: warning: control reaches end of non-void function In addition to the major bug I described above, this also reveals that you forgot to #include the header files that declare fnsplit() and strcat() (dir.h and string.h, respectively), and that it's not good programming practice to omit a function's return type. The last warning tells you that you forgot to put a 'return' statement at the end of main(). > Now I run the program by typing in > > nameit newname > > and the old file is rename to "newname.txt" The program works. It shouldn't. Probably there were some garbage values in the stack frame left by the C runtime code that just happened to point to valid addresses within your program when you ran it. The most likely reason for the crash when the DJGPP environment variable was defined is that the environment loading code left some other values in the stack that were not valid addresses, and therefore caused the crash. > Now, this is what I don't understand. Why do I need to set the variable > when I am running the stand-along .exe file? You don't. The fact that it crashed one way and not the other is total coincidence (albeit strange). :-) -- --------------------------------------------------------------------- | John M. Aldrich | "Autocracy is based on the assumption| | aka Fighteer I | that one man is wiser than a million | | mailto:fighteer AT cs DOT com | men. Let's play that over again, | | http://www.cs.com/fighteer | too. Who decides?" - Lazarus Long | ---------------------------------------------------------------------