Discussion:
The remove function
(too old to reply)
FrankHB1989
2015-04-22 19:00:17 UTC
Permalink
Raw Message
Current wording in N1570 for remove function (7.21.4.1) seems to be not very clear about meaning of "success". If the file did not exist, the function call can be still considered successful according to Description. This should be not intended. Can it be improved?
Jakob Bohm
2015-04-22 19:21:27 UTC
Permalink
Raw Message
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be not very clear about meaning of "success". If the file did not exist, the function call can be still considered successful according to Description. This should be not intended. Can it be improved?
I guess, in practice, programs will be subject to the limitations of
the underlying storage subsystems API limitations, so regardless what
the C standard demands, real world standards and non-standards such
as POSIX, Win32, NFS, AFS, SMB, WebDAV etc. will each impose the
ability or inability of any C implementation to distinguish between
"successfully removed previously existing file" and "successfully
detected that removing already non-existing file would be a trivial
NOP" .

Thus the C language standard cannot require the function to report
those two cases differently in all conforming hosted implementations,
as that would make it impossible to actually create conforming hosted
implementations on a number of systems, including any OS which allows
3rd party file systems with their own remove() semantics to be added
at runtime (This happens to include most major and several minor
operating systems).

In practice, programmers that care usually wrap remove() in a wrapper
which maps failure with errno==ENOENT etc. to success. Very few
programs actually want to fail because deleting a file turned out to
be a NOP.

Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded
FrankHB1989
2015-04-26 05:26:33 UTC
Permalink
Raw Message
在 2015年4月23日星期四 UTC+8上午3:21:29,Jakob Bohm写道:
Post by Jakob Bohm
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be not very clear about meaning of "success". If the file did not exist, the function call can be still considered successful according to Description. This should be not intended. Can it be improved?
I guess, in practice, programs will be subject to the limitations of
the underlying storage subsystems API limitations, so regardless what
the C standard demands, real world standards and non-standards such
as POSIX, Win32, NFS, AFS, SMB, WebDAV etc. will each impose the
ability or inability of any C implementation to distinguish between
"successfully removed previously existing file" and "successfully
detected that removing already non-existing file would be a trivial
NOP" .
Thus the C language standard cannot require the function to report
those two cases differently in all conforming hosted implementations,
as that would make it impossible to actually create conforming hosted
implementations on a number of systems, including any OS which allows
3rd party file systems with their own remove() semantics to be added
at runtime (This happens to include most major and several minor
operating systems).
In practice, programmers that care usually wrap remove() in a wrapper
which maps failure with errno==ENOENT etc. to success. Very few
programs actually want to fail because deleting a file turned out to
be a NOP.
Enjoy
Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded
Sounds somewhat reasonable. However, the standard could have made it clearer, to cover that real world usage (errno==ENOENT etc), or at least, to mention this situation to be "implementation-defined". Then it would not be a problem.
Lew Pitcher
2015-04-22 19:39:57 UTC
Permalink
Raw Message
On Wednesday April 22 2015 15:00, in comp.std.c, "FrankHB1989"
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be not
very clear about meaning of "success". If the file did not exist, the
function call can be still considered successful according to Description.
This should be not intended. Can it be improved?
I have no problem with remove() returning 0 (for success) if the specified
file does not exist prior to the remove() call.

The goal is to ensure that a named file "is no longer accessable by that
name". Assume that the file named as the argument to remove() does not
actually exist in the filesystem prior to the call to remove(); on return
of remove(), is there a file "accessable by that name"? If not, then
remove() was successful (because it's purpose is to ensure that the file is
not accessable by the specified name).

If remove() returned a failure condition (nonzero returncode), then it would
be difficult to avoid synchronization problems while ensuring that a
specified filename is not accessable;

HTH
--
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request
FrankHB1989
2015-04-26 05:40:36 UTC
Permalink
Raw Message
在 2015年4月23日星期四 UTC+8上午3:39:59,Lew Pitcher写道:
Post by Lew Pitcher
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be not
very clear about meaning of "success". If the file did not exist, the
function call can be still considered successful according to Description.
This should be not intended. Can it be improved?
I have no problem with remove() returning 0 (for success) if the specified
file does not exist prior to the remove() call.
The goal is to ensure that a named file "is no longer accessable by that
name". Assume that the file named as the argument to remove() does not
actually exist in the filesystem prior to the call to remove(); on return
of remove(), is there a file "accessable by that name"? If not, then
remove() was successful (because it's purpose is to ensure that the file is
not accessable by the specified name).
If remove() returned a failure condition (nonzero returncode), then it would
be difficult to avoid synchronization problems while ensuring that a
specified filename is not accessable;
HTH
--
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request
I personally like this idea, too. This is natural (without some errno mess). However, some major real world implementations, notably POSIX compliant environments and msvcrt, seem not want to do like this. According to the current wording, they do nothing wrong. One worse thing is it could once confused readers before they actually meet this inconsistency.
Kaz Kylheku
2015-04-22 19:40:32 UTC
Permalink
Raw Message
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be not very
clear about meaning of "success". If the file did not exist, the function
call can be still considered successful according to Description. This should
be not intended. Can it be improved?
The function can be regarded as successful because after its execution, the
file does not exist, and so cannot be opened.

Success can be defined according to the truth value of the proposition

"if P then Q"

where P denotes the truth value of the statement "the file exists before remove
is called" and Q denotes that of "file does not exist after remove is called".

This proposition is only false (not successful) in the case when "P and not Q"
is true. (The file exists prior to execution, file still exists after
execution).

Of course, actual implemenations of remove indicate a failed status
to distinguish this case. On Unixes, -1 is returned and errno is set to ENOENT
if some component of the path name does not exist or is a dangling symlink.

I can imagine an implementation that doesn't care, where zero is returned to
simply indicate that all is well and the object now doesn't exist, as required.
James Kuyper
2015-04-22 19:42:19 UTC
Permalink
Raw Message
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.

The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
Keith Thompson
2015-04-22 20:20:51 UTC
Permalink
Raw Message
Post by James Kuyper
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
POSIX says that remove() is equivalent to unlink() if the name file is
not a directory, or to rmdir() if it is.

For unlink():
http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html

These functions shall fail and shall not unlink the file if:
...

[ENOENT]
A component of path does not name an existing file or path is an
empty string.

This is one of 9 permitted errno values. It's also consistent with the
behavior I see on my system.

I don't remember the exact relationship between the Single Unix
Specification and POSIX. Can you check your source again? Does it
really not mention ENOENT as an error condition for unlink()?
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
James Kuyper
2015-04-22 21:10:33 UTC
Permalink
Raw Message
On 04/22/2015 04:20 PM, Keith Thompson wrote:
...
Post by Keith Thompson
POSIX says that remove() is equivalent to unlink() if the name file is
not a directory, or to rmdir() if it is.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html
...
[ENOENT]
A component of path does not name an existing file or path is an
empty string.
This is one of 9 permitted errno values. It's also consistent with the
behavior I see on my system.
I don't remember the exact relationship between the Single Unix
Specification and POSIX. Can you check your source again? Does it
really not mention ENOENT as an error condition for unlink()?
No, it's just another mistake on my part. I must have missed that line
because I was looking for somewhat different wording - something like
"does not exist" rather than "does not name an existing".
Wojtek Lerch
2015-04-23 03:19:21 UTC
Permalink
Raw Message
On 22/04/2015 4:20 PM, Keith Thompson wrote:
...
Post by Keith Thompson
http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html
...
Post by Keith Thompson
I don't remember the exact relationship between the Single Unix
Specification and POSIX. Can you check your source again? Does it
really not mention ENOENT as an error condition for unlink()?
The SUS and POSIX were merged into a single document around 2001. There
are parts that POSIX considers optional -- those are marked [XSI] in the
text, such as the explanation of EPERM or EACCESS in the context of the
S_ISVTX flag on the unlink() page that you quoted from.
FrankHB1989
2015-04-26 05:59:35 UTC
Permalink
Raw Message
Post by James Kuyper
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
Hmm... I meant the unclear requirements are not that ideal.
Anyway, the implementation is free to set errno here, whether it is an error:

7.5
3 ... The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.

But the return value is just not the case.
James Kuyper
2015-04-27 15:32:19 UTC
Permalink
Raw Message
Post by FrankHB1989
Post by James Kuyper
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that this
was unintentional, in which case it's an indication that there's a
defect in the description. However, I'm suggesting that it might be
intentional. In that case, the description of what the function is
supposed to do led you to the correct conclusion that it had been
successful, and that the return value should therefore be zero - despite
the fact that you didn't think that conclusion was correct! A
description capable of getting you to reach the correct conclusion
despite not expecting it to be correct seems like a reasonably clear
description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or against C
conformance, but as evidence that the people who chose those values did
not consider the non-existence of the file to be remove()d as an error
condition. As a result, they would see nothing odd about having remove()
return a "success"
FrankHB1989
2015-05-01 17:07:45 UTC
Permalink
Raw Message
在 2015年4月27日星期一 UTC+8下午11:32:21,James Kuyper写道:
Post by James Kuyper
Post by FrankHB1989
Post by James Kuyper
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that this
was unintentional, in which case it's an indication that there's a
defect in the description. However, I'm suggesting that it might be
intentional. In that case, the description of what the function is
supposed to do led you to the correct conclusion that it had been
successful, and that the return value should therefore be zero - despite
the fact that you didn't think that conclusion was correct! A
description capable of getting you to reach the correct conclusion
despite not expecting it to be correct seems like a reasonably clear
description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or against C
conformance, but as evidence that the people who chose those values did
not consider the non-existence of the file to be remove()d as an error
condition. As a result, they would see nothing odd about having remove()
return a "success"
OK, it might be intentional, as you said: even if the file did not exist, the operation made by call of remove() can still be considered successful (then zero would be returned).
However, some conforming implementations do not behave like this, e.g. msvcrt and POSIX, as I mentioned before.
Then comes the realistic problem: how to deal with the return value in a portable way?
Does it means that the return value is totally implementation-dependent, or only makes sence when the existence of file is guaranteed just before the call?
If so, there should be at least a note. Ideally, it should be explicit as "if the file is open, the behavior of the remove function is implementation-defined".
Thus I'm still not very convinced (it is intentional to omit the decription about this topic).
Tim Rentsch
2015-05-02 05:42:53 UTC
Permalink
Raw Message
[posting from James Kuyper]
Post by James Kuyper
Post by FrankHB1989
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to
be not very clear about meaning of "success". If the file did
not exist, the function call can be still considered successful
according to Description. This should be not intended. Can it
be improved?
Are you sure it's not intended? I wasn't involved in the
decision, so I don't know. There's nothing about this issue in C
Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C
standard is unintentional." It identifies the value of errno
(which the C standard leaves unspecified, so this is not a
conflict) by cross-reference to the description of unlink()
(which is not a C standard function). The file not existing
corresponds to none of the specified errno values. The length of
that list (9 permitted non-zero errno values) suggests that they
put a fair amount of thought into the error conditions, without
concluding that the non-existence of the specified file should be
treated as one. I'd think it would be hard to do that by
accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that
this was unintentional, in which case it's an indication that
there's a defect in the description. However, I'm suggesting that
it might be intentional. In that case, the description of what the
function is supposed to do led you to the correct conclusion that
it had been successful, and that the return value should therefore
be zero - despite the fact that you didn't think that conclusion
was correct! A description capable of getting you to reach the
correct conclusion despite not expecting it to be correct seems
like a reasonably clear description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library
function call whether or not there is an error, provided the use
of errno is not documented in the description of the function in
this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or
against C conformance, but as evidence that the people who chose
those values did not consider the non-existence of the file to be
remove()d as an error condition. As a result, they would see
nothing odd about having remove() return a "success"
OK, it might be intentional, as you said: even if the file did
not exist, the operation made by call of remove() can still be
considered successful (then zero would be returned).
However, some conforming implementations do not behave like this,
e.g. msvcrt and POSIX, as I mentioned before.
Then comes the realistic problem: how to deal with the return
value in a portable way?
Does it means that the return value is totally implementation
dependent, or only makes sence when the existence of file is
guaranteed just before the call?
If so, there should be at least a note. Ideally, it should be
explicit as "if the file is open, the behavior of the remove
function is implementation-defined".
Thus I'm still not very convinced (it is intentional to omit the
decription about this topic).
I think the problem here is you are confusing conformance and
quality of implementation.

An implementation is free to implement remove() by making no
attempt at all to remove any file, and always returning 1 (ie, a
non-success value). Such an implementation leaves something to
be desired quality-wise, but it would still be conforming.

Similarly an implementation could give good results most of the
time, but always fail on Tuesdays. Likewise all sorts of other
variations on this theme - we might not like what they do, but
they would be conforming.

I am not privy to any inside information about what was intended
for the remove() function. However, given what has been said
elsewhere about such considerations, in documents both official
and unofficial, I am confident that this seemingly lax outcome
was indeed intended, with full awareness of what that entails.
The Standard concerns itself with matters of conformance; it
deliberately does not concern itself with matters of quality of
implementation. That may seem rather odd, but there is no doubt
that this principle is what was decided, and IMO that distinction
has served the goals of standardization better than a different
choice there would have.
FrankHB1989
2015-05-05 01:31:52 UTC
Permalink
Raw Message
在 2015年5月2日星期六 UTC+8下午1:42:56,Tim Rentsch写道:
Post by Tim Rentsch
[posting from James Kuyper]
Post by James Kuyper
Post by FrankHB1989
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to
be not very clear about meaning of "success". If the file did
not exist, the function call can be still considered successful
according to Description. This should be not intended. Can it
be improved?
Are you sure it's not intended? I wasn't involved in the
decision, so I don't know. There's nothing about this issue in C
Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C
standard is unintentional." It identifies the value of errno
(which the C standard leaves unspecified, so this is not a
conflict) by cross-reference to the description of unlink()
(which is not a C standard function). The file not existing
corresponds to none of the specified errno values. The length of
that list (9 permitted non-zero errno values) suggests that they
put a fair amount of thought into the error conditions, without
concluding that the non-existence of the specified file should be
treated as one. I'd think it would be hard to do that by
accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that
this was unintentional, in which case it's an indication that
there's a defect in the description. However, I'm suggesting that
it might be intentional. In that case, the description of what the
function is supposed to do led you to the correct conclusion that
it had been successful, and that the return value should therefore
be zero - despite the fact that you didn't think that conclusion
was correct! A description capable of getting you to reach the
correct conclusion despite not expecting it to be correct seems
like a reasonably clear description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library
function call whether or not there is an error, provided the use
of errno is not documented in the description of the function in
this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or
against C conformance, but as evidence that the people who chose
those values did not consider the non-existence of the file to be
remove()d as an error condition. As a result, they would see
nothing odd about having remove() return a "success"
OK, it might be intentional, as you said: even if the file did
not exist, the operation made by call of remove() can still be
considered successful (then zero would be returned).
However, some conforming implementations do not behave like this,
e.g. msvcrt and POSIX, as I mentioned before.
Then comes the realistic problem: how to deal with the return
value in a portable way?
Does it means that the return value is totally implementation
dependent, or only makes sence when the existence of file is
guaranteed just before the call?
If so, there should be at least a note. Ideally, it should be
explicit as "if the file is open, the behavior of the remove
function is implementation-defined".
Thus I'm still not very convinced (it is intentional to omit the
decription about this topic).
I think the problem here is you are confusing conformance and
quality of implementation.
No. I think I am quite clear on it.
Post by Tim Rentsch
An implementation is free to implement remove() by making no
attempt at all to remove any file, and always returning 1 (ie, a
non-success value). Such an implementation leaves something to
be desired quality-wise, but it would still be conforming.
Yes, it is the status quo. However, I'm doubtful this freedom should be completely kept intentionally, for realistic reasons.
Post by Tim Rentsch
Similarly an implementation could give good results most of the
time, but always fail on Tuesdays. Likewise all sorts of other
variations on this theme - we might not like what they do, but
they would be conforming.
If this is true, then it is not only about QoI. It also makes the interface provided by the standard less useful and the current wording of return value almost totally redundant, i.e. it effects the quality of the standard itself.

Note I don't mean the conformance must change. For example, by explictly state the meaning of "success" is "unspecified", nothing would be need for any implementations. Although it is nonsense, practically.

And if "implementation-defined" descriptions are accepted, the impact would be minimal. Actually I have not seen an implementation whose documentation said nothing clearer than the standard here.
Tim Rentsch
2015-05-05 04:33:20 UTC
Permalink
Raw Message
Post by Tim Rentsch
[posting from James Kuyper]
Post by James Kuyper
Post by FrankHB1989
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to
be not very clear about meaning of "success". If the file did
not exist, the function call can be still considered successful
according to Description. This should be not intended. Can it
be improved?
Are you sure it's not intended? I wasn't involved in the
decision, so I don't know. There's nothing about this issue in C
Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C
standard is unintentional." It identifies the value of errno
(which the C standard leaves unspecified, so this is not a
conflict) by cross-reference to the description of unlink()
(which is not a C standard function). The file not existing
corresponds to none of the specified errno values. The length of
that list (9 permitted non-zero errno values) suggests that they
put a fair amount of thought into the error conditions, without
concluding that the non-existence of the specified file should be
treated as one. I'd think it would be hard to do that by
accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that
this was unintentional, in which case it's an indication that
there's a defect in the description. However, I'm suggesting that
it might be intentional. In that case, the description of what the
function is supposed to do led you to the correct conclusion that
it had been successful, and that the return value should therefore
be zero - despite the fact that you didn't think that conclusion
was correct! A description capable of getting you to reach the
correct conclusion despite not expecting it to be correct seems
like a reasonably clear description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library
function call whether or not there is an error, provided the use
of errno is not documented in the description of the function in
this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or
against C conformance, but as evidence that the people who chose
those values did not consider the non-existence of the file to be
remove()d as an error condition. As a result, they would see
nothing odd about having remove() return a "success"
OK, it might be intentional, as you said: even if the file did
not exist, the operation made by call of remove() can still be
considered successful (then zero would be returned).
However, some conforming implementations do not behave like this,
e.g. msvcrt and POSIX, as I mentioned before.
Then comes the realistic problem: how to deal with the return
value in a portable way?
Does it means that the return value is totally implementation
dependent, or only makes sence when the existence of file is
guaranteed just before the call?
If so, there should be at least a note. Ideally, it should be
explicit as "if the file is open, the behavior of the remove
function is implementation-defined".
Thus I'm still not very convinced (it is intentional to omit the
decription about this topic).
I think the problem here is you are confusing conformance and
quality of implementation.
No. I think I am quite clear on it.
Post by Tim Rentsch
An implementation is free to implement remove() by making no
attempt at all to remove any file, and always returning 1 (ie, a
non-success value). Such an implementation leaves something to
be desired quality-wise, but it would still be conforming.
Yes, it is the status quo. However, I'm doubtful this freedom
should be completely kept intentionally, for realistic reasons.
Post by Tim Rentsch
Similarly an implementation could give good results most of the
time, but always fail on Tuesdays. Likewise all sorts of other
variations on this theme - we might not like what they do, but
they would be conforming.
If this is true, then it is not only about QoI. It also makes the
interface provided by the standard less useful and the current
wording of return value almost totally redundant, i.e. it effects
the quality of the standard itself.
Note I don't mean the conformance must change. For example, by
explictly state the meaning of "success" is "unspecified", nothing
would be need for any implementations. Although it is nonsense,
practically. [snip]
In that case I simply disagree. IMO the current wording admits
both possibilities, ie, remove() on a non-existent file can
either succeed or fail, and both behaviors are conforming. If
that is indeed what was intended then I see no reason to change
any text in the Standard. If it bothers you, submit a Defect
Report.
m***@acm.org
2015-05-01 18:42:01 UTC
Permalink
Raw Message
Post by James Kuyper
Post by FrankHB1989
Post by James Kuyper
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that this
was unintentional, in which case it's an indication that there's a
defect in the description. However, I'm suggesting that it might be
intentional. In that case, the description of what the function is
supposed to do led you to the correct conclusion that it had been
successful, and that the return value should therefore be zero - despite
the fact that you didn't think that conclusion was correct! A
description capable of getting you to reach the correct conclusion
despite not expecting it to be correct seems like a reasonably clear
description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or against C
conformance, but as evidence that the people who chose those values did
not consider the non-existence of the file to be remove()d as an error
condition. As a result, they would see nothing odd about having remove()
return a "success"
Hmm. Very interesting. I'm looking at the BSD Unix man page for unlink(), which is referenced by the man page for remove(), and there are 13 possible errno values listed, including ENOENT, which indicates the named file does not exist.

So at least some systems, it seems, would see something odd about having remove() return success for a file that did not exist.

Randy.
Francis Glassborow
2015-05-01 22:26:28 UTC
Permalink
Raw Message
Post by m***@acm.org
Post by James Kuyper
Post by FrankHB1989
Post by James Kuyper
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that this
was unintentional, in which case it's an indication that there's a
defect in the description. However, I'm suggesting that it might be
intentional. In that case, the description of what the function is
supposed to do led you to the correct conclusion that it had been
successful, and that the return value should therefore be zero - despite
the fact that you didn't think that conclusion was correct! A
description capable of getting you to reach the correct conclusion
despite not expecting it to be correct seems like a reasonably clear
description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or against C
conformance, but as evidence that the people who chose those values did
not consider the non-existence of the file to be remove()d as an error
condition. As a result, they would see nothing odd about having remove()
return a "success"
Hmm. Very interesting. I'm looking at the BSD Unix man page for unlink(), which is referenced by the man page for remove(), and there are 13 possible errno values listed, including ENOENT, which indicates the named file does not exist.
So at least some systems, it seems, would see something odd about having remove() return success for a file that did not exist.
Randy.
However I think we should consider what we want to happen if two threads
both try to remove the same file. In a sense it does not matter which
one removes it first because the file has been removed.

Are we able to make it implementation defined whether an attempt to
remove a file that does not exist returns true or false? I note that
this is another of those awkward function where 0 means success. However
we could define a return of a negative value as 'file does not exist'
that leaves all positive values as other problems. Now we would have a
portable way to test the return value.

Francis
Wojtek Lerch
2015-05-02 21:56:31 UTC
Permalink
Raw Message
Post by Francis Glassborow
Are we able to make it implementation defined whether an attempt to
remove a file that does not exist returns true or false? I note that
this is another of those awkward function where 0 means success. However
we could define a return of a negative value as 'file does not exist'
that leaves all positive values as other problems. Now we would have a
portable way to test the return value.
That would conflict with POSIX, which requires the function to return
either 0 or -1, nothing else.

BTW I just had a closer look at the text -- it says that remove()
"causes the file whose name is the string pointed to by filename
to be no longer accessible by that name". If such a file didn't exist
in the first place, how can the function claim to have successfully
caused its non-existence? If the text really means to allow that
interpretation, wouldn't it be clearer to say something like "ensures"
instead of "causes", and also perhaps "any file" instead of "the file"?
Francis Glassborow
2015-05-02 23:42:18 UTC
Permalink
Raw Message
Post by Wojtek Lerch
Post by Francis Glassborow
Are we able to make it implementation defined whether an attempt to
remove a file that does not exist returns true or false? I note that
this is another of those awkward function where 0 means success. However
we could define a return of a negative value as 'file does not exist'
that leaves all positive values as other problems. Now we would have a
portable way to test the return value.
That would conflict with POSIX, which requires the function to return
either 0 or -1, nothing else.
BTW I just had a closer look at the text -- it says that remove()
"causes the file whose name is the string pointed to by filename
to be no longer accessible by that name". If such a file didn't exist
in the first place, how can the function claim to have successfully
caused its non-existence? If the text really means to allow that
interpretation, wouldn't it be clearer to say something like "ensures"
instead of "causes", and also perhaps "any file" instead of "the file"?
What is all this about existence. Look at what you quoted. It merely
talks about access by a name in a string. According to that it would be
perfectly OK to simply rename the file.

In addition there is a great deal of difference between a remove failing
because there is not accessible file by that name, and failing because
the file system refuses to allow the program to turn of access to the
file by that name.

IME the usual reason for calling remove() is that the programmer wants
to reuse the name. S/he does not then care if the name currently
designates a file, just that the name is free for use.

Lewis Carroll would greatly enjoyed the difference between accessing a
file by a name and the existence of the file possibly accessed by a
different name.

I think that it is time that WG14 had another look particularly in the
context of concurrency.
Wojtek Lerch
2015-05-03 04:06:15 UTC
Permalink
Raw Message
...
Post by Francis Glassborow
Post by Wojtek Lerch
BTW I just had a closer look at the text -- it says that remove()
"causes the file whose name is the string pointed to by filename
to be no longer accessible by that name". If such a file didn't exist
in the first place, how can the function claim to have successfully
caused its non-existence? If the text really means to allow that
interpretation, wouldn't it be clearer to say something like "ensures"
instead of "causes", and also perhaps "any file" instead of "the file"?
What is all this about existence. Look at what you quoted. It merely
talks about access by a name in a string. According to that it would be
perfectly OK to simply rename the file.
This thread has been talking about non-existent files from the
beginning, but if you prefer, let's replace "non-existence" by
"inaccessibility by the specified name". I don't disagree that renaming
(or perhaps moving to a special place, like a "recycle bin") seems to
satisfy the requirements of remove(); but my point was that the text I
quoted sounds like it requires remove() to cause a change. The call is
supposed to cause a file (THE file!) to *no longer* be accessible (by
the provided name, in case that's not obvious enough). Does that not
imply that there is a file that is accessible before the call, and the
call causes it to become inaccessible? If the spec requires the call to
*cause* a change of state from A to B, and the state is already B when
you make the call and has never even been A, how does doing nothing
qualify as causing the change from A to B? Or is the only problem here
my English skills, because the real meaning of "no longer" in fact
includes "never", and the real meaning of "cause" includes "already done"?
Post by Francis Glassborow
In addition there is a great deal of difference between a remove failing
because there is not accessible file by that name, and failing because
the file system refuses to allow the program to turn of access to the
file by that name.
Sure, or failing because of a hardware malfunction -- unlike the two you
mentioned, a hardware failure cannot generally be predicted from the
state of the filesystem, so that's also a fairly big difference. But
that's not really what I am debating here -- what I'm trying to
concentrate on is whether a remove() call SUCCEEDING, BECAUSE there was
no accessible file under the provided name, is a logical possibility
that the text of the standard allows.
Post by Francis Glassborow
IME the usual reason for calling remove() is that the programmer wants
to reuse the name. S/he does not then care if the name currently
designates a file, just that the name is free for use.
I don't know; personally I can think of three general possibilities:

#1 The program expects the name to designate a file, perhaps because the
program has created it. If that expectation turns out wrong, it could
be a sign of a serious problem (perhaps there's a bug in the program, or
someone stole the file by renaming it out of the way in the meantime).

#2 The program expects the name to designate a file because the user has
told the program to delete that file. If that expectation turns out
wrong, the user may appreciate being notified.

#3 The program doesn't know or care if the name designates a file but
wants to use it for a new file, and for some reason it wants to remove
any existing file before creating a new one, rather than just
overwriting it.

#4 The program doesn't know or care if the name designates a file but
for some reason wants to make sure that the name is (and remains) available.

Personally I don't have the feeling that #4 is more common than #1 or
#2, but I don't have any statistically meaningful data about it.
Post by Francis Glassborow
Lewis Carroll would greatly enjoyed the difference between accessing a
file by a name and the existence of the file possibly accessed by a
different name.
This is a very normal thing in Unix/POSIX -- a file can have any number
of names, including zero, and removing one of them doesn't necessarily
make the file cease to exist.
Post by Francis Glassborow
I think that it is time that WG14 had another look particularly in the
context of concurrency.
POSIX has already given it a lot of thought, and it's still a hot topic
-- the fact that certain operations can't be done atomically and must
instead be performed as two or more calls can sometimes have security
implications, and has inspired the creation of a number of new system
calls. In those contexts, it's usually important to know when the
operation you asked the system to perform was impossible because it
looked like somebody else had already done it.
Wojtek Lerch
2015-05-03 04:11:55 UTC
Permalink
Raw Message
... three general possibilities...
Four. I'll count them again tomorrow, just to be sure. :)
Tim Rentsch
2015-05-03 05:43:50 UTC
Permalink
Raw Message
Post by Wojtek Lerch
...
Post by Wojtek Lerch
BTW I just had a closer look at the text -- it says that remove()
"causes the file whose name is the string pointed to by filename
to be no longer accessible by that name". If such a file didn't
exist in the first place, how can the function claim to have
successfully caused its non-existence? If the text really means
to allow that interpretation, wouldn't it be clearer to say
something like "ensures" instead of "causes", and also perhaps
"any file" instead of "the file"?
What is all this about existence. Look at what you quoted. It
merely talks about access by a name in a string. According to that
it would be perfectly OK to simply rename the file.
This thread has been talking about non-existent files from the
beginning, but if you prefer, let's replace "non-existence" by
"inaccessibility by the specified name". I don't disagree that
renaming (or perhaps moving to a special place, like a "recycle
bin") seems to satisfy the requirements of remove(); but my point
was that the text I quoted sounds like it requires remove() to
cause a change. The call is supposed to cause a file (THE file!)
to *no longer* be accessible (by the provided name, in case that's
not obvious enough). Does that not imply that there is a file
that is accessible before the call, and the call causes it to
become inaccessible? [snip]
I believe it doesn't. Look at the parallel text for rename(),
in particular the first sentence of 7.21.4.2 p2:

The rename function causes the file whose name is the string
pointed to by old to be henceforth known by the name given
by the string pointed to by new.

Now look at 7.21.4.2 p3:

The rename function returns zero if the operation succeeds,
nonzero if it fails, in which case /if the file existed
previously/ [my emphasis] it is still known by its original
name.

Clearly the phrase "the file whose name is the string pointed to
by ..." is meant to include situations where no such file exists.
The "cause" verb in 7.21.4.1 p2 is just a red herring, I think.
If necessary we could "cause" the file to no longer be accessible
by creating it and immediately removing it, but doing that is
semantically indistinguishable (as far as C goes) from just doing
nothing, so doing nothing ought to be allowed under the "as if"
rule.

In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
Richard Kettlewell
2015-05-03 11:33:41 UTC
Permalink
Raw Message
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
So is there a real platform where this is a realistic possibility, or is
the standard just providing a freedom that nobody actually needs
(excepting people who enjoy arguing about what it means)?
--
http://www.greenend.org.uk/rjk/
Tim Rentsch
2015-05-03 13:51:18 UTC
Permalink
Raw Message
Post by Richard Kettlewell
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
So is there a real platform where this is a realistic possibility,
or is the standard just providing a freedom that nobody actually
needs (excepting people who enjoy arguing about what it means)?
First I should clarify my previous statement. What I meant was
"I think /the possibility of/ a success return ..." etc.

To answer your question, I don't know of any actual case where
this is done. Still I think the freedom is useful, so that C
implementations can run on as wide a range of platforms as
possible, including platforms we don't know about or that
do not yet exist.
Richard Kettlewell
2015-05-03 14:03:35 UTC
Permalink
Raw Message
Post by Tim Rentsch
Post by Richard Kettlewell
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
So is there a real platform where this is a realistic possibility,
or is the standard just providing a freedom that nobody actually
needs (excepting people who enjoy arguing about what it means)?
First I should clarify my previous statement. What I meant was
"I think /the possibility of/ a success return ..." etc.
To answer your question, I don't know of any actual case where
this is done. Still I think the freedom is useful, so that C
implementations can run on as wide a range of platforms as
possible, including platforms we don't know about or that
do not yet exist.
The latter is a very questionable form of usefulness!
--
http://www.greenend.org.uk/rjk/
Tim Rentsch
2015-05-03 14:34:43 UTC
Permalink
Raw Message
Post by Richard Kettlewell
Post by Tim Rentsch
Post by Richard Kettlewell
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
So is there a real platform where this is a realistic possibility,
or is the standard just providing a freedom that nobody actually
needs (excepting people who enjoy arguing about what it means)?
First I should clarify my previous statement. What I meant was
"I think /the possibility of/ a success return ..." etc.
To answer your question, I don't know of any actual case where
this is done. Still I think the freedom is useful, so that C
implementations can run on as wide a range of platforms as
possible, including platforms we don't know about or that
do not yet exist.
The latter is a very questionable form of usefulness!
I don't understand why you would say that. ISTM that a natural
desire in writing a standard is to accommodate possible future
environments. For example, I can imagine a situation where a
system might want to give a success return in this case, for
security reasons, as otherwise remove() might be used to detect
the existence of a file that would not be detectable otherwise.
If a particular file system follows such a model, completely
outside the control of a C implementation that might run on it,
I don't think we would want to preclude the possibility of
having a conforming implementation that runs on such a system.
Richard Kettlewell
2015-05-03 15:10:34 UTC
Permalink
Raw Message
Post by Tim Rentsch
Post by Richard Kettlewell
Post by Tim Rentsch
To answer your question, I don't know of any actual case where
this is done. Still I think the freedom is useful, so that C
implementations can run on as wide a range of platforms as
possible, including platforms we don't know about or that
do not yet exist.
The latter is a very questionable form of usefulness!
I don't understand why you would say that.
Becuase it doesn’t improve anyone’s life right now. You’re just
guessing that it might do so in the future. Unless your guess pays off
the benefits cannot outweigh the costs.
Post by Tim Rentsch
ISTM that a natural desire in writing a standard is to accommodate
possible future environments. For example, I can imagine a situation
where a system might want to give a success return in this case, for
security reasons, as otherwise remove() might be used to detect the
existence of a file that would not be detectable otherwise.
I don’t follow. If remove() succeeds for existing non-secret filenames
and fails for both nonexistent filenames and for existing secret
filenames then this doesn’t provide any means for the caller to detect
secret filenames.
Post by Tim Rentsch
If a particular file system follows such a model, completely outside
the control of a C implementation that might run on it, I don't think
we would want to preclude the possibility of having a conforming
implementation that runs on such a system.
As it happens I can just use unlink() and _unlink() on the platforms I’m
paid to care about, and get a promise of sensible behavior.
--
http://www.greenend.org.uk/rjk/
Tim Rentsch
2015-05-03 21:10:53 UTC
Permalink
Raw Message
Post by Tim Rentsch
Post by Richard Kettlewell
Post by Tim Rentsch
To answer your question, I don't know of any actual case where
this is done. Still I think the freedom is useful, so that C
implementations can run on as wide a range of platforms as
possible, including platforms we don't know about or that
do not yet exist.
The latter is a very questionable form of usefulness!
I don't understand why you would say that.
Becuase it doesn't improve anyone's life right now. You're just
guessing that it might do so in the future. Unless your guess
pays off the benefits cannot outweigh the costs.
Hmmmm. My assessment is just the opposite of that. The cost
of having more latitude available is small, and the potential
benefit is high. In practical terms I don't think the "cost"
has cost anyone anything, not counting the time spent discussing
the point in the newsgroup (to which I would assign a very small
weighting factor).
Post by Tim Rentsch
ISTM that a natural desire in writing a standard is to accommodate
possible future environments. For example, I can imagine a situation
where a system might want to give a success return in this case, for
security reasons, as otherwise remove() might be used to detect the
existence of a file that would not be detectable otherwise.
I don't follow. If remove() succeeds for existing non-secret
filenames and fails for both nonexistent filenames and for
existing secret filenames then this doesn't provide any means for
the caller to detect secret filenames.
I think you're assuming that remove() on a file whose name is
secret doesn't remove the file. I am not making that assumption.
Post by Tim Rentsch
If a particular file system follows such a model, completely outside
the control of a C implementation that might run on it, I don't think
we would want to preclude the possibility of having a conforming
implementation that runs on such a system.
As it happens I can just use unlink() and _unlink() on the
platforms I'm paid to care about, and get a promise of sensible
behavior.
That seems completely consistent with the viewpoint I've
been describing. Do you think otherwise?
Wojtek Lerch
2015-05-03 13:22:51 UTC
Permalink
Raw Message
Post by Tim Rentsch
Post by Wojtek Lerch
...
Post by Wojtek Lerch
BTW I just had a closer look at the text -- it says that remove()
"causes the file whose name is the string pointed to by filename
to be no longer accessible by that name". If such a file didn't
exist in the first place, how can the function claim to have
successfully caused its non-existence? If the text really means
to allow that interpretation, wouldn't it be clearer to say
something like "ensures" instead of "causes", and also perhaps
"any file" instead of "the file"?
What is all this about existence. Look at what you quoted. It
merely talks about access by a name in a string. According to that
it would be perfectly OK to simply rename the file.
This thread has been talking about non-existent files from the
beginning, but if you prefer, let's replace "non-existence" by
"inaccessibility by the specified name". I don't disagree that
renaming (or perhaps moving to a special place, like a "recycle
bin") seems to satisfy the requirements of remove(); but my point
was that the text I quoted sounds like it requires remove() to
cause a change. The call is supposed to cause a file (THE file!)
to *no longer* be accessible (by the provided name, in case that's
not obvious enough). Does that not imply that there is a file
that is accessible before the call, and the call causes it to
become inaccessible? [snip]
I believe it doesn't. Look at the parallel text for rename(),
The rename function causes the file whose name is the string
pointed to by old to be henceforth known by the name given
by the string pointed to by new.
The rename function returns zero if the operation succeeds,
nonzero if it fails, in which case /if the file existed
previously/ [my emphasis] it is still known by its original
name.
Clearly the phrase "the file whose name is the string pointed to
by ..." is meant to include situations where no such file exists.
If no such file exists, how can it henceforth be known by the new name?
The part in p3 that you emphasized doesn't apply, because we're
talking about a call that does nothing and then claims success by
returning zero.
Post by Tim Rentsch
The "cause" verb in 7.21.4.1 p2 is just a red herring, I think.
If necessary we could "cause" the file to no longer be accessible
by creating it and immediately removing it, but doing that is
semantically indistinguishable (as far as C goes) from just doing
nothing, so doing nothing ought to be allowed under the "as if"
rule.
By the same kind of reasoning, rename() can just create a new file if
the old one does not exist. Do you think the standard allows that too?
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
How about an analogy. Would I be telling the truth if I said:

I have caused the Earth to no longer be a cube. It's a sphere now.
Tim Rentsch
2015-05-03 14:14:50 UTC
Permalink
Raw Message
Post by Wojtek Lerch
Post by Tim Rentsch
Post by Wojtek Lerch
...
Post by Wojtek Lerch
BTW I just had a closer look at the text -- it says that remove()
"causes the file whose name is the string pointed to by filename
to be no longer accessible by that name". If such a file didn't
exist in the first place, how can the function claim to have
successfully caused its non-existence? If the text really means
to allow that interpretation, wouldn't it be clearer to say
something like "ensures" instead of "causes", and also perhaps
"any file" instead of "the file"?
What is all this about existence. Look at what you quoted. It
merely talks about access by a name in a string. According to that
it would be perfectly OK to simply rename the file.
This thread has been talking about non-existent files from the
beginning, but if you prefer, let's replace "non-existence" by
"inaccessibility by the specified name". I don't disagree that
renaming (or perhaps moving to a special place, like a "recycle
bin") seems to satisfy the requirements of remove(); but my point
was that the text I quoted sounds like it requires remove() to
cause a change. The call is supposed to cause a file (THE file!)
to *no longer* be accessible (by the provided name, in case that's
not obvious enough). Does that not imply that there is a file
that is accessible before the call, and the call causes it to
become inaccessible? [snip]
I believe it doesn't. Look at the parallel text for rename(),
The rename function causes the file whose name is the string
pointed to by old to be henceforth known by the name given
by the string pointed to by new.
The rename function returns zero if the operation succeeds,
nonzero if it fails, in which case /if the file existed
previously/ [my emphasis] it is still known by its original
name.
Clearly the phrase "the file whose name is the string pointed to
by ..." is meant to include situations where no such file exists.
If no such file exists, how can it henceforth be known by the new name?
I didn't say it could. My point is about the meaning of the
phrase, not about what happens in the situation (ie, for rename()).
Post by Wojtek Lerch
The part in p3 that you emphasized doesn't apply, because we're
talking about a call that does nothing and then claims success by
returning zero.
To repeat myself, I'm not talking about a situation, but about
why the phrase "the file whose name is the string pointed to by
..." does not imply that such a file has to exist.
Post by Wojtek Lerch
Post by Tim Rentsch
The "cause" verb in 7.21.4.1 p2 is just a red herring, I think.
If necessary we could "cause" the file to no longer be accessible
by creating it and immediately removing it, but doing that is
semantically indistinguishable (as far as C goes) from just doing
nothing, so doing nothing ought to be allowed under the "as if"
rule.
By the same kind of reasoning, rename() can just create a new file if
the old one does not exist. Do you think the standard allows that too?
/Is it/ the same kind of reasoning? For remove(), the resulting
states are semantically indistinguishable. If that is also
true for the rename() scenario, then I think the answer to your
question is Yes.
Post by Wojtek Lerch
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
I should (again) clarify my previous statement. What I meant was
"I think /the possibility of/ a success return ..." etc.
Post by Wojtek Lerch
I have caused the Earth to no longer be a cube. It's a sphere now.
Are you an omnipotent being, and can I not ascertain whether the
Earth is now (or previously) a sphere or a cube? If so then I
have no reason to doubt you. Of course what I'm trying to get at
is these conditions do hold analogously for remove().

I don't mean to be contentious. I just don't see anything wrong
with allowing this possibility, considered just from the point
of view of conformance.
Francis Glassborow
2015-05-03 16:27:48 UTC
Permalink
Raw Message
I am not quoting because I do not think the ever expanding set of
quotations is germaine to the following comments.

File systems are very much system dependant. I know of at least one
platform on which there are no file extensions. That is fine for .c and
.h files because the implementation simply mpas those to subdirectories
called 'c' and 'h'. However this is not true for general file names.

POSIX supporting platforms have various features that are not
necessarily available on other platforms so the concept of writing
portable programs that make use of any file-system specfics is dubious
at best.

In essence, IMO, file-systems imply a degree of implementation defined
behaviour. I have no problem with POSIX supporting just two return
values from remove() or any other function that returns a
success/failure value. It is unfortunate that for historical reasons
that 0 is used for success. If we were designing from scratch I guess we
would use a bool today for that purpose but we effectively have an
'antibool' used across a range of function returns which has a potential
for nice obfustication for non-experts.

If I want to check a file for existence I can attempt to open it in read
mode (and note that that results in a null-pointer indicating failure)

If we allow platforms to return success from remove() as long as the end
result is that there is no accessible file by the name used in the
string then we can still check whether a file exists on those platforms
before we try to remove it.

Of course an alternative is to open the file for writing before calling
remove(). However I must confess my ignorance about POSIX based file
systems. Does opening for writing follow a link if that is how the file
name is appears in the directory or replace the link with a file whilst
leaving the original file alone.

I have no idea what WG14 intended by the wording it chose for various
aspects of C support for file systems. I very much doubt that just
trying to deduce their intentions from the current wording is very
profitable.

Finally I note that WG21 filesystem TS was appoved by ISO at the end of
last December. Seems reasonable that we should be moving on after more
than 25 years in which immense changes have happened resulting in
platforms beyond our daydreams in the 1980s when most if not all of C's
file handling functionality was specified.

Francis
Richard Kettlewell
2015-05-03 16:41:55 UTC
Permalink
Raw Message
Post by Francis Glassborow
If I want to check a file for existence I can attempt to open it in
read mode (and note that that results in a null-pointer indicating
failure)
That doesn’t distinguish between “does not exist” and “no read
permission”.
Post by Francis Glassborow
If we allow platforms to return success from remove() as long as the
end result is that there is no accessible file by the name used in the
string then we can still check whether a file exists on those
platforms before we try to remove it.
No, you can’t; the situation may change between the test and the remove.
--
http://www.greenend.org.uk/rjk/
Francis Glassborow
2015-05-03 17:28:37 UTC
Permalink
Raw Message
Post by Richard Kettlewell
Post by Francis Glassborow
If I want to check a file for existence I can attempt to open it in
read mode (and note that that results in a null-pointer indicating
failure)
That doesn’t distinguish between “does not exist” and “no read
permission”.
Well I guess we could also have files that have no read permission but
allow writing and so allo removing. Which really emphasises that we need
an exist(), preferably that returns information about access permissions.
Post by Richard Kettlewell
Post by Francis Glassborow
If we allow platforms to return success from remove() as long as the
end result is that there is no accessible file by the name used in the
string then we can still check whether a file exists on those
platforms before we try to remove it.
No, you can’t; the situation may change between the test and the remove.
On a multi-threaded system that is always possible even for a simple
call to remove() unless you make the call in a critical section.

I think your comments serve to emphasise that it is time for WG14 to
look at its file system support.

Francis
Keith Thompson
2015-05-03 19:21:15 UTC
Permalink
Raw Message
Francis Glassborow <***@btinternet.com> writes:
[...]
Post by Francis Glassborow
Of course an alternative is to open the file for writing before
calling remove(). However I must confess my ignorance about POSIX
based file systems. Does opening for writing follow a link if that is
how the file name is appears in the directory or replace the link with
a file whilst leaving the original file alone.
[...]

There are two kinds of links: hard links and symbolic links.

A symbolic link (symlink) can be created by the "ln -s" command or by
the symlink() system call. It's implemented as a small file containing
the name of the target file, with a flag indicating that it's a symlink.
Most operations on a symlink act on the target file; some specialized
operations like readlink() act on the symlink itself. The idea is that
the symlink acts, for most purposes, as if it were the target file.

A hard link can be created by the "ln" command with no "-s" option.
It's just a directory entry. If you create a file "foo.txt" and then a
hard link "ln foo.txt bar.txt", both "foo.txt" and "bar.txt" are hard
links to the same file; neither is distinguished as the "real" file.
The file itself isn't removed until both foo.txt and bar.txt have been
"unlinked".
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Tim Rentsch
2015-05-03 21:26:44 UTC
Permalink
Raw Message
Post by Francis Glassborow
I am not quoting because I do not think the ever expanding set of
quotations is germaine to the following comments.
File systems are very much system dependant. I know of at least one
platform on which there are no file extensions. That is fine for .c
and .h files because the implementation simply mpas those to
subdirectories called 'c' and 'h'. However this is not true for
general file names.
POSIX supporting platforms have various features that are not
necessarily available on other platforms so the concept of writing
portable programs that make use of any file-system specfics is dubious
at best.
In essence, IMO, file-systems imply a degree of implementation defined
behaviour. I have no problem with POSIX supporting just two return
values from remove() or any other function that returns a
success/failure value. It is unfortunate that for historical reasons
that 0 is used for success. If we were designing from scratch I guess
we would use a bool today for that purpose but we effectively have an
antibool' used across a range of function returns which has a
potential for nice obfustication for non-experts.
If I want to check a file for existence I can attempt to open it in
read mode (and note that that results in a null-pointer indicating
failure)
If we allow platforms to return success from remove() as long as the
end result is that there is no accessible file by the name used in the
string then we can still check whether a file exists on those
platforms before we try to remove it.
Of course an alternative is to open the file for writing before
calling remove(). However I must confess my ignorance about POSIX
based file systems. Does opening for writing follow a link if that is
how the file name is appears in the directory or replace the link with
a file whilst leaving the original file alone.
I have no idea what WG14 intended by the wording it chose for various
aspects of C support for file systems. I very much doubt that just
trying to deduce their intentions from the current wording is very
profitable.
Finally I note that WG21 filesystem TS was appoved by ISO at the end
of last December. Seems reasonable that we should be moving on after
more than 25 years in which immense changes have happened resulting in
platforms beyond our daydreams in the 1980s when most if not all of
C's file handling functionality was specified.
I agree with most of what you say, with two exceptions: one, where
you say "implementation defined" I would say "implementation
dependent"; and two, I'm not sure that C needs to define more
elaborate file handling functionality. IMO one of C's strengths
is that it doesn't try to solve all the world's problems. Instead
it supplies some simple library functions for common simple cases,
and expects that more demanding applications will use functions
that are system-specific (eg, read(), write(), accept(), etc).

If there were consensus (ie, about file handling system calls)
among all the major operating systems now in use then making an
effort to codify that in the Standard is probably a worthwhile
endeavor. Going the other direction, however, IMO is not.
Wojtek Lerch
2015-05-04 04:51:02 UTC
Permalink
Raw Message
Post by Francis Glassborow
I am not quoting because I do not think the ever expanding set of
quotations is germaine to the following comments.
File systems are very much system dependant. I know of at least one
platform on which there are no file extensions. That is fine for .c and
.h files because the implementation simply mpas those to subdirectories
called 'c' and 'h'. However this is not true for general file names.
POSIX supporting platforms have various features that are not
necessarily available on other platforms so the concept of writing
portable programs that make use of any file-system specfics is dubious
at best.
In essence, IMO, file-systems imply a degree of implementation defined
behaviour. I have no problem with POSIX supporting just two return
values from remove() or any other function that returns a
success/failure value. It is unfortunate that for historical reasons
that 0 is used for success. If we were designing from scratch I guess we
would use a bool today for that purpose but we effectively have an
'antibool' used across a range of function returns which has a potential
for nice obfustication for non-experts.
I think the real issue is that at least several common situations are
possible on most implementations, but the C standard not only doesn't
specify a way for a remove() call to distinguish them, but, as it turns
out, doesn't even clearly say which ones count as "success" and which
ones as "failure":

* The file existed and was removed as requested
* There was no such file and the call didn't do anything
* The file existed but the removal was refused for some reason
* The removal was refused without even indicating if the file existed or not
* Some unexpected failure happened, such as a hardware malfunction

In POSIX, the first one counts as success and the rest as failures, with
a specific errno value (or three) assigned to each of them. In C, the
only two results are "success" or "failure", and there's no way to tell
the above situations apart, other than the first one is obviously a success.
Post by Francis Glassborow
If I want to check a file for existence I can attempt to open it in read
mode (and note that that results in a null-pointer indicating failure)
But a failure doesn't tell you anything about the file's existence.
Maybe you just ran out of memory to allocate a FILE structure.
Post by Francis Glassborow
If we allow platforms to return success from remove() as long as the end
result is that there is no accessible file by the name used in the
string then we can still check whether a file exists on those platforms
before we try to remove it.
Of course an alternative is to open the file for writing before calling
remove(). However I must confess my ignorance about POSIX based file
systems. Does opening for writing follow a link if that is how the file
name is appears in the directory or replace the link with a file whilst
leaving the original file alone.
If you open it for writing you will be overwriting the existing file.
To create a new file you would have to remove the existing file first.
Post by Francis Glassborow
I have no idea what WG14 intended by the wording it chose for various
aspects of C support for file systems. I very much doubt that just
trying to deduce their intentions from the current wording is very
profitable.
Finally I note that WG21 filesystem TS was appoved by ISO at the end of
last December. Seems reasonable that we should be moving on after more
than 25 years in which immense changes have happened resulting in
platforms beyond our daydreams in the 1980s when most if not all of C's
file handling functionality was specified.
Thanks for this important detail. It sounds very interesting.
Wojtek Lerch
2015-05-04 04:29:05 UTC
Permalink
Raw Message
Post by Tim Rentsch
Post by Wojtek Lerch
Post by Tim Rentsch
[...] my point was that the text I quoted
[7.21.4.1#2] sounds like it requires remove() to
cause a change. The call is supposed to cause a file (THE file!)
to *no longer* be accessible (by the provided name, in case that's
not obvious enough). Does that not imply that there is a file
that is accessible before the call, and the call causes it to
become inaccessible? [snip]
I believe it doesn't. Look at the parallel text for rename(),
The rename function causes the file whose name is the string
pointed to by old to be henceforth known by the name given
by the string pointed to by new.
The rename function returns zero if the operation succeeds,
nonzero if it fails, in which case /if the file existed
previously/ [my emphasis] it is still known by its original
name.
Clearly the phrase "the file whose name is the string pointed to
by ..." is meant to include situations where no such file exists.
If no such file exists, how can it henceforth be known by the new name?
I didn't say it could. My point is about the meaning of the
phrase, not about what happens in the situation (ie, for rename()).
I don't doubt that the meaning of the phrase "the file whose name is X"
can in some contexts include non-existent files -- one trivial example
is the context of the sentence "The file whose name is X can't be
removed because it doesn't exist". But that's not what my question was
about -- what I asked was whether in a situation where no such file
existed, it's logical for a remove() call to claim that it has
successfully caused that non-existent file to no longer exist. It's
really just a question about the exact meaning of the English words
"cause" and "no longer".
Post by Tim Rentsch
Post by Wojtek Lerch
The part in p3 that you emphasized doesn't apply, because we're
talking about a call that does nothing and then claims success by
returning zero.
To repeat myself, I'm not talking about a situation, but about
why the phrase "the file whose name is the string pointed to by
..." does not imply that such a file has to exist.
The phrase itself does not, but using it in some contexts does. In
particular, claiming that an operation has been performed on the file
sounds illogical if the file has never existed.
Post by Tim Rentsch
Post by Wojtek Lerch
Post by Tim Rentsch
The "cause" verb in 7.21.4.1 p2 is just a red herring, I think.
If necessary we could "cause" the file to no longer be accessible
by creating it and immediately removing it, but doing that is
semantically indistinguishable (as far as C goes) from just doing
nothing, so doing nothing ought to be allowed under the "as if"
rule.
By the same kind of reasoning, rename() can just create a new file if
the old one does not exist. Do you think the standard allows that too?
/Is it/ the same kind of reasoning? For remove(), the resulting
states are semantically indistinguishable. If that is also
true for the rename() scenario, then I think the answer to your
question is Yes.
The reasoning I was talking about was your claim that a function whose
specified job is to perform an operation on the file named X can
legitimately claim success after noticing that there's no file named X,
creating a new one, and then performing the required operation on the
new file. Whether the result of the operation is distinguishable from
the result of not doing anything at all is a separate issue, dependent
on what the operation is, but irrelevant to the reasoning I was
referring to.
Post by Tim Rentsch
Post by Wojtek Lerch
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
I should (again) clarify my previous statement. What I meant was
"I think /the possibility of/ a success return ..." etc.
Post by Wojtek Lerch
I have caused the Earth to no longer be a cube. It's a sphere now.
Are you an omnipotent being, and can I not ascertain whether the
Earth is now (or previously) a sphere or a cube? If so then I
have no reason to doubt you. Of course what I'm trying to get at
is these conditions do hold analogously for remove().
No, of course I'm not an omnipotent being (but thanks for asking). I
didn't change the shape of the Earth. The Earth has always been a
sphere. I don't need to be omnipotent to do nothing. In other words, I
meant the real world to be the context of my example.

How about another example: someone hires me to demolish a building on
some remote island. His lawyer dislikes the word "demolish", and
instead writes in my contract that my job is to cause the building at
address X to no longer stand. When I show up at the site, it turns out
that there's never been a building there -- the contractor who was
supposed to build it was a crook who just sent back photos of some other
building as proof that his job was done, and then took his money and
fled. What are my chances of convincing the lawyer that I have
successfully fulfilled my obligation, and collecting my payment?
Post by Tim Rentsch
I don't mean to be contentious. I just don't see anything wrong
with allowing this possibility, considered just from the point
of view of conformance.
To put it a bit more formally, you mean you don't see anything logically
wrong with /interpreting the existing text/ as allowing that
possibility, correct? As opposed to not seeing anything practically
wrong with letting the C standard allow it?
Tim Rentsch
2015-05-05 05:04:21 UTC
Permalink
Raw Message
Post by Wojtek Lerch
Post by Tim Rentsch
Post by Wojtek Lerch
Post by Tim Rentsch
[...] my point was that the text I quoted
[7.21.4.1#2] sounds like it requires remove() to
cause a change. The call is supposed to cause a file (THE file!)
to *no longer* be accessible (by the provided name, in case that's
not obvious enough). Does that not imply that there is a file
that is accessible before the call, and the call causes it to
become inaccessible? [snip]
I believe it doesn't. Look at the parallel text for rename(),
The rename function causes the file whose name is the string
pointed to by old to be henceforth known by the name given
by the string pointed to by new.
The rename function returns zero if the operation succeeds,
nonzero if it fails, in which case /if the file existed
previously/ [my emphasis] it is still known by its original
name.
Clearly the phrase "the file whose name is the string pointed to
by ..." is meant to include situations where no such file exists.
If no such file exists, how can it henceforth be known by the new name?
I didn't say it could. My point is about the meaning of the
phrase, not about what happens in the situation (ie, for rename()).
I don't doubt that the meaning of the phrase "the file whose name
is X" can in some contexts include non-existent files -- one
trivial example is the context of the sentence "The file whose
name is X can't be removed because it doesn't exist". But that's
not what my question was about -- what I asked was whether in a
situation where no such file existed, it's logical for a remove()
call to claim that it has successfully caused that non-existent
file to no longer exist. It's really just a question about the
exact meaning of the English words "cause" and "no longer".
Post by Tim Rentsch
Post by Wojtek Lerch
The part in p3 that you emphasized doesn't apply, because we're
talking about a call that does nothing and then claims success by
returning zero.
To repeat myself, I'm not talking about a situation, but about
why the phrase "the file whose name is the string pointed to by
..." does not imply that such a file has to exist.
The phrase itself does not, but using it in some contexts does.
In particular, claiming that an operation has been performed on
the file sounds illogical if the file has never existed.
Post by Tim Rentsch
Post by Wojtek Lerch
Post by Tim Rentsch
The "cause" verb in 7.21.4.1 p2 is just a red herring, I think.
If necessary we could "cause" the file to no longer be accessible
by creating it and immediately removing it, but doing that is
semantically indistinguishable (as far as C goes) from just doing
nothing, so doing nothing ought to be allowed under the "as if"
rule.
By the same kind of reasoning, rename() can just create a new file if
the old one does not exist. Do you think the standard allows that too?
/Is it/ the same kind of reasoning? For remove(), the resulting
states are semantically indistinguishable. If that is also
true for the rename() scenario, then I think the answer to your
question is Yes.
The reasoning I was talking about was your claim that a function
whose specified job is to perform an operation on the file named X
can legitimately claim success after noticing that there's no file
named X, creating a new one, and then performing the required
operation on the new file. Whether the result of the operation is
distinguishable from the result of not doing anything at all is a
separate issue, dependent on what the operation is, but irrelevant
to the reasoning I was referring to.
Post by Tim Rentsch
Post by Wojtek Lerch
Post by Tim Rentsch
In short, I think a success return for remove() when there is no
file by that name is intended by, and also allowed by the text
of, the Standard.
I should (again) clarify my previous statement. What I meant was
"I think /the possibility of/ a success return ..." etc.
Post by Wojtek Lerch
I have caused the Earth to no longer be a cube. It's a sphere now.
Are you an omnipotent being, and can I not ascertain whether the
Earth is now (or previously) a sphere or a cube? If so then I
have no reason to doubt you. Of course what I'm trying to get at
is these conditions do hold analogously for remove().
No, of course I'm not an omnipotent being (but thanks for asking).
I didn't change the shape of the Earth. The Earth has always been
a sphere. I don't need to be omnipotent to do nothing. In other
words, I meant the real world to be the context of my example.
How about another example: someone hires me to demolish a
building on some remote island. His lawyer dislikes the word
"demolish", and instead writes in my contract that my job is to
cause the building at address X to no longer stand. When I show
up at the site, it turns out that there's never been a building
there -- the contractor who was supposed to build it was a crook
who just sent back photos of some other building as proof that his
job was done, and then took his money and fled. What are my
chances of convincing the lawyer that I have successfully
fulfilled my obligation, and collecting my payment?
Post by Tim Rentsch
I don't mean to be contentious. I just don't see anything wrong
with allowing this possibility, considered just from the point
of view of conformance.
To put it a bit more formally, you mean you don't see anything
logically wrong with /interpreting the existing text/ as allowing
that possibility, correct? As opposed to not seeing anything
practically wrong with letting the C standard allow it?
I'm sorry my attempts to communicate my thoughts here have
not been more successful. Let me try again.

I agree that the current text giving the semantics for remove()
could be taken to say that remove() on a non-existent file must
give a failure return.

However, I don't think that text /must/ be taken that way. It
also could be taken to say that remove() on a non-existent file
may give a success return (a failure return is always possible).
To be clear, both of these positions are just my opinion.

In practical terms I don't think there is any significant
difference between the two alternatives. The safe path for
implementors is to assume the first alternative; the safe path
for developers is to assume the second alternative. Since I
speak mainly from a developer perspective, and since I expect no
significant change in anyone's behavior no matter which
alternative holds, I espouse the second alternative. I wouldn't
mind if someone thought it important to clarify the matter, but
from my point on view it's easier just to assume both success and
failure outcomes are allowed in a conforming implementation, and
not worry if the intended position is more stringent than that.

Does that all make sense now?
Wojtek Lerch
2015-05-08 04:06:03 UTC
Permalink
Raw Message
Post by Tim Rentsch
I'm sorry my attempts to communicate my thoughts here have
not been more successful. Let me try again.
I agree that the current text giving the semantics for remove()
could be taken to say that remove() on a non-existent file must
give a failure return.
However, I don't think that text /must/ be taken that way. It
also could be taken to say that remove() on a non-existent file
may give a success return (a failure return is always possible).
I guess if that weren't true, we wouldn't be having this discussion...
Post by Tim Rentsch
To be clear, both of these positions are just my opinion.
In practical terms I don't think there is any significant
difference between the two alternatives. The safe path for
implementors is to assume the first alternative; the safe path
for developers is to assume the second alternative. Since I
speak mainly from a developer perspective, and since I expect no
significant change in anyone's behavior no matter which
alternative holds, I espouse the second alternative. I wouldn't
mind if someone thought it important to clarify the matter, but
from my point on view it's easier just to assume both success and
failure outcomes are allowed in a conforming implementation, and
not worry if the intended position is more stringent than that.
OK, I'll buy that. The simple success/failure return is hopelessly
little information for any program that has a reason to care about what
happened in the remove() call anyway. Any program that needs to know
will have to rely on some better guarantees, such as those provided by
POSIX.
Post by Tim Rentsch
Does that all make sense now?
Absolutely, thank you.

James Kuyper
2015-05-03 01:03:13 UTC
Permalink
Raw Message
Post by James Kuyper
Post by FrankHB1989
Post by James Kuyper
Post by FrankHB1989
Current wording in N1570 for remove function (7.21.4.1) seems to be
not very clear about meaning of "success". If the file did not exist,
the function call can be still considered successful according to
Description. This should be not intended. Can it be improved?
Are you sure it's not intended? I wasn't involved in the decision, so I
don't know. There's nothing about this issue in C Rationale.
The Single Unix standard's description of remove() says that "Any
conflict between the requirements described here and the ISO C standard
is unintentional." It identifies the value of errno (which the C
standard leaves unspecified, so this is not a conflict) by
cross-reference to the description of unlink() (which is not a C
standard function). The file not existing corresponds to none of the
specified errno values. The length of that list (9 permitted non-zero
errno values) suggests that they put a fair amount of thought into the
error conditions, without concluding that the non-existence of the
specified file should be treated as one. I'd think it would be hard to
do that by accident.
Hmm... I meant the unclear requirements are not that ideal.
You said above that "the function call can still be considered
successful according to the Description." You were assuming that this
was unintentional, in which case it's an indication that there's a
defect in the description. However, I'm suggesting that it might be
intentional. In that case, the description of what the function is
supposed to do led you to the correct conclusion that it had been
successful, and that the return value should therefore be zero - despite
the fact that you didn't think that conclusion was correct! A
description capable of getting you to reach the correct conclusion
despite not expecting it to be correct seems like a reasonably clear
description to me.
Post by FrankHB1989
7.5
3 ... The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.
But the return value is just not the case.
True - but I'm not citing the errno values as evidence for or against C
conformance, but as evidence that the people who chose those values did
not consider the non-existence of the file to be remove()d as an error
condition. As a result, they would see nothing odd about having remove()
return a "success"
Sorry - I forgot when I wrote that, that I had already conceded that I
was wrong in believing that there was no POSIX error code for the file
not existing. For me, the time between those two messages was fairly
eventful.
--
James Kuyper
Loading...