tmpnam question

S

Serve Laurijssen

What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?
 
R

Richard Bos

Serve Laurijssen said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

In effect, nothing.

Note, however, that for a filename generated by tmpnam() you should use
L_tmpnam, not FILENAME_MAX.
According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?

Your docs are wrong. Only the first call writes to the static buffer;
you then copy it to your own buffer by hand. The second call writes
directly to your buffer. The end result, in both cases, is that the
filename ends up in your buffer; the second case is likely, though not
guaranteed, to be slightly faster.

Richard
 
T

those who know me have no need of my name

in comp.lang.c i read:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?

think of it as saving you a strcpy. this can be handy in that tmpnam is
allowed to fail, in which case it returns a null pointer which makes your
first example have undefined behavior.

also, the standard doesn't say that an internal static buffer must be used
if a non-null pointer is provided. in fact it implies such a buffer need
not be used.
 
M

Mark Shelor

Serve said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?


The first form

char *p = tmpnam(NULL);

creates a string that is not the name of an existing file, and returns a
pointer to an internal static array containing the string.

The second form

char s[L_tmpnam];
char *p = tmpnam(s);

stores the string in "s" and returns a pointer to the character array
"s[]". In other words, "p" will be pointing to "s[]", not to the
internal static array.

The internal static buffer plays no observable role when using the
second form.

Some programmers may consider the first form more convenient, since
there's no need to define, and properly size, a character array before
calling tmpnam(NULL).

You can examine tmpnam's behavior by running the following program on
your system:

------------------

#include <stdio.h>

char t[L_tmpnam];

int main()
{
char s[L_tmpnam];
char *i;
char *p;

printf("%s\n", i = tmpnam(NULL));
printf("i = %p\n\n", i);

printf("%s\n", p = tmpnam(t));
printf("%s\n", i);
printf("t = %p\n", t);
printf("p = %p\n\n", p);

printf("%s\n", p = tmpnam(s));
printf("%s\n", i);
printf("s = %p\n", s);
printf("p = %p\n", p);

return(0);
}

------------------

The output I get on my system is:

/var/tmp/tmp.0.001345
i = 0x80009078

/var/tmp/tmp.1.001345
/var/tmp/tmp.0.001345
t = 0x20a0
p = 0x20a0

/var/tmp/tmp.2.001345
/var/tmp/tmp.0.001345
s = 0xbffff5f8
p = 0xbffff5f8


Mark
 
C

CBFalconer

Serve said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer.
What's the use of the parameter then (or the internal static buffer)?

from N869:

7.19.4.4 The tmpnam function

Synopsis
[#1]
#include <stdio.h>
char *tmpnam(char *s);

Description

[#2] The tmpnam function generates a string that is a valid
file name and that is not the same as the name of an
existing file.213)

____________________

213Files created using strings generated by the tmpnam
function are temporary only in the sense that their names
should not collide with those generated by conventional
naming rules for the implementation. It is still
necessary to use the remove function to remove such files
when their use is ended, and before program termination.


[#3] The tmpnam function generates a different string each
time it is called, up to TMP_MAX times. If it is called
more than TMP_MAX times, the behavior is implementation-
defined.

[#4] The implementation shall behave as if no library
function calls the tmpnam function.

Returns

[#5] If the argument is a null pointer, the tmpnam function
leaves its result in an internal static object and returns a
pointer to that object. Subsequent calls to the tmpnam
function may modify the same object. If the argument is not
a null pointer, it is assumed to point to an array of at
least L_tmpnam chars; the tmpnam function writes its result
in that array and returns the argument as its value.

Environmental limits

[#6] The value of the macro TMP_MAX shall be at least 25.
 
S

Serve Laurijssen

Serve Laurijssen said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?

I know it's OT but very important nonetheless. If I provide my own buffer
will that be safe in a multithreaded environment?
 
T

those who know me have no need of my name

in comp.lang.c i read:
I know it's OT but very important nonetheless.

then perhaps you should ask your important question where it can be
properly addressed.
 
M

Mark Shelor

Serve said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?


I know it's OT but very important nonetheless. If I provide my own buffer
will that be safe in a multithreaded environment?


It depends on how your buffer variable is defined.

Your code will not be thread-safe if the buffer is either an external
variable or a local static variable. Why not? Because asynchronously
operating threads can clobber each other's buffer data if there's only a
single copy of the buffer.

On the other hand, if a separate buffer is created for each thread, then
your code will be thread-safe. You can do this either by defining the
buffer as a local (i.e. automatic) variable, or by allocating separate
memory for it at runtime via malloc. The first approach is usually much
simpler.


#include <stdio.h>


/* Thread-safe */

void func1(void)
{
char buf[L_tmpnam];

tmpnam(buf);
...
}


/* NOT thread-safe */

void func2(void)
{
static char buf[L_tmpnam];

tmpnam(buf);
...
}


Mark
 
J

Jack Klein

Serve said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?


I know it's OT but very important nonetheless. If I provide my own buffer
will that be safe in a multithreaded environment?


It depends on how your buffer variable is defined.

Your code will not be thread-safe if the buffer is either an external
variable or a local static variable. Why not? Because asynchronously
operating threads can clobber each other's buffer data if there's only a
single copy of the buffer.

On the other hand, if a separate buffer is created for each thread, then
your code will be thread-safe.

[snip]

Please cite the reference to ANY version of the C language standard
that states that using tmpnam this way is "thread-safe". If not,
don't post such off-topic rubbish here.

There are no such things as threads defined or supported by the C
language, so there most certainly no guarantee that any usage of any
library function is "thread-safe".
 
J

Jack Klein

Serve Laurijssen said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?

I know it's OT but very important nonetheless. If I provide my own buffer
will that be safe in a multithreaded environment?

No, there is no way tmpnam can be "safe in a multithreaded
environment" on the Aztec C compiler for CP/M 80.

If you have a different implementation and platform in mind, you had
best consult the documentation or ask in a support group for that
combination.

Since ISO C neither defines nor supports threads, the only possible
answer here is "no", because there is no such thing as a multithreaded
environment.

And don't take the nonsense that Mark Shelor posted without
confirmation either. He might know how his particular compiler/OS
combination works, but neither you nor he know whether you use the
same combination that he does.
 
E

E. Robert Tisdale

Jack said:
There are no such things as threads defined or supported by the C
language, so there most certainly no guarantee that any usage of any
that any usage of any library function is "thread-safe".

Nonsense!

There certainly *are* guarantees that
C library functions are thread safe.
They are simply *not* specified by the ANSI/ISO C[89]9 standards.

Once again, you have blundered into a proclaimation
about implementations that are *not* specified by the standard.
 
M

Mark Shelor

Jack said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?

I know it's OT but very important nonetheless. If I provide my own buffer
will that be safe in a multithreaded environment?

No, there is no way tmpnam can be "safe in a multithreaded
environment" on the Aztec C compiler for CP/M 80.


Fascinating. But perhaps Serve is more concerned with 21st-century
programming than with relics from a computer museum <g>
 
P

Peter Pichler

E. Robert Tisdale said:
Nonsense!

Isn't it fantastic to snip quotes out of context? ;-)
There certainly *are* guarantees that
C library functions are thread safe.
They are simply *not* specified by the ANSI/ISO C[89]9 standards.

Remind me, what language do we discuss here?
 
R

Richard Bos

Mark Shelor said:
Serve said:
char buf[FILENAME_MAX];
tmpnam(buf);

I know it's OT but very important nonetheless.

So ask in a group that can give you a reliable answer. Unlike, say, Mr.
Shelor, because...
It depends on how your buffer variable is defined.

It depends on a lot more than that.
On the other hand, if a separate buffer is created for each thread, then
your code will be thread-safe.

You do not know that. The C Standard does not guarantee that _any_
Library function is thread-safe. In particular, tmpnam() might need some
internal state to generate the next free filename; you have no
guarantee, within the C Standard, that one threads might not be trying
to read this internal state while another is halfway through writing to
it. And no amount of _Standard_ C trickery is going to get rid of this
problem.
You really do need to know what platform, and even what implementation,
you are talking about; and then you need to ask the experts on _that_
platform, not some random VC++'er who thinks that the whole world is his
Windows boxlet.

Richard
 
P

pete

E. Robert Tisdale said:
Nonsense!

There certainly *are* guarantees that
C library functions are thread safe.

There is explicitly no guarantee.

N869
7.1.4 Use of library functions
[#4] The functions in the standard library are

not guaranteed

to be reentrant and may modify objects with
static storage duration.
 
P

pete

Mark said:
Fascinating. But perhaps Serve is more concerned with 21st-century
programming than with relics from a computer museum <g>

Perhaps Serve is more concerned with POSIX
and is wasting his time with clueless people,
who are here only because C, is the name of the only
programming language that they know how to spell ?
 
S

Servé Lau

Mark Shelor said:
Jack said:
What's the difference between

char buf[FILENAME_MAX];
strcpy(buf, tmpnam(NULL));

and
char buf[FILENAME_MAX];
tmpnam(buf);

According to my docs both calls write to an internal static buffer. What's
the use of the parameter then (or the internal static buffer)?

I know it's OT but very important nonetheless. If I provide my own buffer
will that be safe in a multithreaded environment?

No, there is no way tmpnam can be "safe in a multithreaded
environment" on the Aztec C compiler for CP/M 80.


Fascinating. But perhaps Serve is more concerned with 21st-century
programming than with relics from a computer museum <g>

I'm interested in getting work done in C, but getting something done is OT
here.
At least I know about L_tmpnam now.
 
C

Chris Torek

I'm interested in getting work done in C, but getting something done is OT
here.

Not necessarily -- if the "something" that has to get done can be
done entirely in Standard C, it can be on topic. (That does not
mean it necessarily *is* on-topic either. :) )
At least I know about L_tmpnam now.

L_tmpnam is topical; whether tmpnam() is reliable is not. (And,
though it is indeed OT, I will now mention that tmpnam() is *not*
reliable on many systems, for reasons that have nothing to do with
multithreaded code. In particular, one should never use it to
build file names to hold "sensitive" data on any multi-user POSIXy
system. To find out why, ask in comp.unix.programmer.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top