[comp.std.c] Writeability of strings

rsalz@bbn.com (Rich Salz) (12/19/88)

Simple question.  Which is legal and/or "safer":

	char *foo = "/tmp/xxxxxx";
	(void)mktemp(foo);

	char *foo = mktemp("/tmp/xxxxxx");

	char foo[] = "/tmp/xxxxxx";
	(void)mktemp(foo);

	#define TEMPNAME "/tmp/xxxxxx";
	char foo[sizeof TEMPNAME];
	(void)mktemp(strcpy(foo, TEMPNAME));

Thanks!
	/rich $alz
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.

rsalz@bbn.com (Rich Salz) (12/20/88)

Simple question, fast answers...  In <1316@papaya.bbn.com> I asked:

>Simple question.  Which is legal and/or "safer":
>	char *foo = "/tmp/XXXXXX";
>	(void)mktemp(foo);
Bad code.  "Anonymous" strings can be stuck in ROM.  May 13 draft, page 71
(I have it, I should'a looked there first.)

>	char *foo = mktemp("/tmp/XXXXXX");
Bad code for the same reason.

>	char foo[] = "/tmp/XXXXXX";
>	(void)mktemp(foo);
Okay code, but might cause problems for some mktemp() routines (see below).

>	#define TEMPNAME "/tmp/XXXXXX";
>	char foo[sizeof TEMPNAME];
>	(void)mktemp(strcpy(foo, TEMPNAME));
This is the best.  Some versions of mktemp() will fail if given an ending
other than XXXXXX.  (The ones I'm familiar with just blithely assume they
can clobber the last six characters, and don't check, but I've just been
"lucky" I guess.)  David Koblas knows about a buggy mktemp() that goes one
step beyond, and suggested changing the declaration of foo to be
	char foo [sizeof TEMPNAME + 2];
which is kinda icky.

Chris Torek warns about compilers that think -- wrongly -- think
sizeof("string")==sizeof(char *), when it should be strlen("string") + 1.

>Thanks!
Thanks, indeed, to at least the following:
	Jerry Schwarz, AT&T Bell Labs, <jss@ulysses.att.com>
	David Koblas, MIPS Computer Systems, <koblas@mips.com>
	Chris Torek, University of Maryland, <chris@mimsy.umd.edu>
	John Haugh, <jfh@rpp386.dallas.tx.us>
	Karl Heuer, Interactive Systems, <karl@haddock.isc.com>
	Colin, Microsoft Corp., <uunet!microsof!w-colinp>

/rich $alz
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (12/20/88)

In article <1316@papaya.bbn.com> rsalz@bbn.com (Rich Salz) writes:
| Simple question.  Which is legal and/or "safer":
| 
| 	char *foo = "/tmp/xxxxxx";
| 	(void)mktemp(foo);
| 
| 	char *foo = mktemp("/tmp/xxxxxx");

  These will fail if you are not able to modify the value of a constant
string in memory.

| 	char foo[] = "/tmp/xxxxxx";
| 	(void)mktemp(foo);

  This may fail if used more than once (I got badly burned by this). The
behavior of mktmp is not predictable if the input string doesn't contain
the xxxxxx string. Some will fail, some will do nothing, and some will
append a six digit number to the end of the string. This last behavior,
in a system in which strings are writable, will cause the string to
become six chars longer with each call, until it trashes something and
the program dies. Some compilers also want to see { braces } around
array init, so 'char foo[] = {"string"};' is more portable. I learned
that the hard way, too.

| 	#define TEMPNAME "/tmp/xxxxxx";
| 	char foo[sizeof TEMPNAME];
| 	(void)mktemp(strcpy(foo, TEMPNAME));

  This should work in ANSI, UNIX or MS-DOS C environments (or any other
I can think of). You are starting with a fresh copy of the string each
time, in a variable.

-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me