Don't Close() directories because they are only Lock()ed but not Open()ed.
[AROS.git] / compiler / clib / close.c
blob6bf1c8507cb8a744e4f88a3ad1d283cc927496a7
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 ANSI C function close().
6 */
8 #include "__arosc_privdata.h"
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <errno.h>
15 #include "__fdesc.h"
17 /*****************************************************************************
19 NAME */
20 #include <unistd.h>
22 int close (
24 /* SYNOPSIS */
25 int fd)
27 /* FUNCTION
28 Closes an open file. If this is the last file descriptor
29 associated with this file, then all allocated resources
30 are freed, too.
32 INPUTS
33 fd - The result of a successful open()
35 RESULT
36 -1 for error or zero on success.
38 NOTES
39 This function must not be used in a shared library or
40 in a threaded application.
42 EXAMPLE
44 BUGS
46 SEE ALSO
47 open(), read(), write(), fopen()
49 INTERNALS
51 ******************************************************************************/
53 fdesc *fdesc;
55 if (!(fdesc = __getfdesc(fd)))
57 errno = EBADF;
59 return -1;
62 if (--fdesc->fcb->opencount == 0)
64 /* Due to a *stupid* behaviour of the dos.library we cannot handle closing failures cleanly :-(
65 if (
66 !(fdesc->fcb->privflags & _FCB_DONTCLOSE_FH) &&
67 !Close(fdesc->fh)
70 fdesc->opencount++;
71 errno = __arosc_ioerr2errno(IoErr());
73 return -1;
76 /* FIXME: Damn dos.library! We cannot report the error code correctly! This oughta change someday... */
77 /* Since the dos.library destroys the file handle anyway, even if the closing fails, we cannot
78 report the error code correctly, so just close the file and get out of here */
80 if (!(fdesc->fcb->privflags & _FCB_DONTCLOSE_FH))
82 // don't close directories because we don't Open() them.
83 if (fdesc->fcb->isdir)
85 UnLock(fdesc->fcb->fh);
87 else
89 Close(fdesc->fcb->fh);
93 FreeVec(fdesc->fcb);
96 __free_fdesc(fdesc);
97 __setfdesc(fd, NULL);
99 return 0;
100 } /* close */