Getting the file name from a FILE *

C

Chris Peters

The file name is the first parameter of the
fopen call. No matter what that is. That will
be returned.

Easy isn't it?

fopen remembers the file name, and that is what you get

WYGIWYO

What You Get Is What You Opened!

This sounds like a terrible idea to me. Consider a program that opens tens
of thousands of files simultaneously, all with long filenames, say 100 or
200 bytes each. You could easily be wasting 1MB or more just storing
copies of all the filenames in your standard library.
 
W

Walter Roberson

Chris Peters said:
Consider a program that opens tens
of thousands of files simultaneously, all with long filenames, say 100 or
200 bytes each. You could easily be wasting 1MB or more just storing
copies of all the filenames in your standard library.

As Jacob is writing the implementation of fopen(), he could choose to
limit the number of simultaneously open files, possibly even according
to whether he has "room" to store the new filename (though he
wouldn't want to get into compacting out holes in a static name
array, as that could end up moving filenames around after the name
pointer had already been made available to to program.)

On POSIX systems, the minimum maximum number of simultaneous open
files is just 16. 200 or 255 are common (traditionally the file
descriptor number was a single byte.)

Checking around a bit, I see that the default hard limit in NT
is 10000 files, and that apparently for some people that's a problem.
Odd. It's alterable, apparently,
http://support.microsoft.com/kb/326591/en-us
There's a mention of NetDDE (Dynamic Data Exchange) as being an
example of when it could be a problem. On the other hand,
NetDDE was removed from Windows Vista, it appears
http://en.wikipedia.org/wiki/Dynamic_Data_Exchange
 
J

jacob navia

Chris said:
This sounds like a terrible idea to me. Consider a program that opens tens
of thousands of files simultaneously, all with long filenames, say 100 or
200 bytes each. You could easily be wasting 1MB or more just storing
copies of all the filenames in your standard library.

If you open 10 thousand files with each a name of
256 chars, you get 256*10000-->2 560 000 bytes,
2MB.

Nothing for a machine that can open 10 000 files simultaneously.

Those machines have now routinely 1GB installed.
 
C

christian.bau

1) It is not difficult at all to see if the name still matches
    the contents of the file. Open the file with that name
    and compare the first bytes... If the data matches with the
    data in the still opened original file they are the same.
    That would make you immune against this quite rare problem.

That is pathetic. The customary way of updating files in MacOS X is to
write a copy of the modified file, then using a (non-standard C) call
to exchange the original and the modified file, and finally deleting
the original. If application B does that while your application A does
its clever thing, data loss is inevitable.
2) Under windows it is not possible to erase a file that is
    already open by another process, as far as I know. If
    under Unix, you have to take care that when you get the
    file name you should not assume that the file is still there.
    All this is not the problem of fopen.

You should really get used to looking a bit further than Windows.

What you are suggesting is in the end a function that returns the name
that was used to open a file, not the name of the file. That is
trivial to implement for anyone who wants it, and not very useful. If
you can implement a function that will either return the _correct_
name of a file or determine that there is no name, go ahead and do it.
 
K

Keith Thompson

jacob navia said:
The file name is the first parameter of the
fopen call. No matter what that is. That will
be returned.

Easy isn't it?
[...]

Not really.

What if the file wasn't opened via fopen()?

Among standard functions, tmpfile() and freopen() probably aren't much
of a problem, but you at least need to think about them.

There might be more serious problems if you support non-standard
functions that return FILE* results (popen(), for example).

(In your initial description, you mentioned "lower case"; re-reading
it, I think you were referring to the name "fopen", not to the result
it returns.)
 
R

Richard Tobin

1) It is not difficult at all to see if the name still matches
the contents of the file. Open the file with that name
and compare the first bytes... If the data matches with the
data in the still opened original file they are the same.
That would make you immune against this quite rare problem.

But why would you want to do this at all? If you already have the
file open, why open it again? Just what is the problem you are trying
to solve?

The most obvious use for having the file name is to give better error
messages (as in your example), and for that none of these issues are
important. So long as users understand the limited uses of the file
name, it seems like a handy addition.

-- Richard
 
R

Richard Tobin

christian.bau said:
You should really get used to looking a bit further than Windows.

If you're selling a compiler that only works with Windows, it doesn't
matter that your extensions rely on Windoziness.
What you are suggesting is in the end a function that returns the name
that was used to open a file, not the name of the file. That is
trivial to implement for anyone who wants it, and not very useful.

It's very useful for producing better error messages, and can't be
reasonably implemented by the user without changing existing
interfaces.

-- Richard
 
R

Richard Tobin

Chris Peters said:
This sounds like a terrible idea to me. Consider a program that opens tens
of thousands of files simultaneously, all with long filenames, say 100 or
200 bytes each. You could easily be wasting 1MB or more just storing
copies of all the filenames in your standard library.

And each of them quite likely has a buffer associated with it. By
comparison the filename is unlikely to be significant, and of course
most filenames aren't anything like 200 bytes.

A more important limitation, mentioned in various forms by other
posters, is that many files just aren't opened by fopen() in the
current process. They're inherited, or are pipes or sockets or
who-knows-what. But perhaps that's rarer in Windows, and in any case
it's handy to have the filename for those cases where it is possible.

-- Richard
 
I

Ian Collins

Richard said:
If you're selling a compiler that only works with Windows, it doesn't
matter that your extensions rely on Windoziness.

Until you try to port either the compiler or the code that builds with
it. Sounds like M$ standard practice :)
 
R

Richard

CBFalconer said:
Many large problems on Linux/Unix. A file may be accessed via a
name, but once open it is nameless, and may well be identical to a
file opened with another program under another name, including
using identical storage. This is simply not a possible function.
If you want to know what name you used to open it, all you have to
do is remember it.

Just because things work on primitive operating systems, such as
Winders, doesn't mean they can work everywhere.

There is no such OS as Winders as far as I know. Please refrain from
using silly slang in a technical news group - as you frequently remind
others.
 
S

Serve Lau

jacob navia said:
What problems could arise with this function? Why is not in the C API?

I wouldn't put this in libc, it's something people can add themselves easily
when they need it.

But anyway, how will you store the strings? You cant store pointers so you
have to go for string copying. But how large will you make the arrays you
will copy the names into? And will you provide a wide char version too for
consistency?
 
R

Richard Tobin

Serve Lau said:
But anyway, how will you store the strings? You cant store pointers so you
have to go for string copying. But how large will you make the arrays you
will copy the names into?

How about the right length? Are you suggesting that there's some
reason why fopen() shouldn't malloc() the space?

-- Richard
 
S

Serve Lau

Richard Tobin said:
How about the right length? Are you suggesting that there's some
reason why fopen() shouldn't malloc() the space?

That will require more knowledge of internal workings of standard C
functions which is IMO never a good thing.
 
R

Richard Tobin

That will require more knowledge of internal workings of standard C
functions which is IMO never a good thing.

I'm baffled. Aren't we talking about Jacob's implementation?
He's the implementor of the functions, he's supposed to know
about their internal workings.

-- Richard
 
J

jacob navia

Serve said:
But anyway, how will you store the strings? You cant store pointers so
you have to go for string copying. But how large will you make the
arrays you will copy the names into? And will you provide a wide char
version too for consistency?

I *can* store pointers.

fopen:

File->FileName = strdup(fname);

fclose:
free(File->FileName);
 
R

Ralf Damaschke

Serve said:
That will require more knowledge of internal workings of standard C
functions which is IMO never a good thing.

What knowledge of internal workings am I required to know for writing:
#include <stdlib.h>
char *s = NULL;
void foo(char *bar) {if (s = malloc(strlen(bar)+1)) strcpy(s, bar);}

Besides, the implementor of fopen() really should have knowledge of
the internal working of standard C functions like fgetc, fwrite, etc.

Ralf
 
W

Walter Roberson

How about the right length? Are you suggesting that there's some
reason why fopen() shouldn't malloc() the space?

I do not have my C89 hardcopy here to check against. I know that there
are various routines that are marked with wording similar to
"The implementation shall behave as if no library routine
calls <name>". I do not recall if malloc() is one of those routines ?
 
S

Serve Lau

Richard Tobin said:
I'm baffled. Aren't we talking about Jacob's implementation?
He's the implementor of the functions, he's supposed to know
about their internal workings.

I meant the people *using* fopen. What if malloc fails? Should fopen return
NULL suddenly while the file couldve been opened?
 
S

Serve Lau

jacob navia said:
I *can* store pointers.

fopen:

File->FileName = strdup(fname);

fclose:
free(File->FileName);

Yes but it can fail. Will fopen return NULL on failure of strdup or return a
valid FILE pointer. When the buffer fails to be allocated in fopen this is a
critical error and fopen should return NULL but not being able to allocate
the filename is not crititical and if you return NULL one cant distingish
between allocation failure and "non named files" anymore. I really think you
should keep this out the library and let clients deal with this who have
more context in their own programs anyway.
 
S

santosh

Walter said:
The implementation shall behave as if no library routine
calls

From n1256:

7.11.1.1(5)
The implementation shall behave as if no library function calls the
setlocale function.

7.11.2.1(7)
The implementation shall behave as if no library function calls the
localeconv function.

7.14.1.1(7)
The implementation shall behave as if no library function calls the
signal function.

7.19.4.4(4)
The implementation shall behave as if no library function calls the
tmpnam function.

7.20.2.1(3)
The implementation shall behave as if no library function calls the rand
function.

7.20.2.2(3)
The implementation shall behave as if no library function calls the
srand function.

7.20.4.5(3)
The implementation shall behave as if no library function calls the
getenv function.

7.20.7.1(3)
The implementation shall behave as if no library function calls the
mblen function.

7.20.7.2(3)
The implementation shall behave as if no library function calls the
mbtowc function.

7.20.7.3(3)
The implementation shall behave as if no library function calls the
wctomb function.

7.21.5.8(6)
The implementation shall behave as if no library function calls the
strtok function.

7.21.6.2(3)
The implementation shall behave as if no library function calls the
strerror function.

7.24.6.3(1)
Restartable multibyte/wide character conversion functions
[ ... ]
The implementation behaves as if no library function calls these
functions with a null pointer for ps.

7.24.6.4(1)
Restartable multibyte/wide string conversion functions.
[ ... ]
The implementation behaves as if no library function calls these
functions with a null pointer for ps.
 

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

Members online

No members online now.

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top