ISO C/200X Proposal:
File Inquiry Functions


By David R. Tribble
david@tribble.com

Revision 2.4, 2005-08-10

 

Contents


Cover Sheet

 
                           C0X Revision Proposal
                           =====================

   Title:              File Inquiry Functions
   Author:             David R. Tribble
   Author Affiliation: Self
   Postal Address:     ***************
                       ***************
                       USA
   E-mail Address:     david@tribble.com
   Telephone Number:   ***************
   Sponsor:            _____________
   Revision:           2.4
   Date:               2005-08-10
   Supersedes:         2.3, 2003-12-30
   Proposal Category:
      __ Editorial change/non-normative contribution
      __ Correction
      X_ New feature
      __ Addition to obsolescent feature list
      __ Addition to Future Directions
      __ Other (please specify)  ______________________________
   Area of Standard Affected:
      __ Environment
      __ Language
      __ Preprocessor
      X_ Library
         X_ Macro/typedef/tag name
         X_ Function
         __ Header
         __ Other (please specify)  ____________________________________  
   Prior Art:
        The 'stat' structure, and 'stat()' and 'fstat()' functions of
        POSIX (Unix); the 'BY_HANDLE_FILE_INFORMATION' structure and
        the 'GetFileInformationByHandle()' function, and the
        'WIN32_FIND_DATA' and 'WIN32_FILE_ATTRIBUTE_DATA' structures of
        Microsoft Windows (Win32).  Other operating systems have similar
        functionality (MS-DOS, MacOS, VMS, etc.).
   Target Audience:
        C programmers, and programmers who write programs that
        generate C code.
   Related Documents (if any): None.
   Proposal Attached: X_ Yes __ No, but what's your interest?
   Abstract:
        The addition of standard functions that return information
        about a given file or I/O stream.
 


1. Introduction

All hosted ISO C (ISO 9899:1999) implementations provide the concept of an I/O stream, also known as a file, i.e., a named collection of characters (bytes) that is accessible via the standard library functions declared in the <stdio.h> header, such as fopen().

This proposal describes a set of types and functions to be added to the standard C library to provide the means to interrogate the implementation for information about files and streams.

The functions and types suggested in this proposal codify, in a general way, existing practice among several popular implementations of C.


1.1 Problems Addressed

The following is a list of common programming operations that are not currently supported by ISO C (C99), or at best are expensive to do.

  1. Does a particular file exist?

    It is possible to use fopen() and then fclose() to check for the existence of a given file, but this is generally an expensive operation. Opening a file takes much longer than simply checking its status on most systems. Even if the fopen() call fails, this does not really indicate whether the file exists of not, because the execution unit (program) might not have the proper access permissions to the file.

    It is reasonable to assume that some applications need to know only if a file exists (e.g., it might be used as a semaphore or locking mechanism) without needing to read or write its contents.

  2. How big is a particular file?

    A program may want to read the entire contents of the file into a memory buffer, or it may need to allocate a data object based on the size of the file, or it may need to take some action if the file is empty. The size of a file can be determined by opening the file and seeking to its end in order to count the bytes, but this incurs the overhead of actually opening the file, which might not be necessary for the application, particularly if it does not care about the actual contents of the file.

  3. Is a particular file larger than some other file?

    A program may want to perform some action based on the relative sizes of two different files, without regard to the contents of the files themselves.

  4. How old is a particular file?
    When was it last modified?
    Is it older than some other file?

    ISO C does not provide the capability to determine these.

  5. Does a particular file name refer to a file or a directory (or something else)?

    Knowing that a given file is a directory may allow a program to decide not to attempt to open or create it. It may also allow a program to use the directory name to construct the name of another file.

    (Note that ISO C does not support the ability to create or remove directories. But see Proposal [P2] for a related proposal that addresses this.)

  6. Are two files the same physical file?

    A program may take certain actions if it can determine that two files or I/O streams designate the same physical file.

  7. Is an I/O stream a regular file or some other kind of device?

    A program may handle I/O for a particular file if it is not a regular file, such as sending different end-of-line characters to a writable stream.

  8. Is another process modifying the same file I'm using?

    A program can check the modification time of a file and compare it to the time it last read/wrote to the file, which could indicate that more data is available (written by some other process), or that there is a conflict because another process is using the file.

Many programmers provide these capabilities by wrapping portable functions around implementation-specific functions. This proposal suggests functions and types to be added to standard C to provide these common capabilities.


2. Definitions

The following terms are used in this proposal. Some of the terms may need to be added to the ISO standard.

access permissions
The operations permitted on a given file, such as reading, writing, executing (in the case of binary program images), and searching (in the case of directories).

directory
A collection of files and possibly other directories residing on an external storage device. Most implementations support a hierarchical arrangement of directories and files. Most implementations also associate the execution of a given execution unit (i.e., program) with a currrent working directory.

ISO C does not define or support the concept of directory.

file
A sequence of bytes (or characters) residing on an external structured storage device. C programs can open files by name (using the fopen() library function) and read and/or write their contents.

file type
The kind of file designated by a given file name. In the most general sense, a file can be a regular file or possibly a directory. Implementations usually provide other file types, such as named pipe, socket, symbolic link, character device, block device, volume label, and others.

serial number
A unique number assigned to a given file within the file system on which it resides.

structured storage device
A hardware device, such as a disk drive, used for storing data, usually arranged as a collection of file and possibly directories. See file system.

3. Constants

The following constants are preprocessor macros defined in the <stdio.h> standard header.

_FILE_PERM_EXEC
_FILE_PERM_READ
_FILE_PERM_SEARCH
_FILE_PERM_WRITE
(See the fi_perms structure member below.)
_FILE_TYPE_DIR
_FILE_TYPE_FILE
_FILE_TYPE_UNKNOWN
(See the fi_type structure member below.)

The following constant is a preprocessor macro defined in the <time.h> standard header.

_TIME_ERROR
(See the fi_accessed, fi_created, and fi_modified, and fi_revised structure members below.)
[Note]
These constants have names with a leading underscore, because such names are explicitly reserved for the implementation and (presumably) for the ISO standard library.

Implementations may provide other constants with names of the form _FILE_TYPE_XXX in addition to those specified in this proposal.

[Note]
The _FILE_TYPE_
XXX macros described in this proposal are considered the minimum number of useful files types covering the broadest number of existing implementations.

However, implementations may provide additional macros to reflect their support of other file types such as:

  • socket
  • pipe (FIFO)
  • symbolic link
  • character I/O device
  • block I/O device
  • network device
  • volume label
See Appendix A for further discussion.

Implementations may provide other constants with names of the form _FILE_PERM_XXX in addition to those specified in this proposal.

[Note]
The _FILE_PERM_
XXX macros described in this proposal are considered the minimum number of useful file access permissions covering the broadest number of existing implementations.

However, implementations may provide additional macros to reflect their support of file access permissions and modes such as:

  • user access
  • group access
  • set-user-ID mode
  • set-group-ID mode
  • backup/archival indicator
  • system access
  • hidden file
See Appendix B for further discussion.

3.1 Macro _FILE_PERM_EXEC

Synopsis

    #include <stdio.h>

    #define _FILE_PERM_EXEC     integer-expression

This preprocessor macro evaluates to an integer constant expression. This value specifies that a file designates an executable binary image.


3.2 Macro _FILE_PERM_READ

Synopsis

    #include <stdio.h>

    #define _FILE_PERM_READ     integer-expression

This preprocessor macro evaluates to an integer constant expression. This value specifies that a file can be read by the execution unit.


3.3 Macro _FILE_PERM_SEARCH

Synopsis

    #include <stdio.h>

    #define _FILE_PERM_SEARCH   integer-expression

This preprocessor macro evaluates to an integer constant expression. This value specifies that a file designates a directory and that it can be searched by the execution unit.


3.4 Macro _FILE_PERM_WRITE

Synopsis

    #include <stdio.h>

    #define _FILE_PERM_WRITE    integer-expression

This preprocessor macro evaluates to an integer constant expression. This value specifies that a file can be written by the execution unit.


3.5 Macro _FILE_TYPE_DIR

Synopsis

    #include <stdio.h>

    #define _FILE_TYPE_DIR      integer-expression

This preprocessor macro evaluates to an integer constant expression. This value specifies that a file designates a directory.


3.6 Macro _FILE_TYPE_FILE

Synopsis

    #include <stdio.h>

    #define _FILE_TYPE_FILE     integer-expression

This preprocessor macro evaluates to an integer constant expression. This value specifies that a file designates a regular file.


3.7 Macro _FILE_TYPE_UNKNOWN

Synopsis

    #include <stdio.h>

    #define _FILE_TYPE_UNKNOWN  integer-expression

This preprocessor macro evaluates to an integer constant expression. This value specifies that a file designates an external file that does not exist or has an unknown or unsupported type.


3.8 Macro _TIME_ERROR

Synopsis

    #include <time.h>

    #define _TIME_ERROR   arithmetic-expresssion

This preprocessor macro evaluates to an arithmetic value of type time_t, and represents an unknown, indeterminate, or erroneous time value. It is guaranteed not to represent a valid time.

[Note]
This constant is meant to replace the use of (time_t)(-1) as an indicator of an erroneous or unknown time value, such as returned by the mktime() function. A time of -1 may be an otherwise valid time value on some implementations.
[Note]
If the related Proposal [P3] is adopted into ISO C, the constant _LONGTIME_ERROR can be used instead.

4. Types

The following types are defined in the <stdio.h> standard header.

[Note]
These types and structure tages have names with a leading underscore, because such names are explicitly reserved for the implementation and (presumably) for the ISO standard library.
[Note]
The constants, types, and functions defined in this proposal could instead be placed into a completely new standard header (perhaps named <stdfile.h>) instead of being added to the existing <stdio.h> header. If this approach is taken, then the names defined in this proposal do not need leading underscores to keep them from intruding into the user namespace.

4.1 Structure _fileinfo

Synopsis
    #include <stdio.h>

    struct _fileinfo
    {
        int                 fi_type;        // File type
        unsigned long int   fi_perms;       // Access permissions
        long long int       fi_size;        // Size, in bytes
        time_t              fi_modified;    // Modification time
        time_t              fi_accessed;    // Last access time
        time_t              fi_created;     // Creation time
        time_t              fi_revised;     // Status update time
        long int            fi_id;          // Serial number
        char                fi_filesys[n];  // File system identity
    };
[Note]
The members having type time_t may instead be defined as having type longtime_t, an extended-precision time type, if the related Proposal [P3] is adopted into ISO C.

Description

This structure contains information about a file.

The structure contains the following members, in no particular order.

time_t fi_accessed

This specifies the time that the file was last accessed. If this information cannot be determined (or if no such concept is supported by the implementation), this has a value equal to _TIME_ERROR.

[Note]
The meaning of "accessed" is implementation-defined, since different systems have different notions of what constitutes an "access" to a given file.

POSIX systems, for example, may consider this to be the time of the last actual access to a file (corresponding to the st_atime member of the stat structure), or they may consider this to be either the last access time or the time of the last status change (corresponding to the st_ctime member), whichever is later.

time_t fi_created

This specifies the time that the file was initially created. If this information cannot be determined (or if no such concept is supported by the implementation), this has a value equal to _TIME_ERROR.

[Note]
While many implementations are capable of providing the creation time of a file, POSIX is not. Therefore, POSIX implementations must set this member equal to -1.

char fi_filesys[n]

Specifies the name of the file system on which the file resides as a null-terminated character string. The length of the name (n) and its contents are implementation-defined. If this information cannot be determined (or if no such concept is supported by the implementation), the first character in the array is zero ('\0').

Two file system identities can be compared for equality using the strcmp() function.

[Note]
The intent is to be able to uniquely identify a file by its file system name and serial number.

The implementation is expected to provide a suitable identification value so that two files residing on the same file system have file system name strings that compare equal.

This member has type char[n] in order to be as generic as possible so that it can hold a unique identification value of an arbitrary size.

It might be reasonable to define this to be type long int, similar to the fi_id member. However, there are probably implementations that uniquely identify their file systems by name instead of by number, or even by some other kind of data object.

This kind of non-numeric file system identifier is best represented as either an opaque object of some implementation-defined type, or as a generic character string. The latter approach is preferred because it does not require the existence of a standard structure member with an unknown type, and it lends itself to simple tests for equality using strcmp(). Implementations that use a binary data object for identification can simply encode the bytes of the object as a hexadecimal character string.

long int fi_id

This specifies the serial number of the file, which is a unique number within the file system on which the file resides. If this information cannot be determined (or if no such concept is supported by the implementation), this has a value of -1.

[Note]
The intent is that the serial numbers for two different files in the same file system do not compare equal. Conversely, if two files in the same file system have the same serial number, then they can be considered to be the same file (even if they can be opened with different names).

It is not clear, however, that these semantics should be requirements mandated by the standard.

This member has type long int, but it might be more practical to define it as type char[n] (for some implementation-defined size n), so that it could hold a unique identification value of an arbitrary size.

time_t fi_modified

This specifies the time that the file was last modified. If this information cannot be determined (or if no such concept is supported by the implementation), this has a value equal to _TIME_ERROR.

[Note]
It is expected that most implementations will be able to provide at least this one piece of date/time information for a given file.

On POSIX implementations, for instance, this corresponds to the st_mtime member of the stat structure.

unsigned long int fi_perms

This specifies the access permissions of the file, which is a bitwise or-ing of zero or more _FILE_PERM_XXX constants. If the permissions of the file cannot be determined, this has a value equal to zero (0).

Testing a particular permissions bit by and-ing this member value with one of the _FILE_PERM_XXX constants results in a non-zero (true) value if the execution unit is permitted such access, or a zero (false) value if the access is not permitted.

A regular file or directory can have the _FILE_PERM_READ and _FILE_PERM_WRITE bits set, indicating that it can be read or written, respectively, by the execution unit.

A regular file can have the _FILE_PERM_EXEC bit set, indicating that it is an executable binary image that can be executed from the current execution unit (in an implementation-defined manner, possibly via the system() function).

A directory can have the _FILE_PERM_SEARCH bit set, indicating that the execution unit can search the contents of the directory (in an implementation-defined manner).

[Note]
The permissions bits are intended to take into account user-ID, group-ID, physical file access modes, etc., in determining whether or not a particular _FILE_PERM_
XXX access is granted to the program.

For example, Unix determines read access to a file by checking three levels of permissions: one for the owner (user), one for the group, and one for everyone else (other). If the execution unit can access a given file according to these combined permissions, then the fi_perms member should have its _FILE_PERM_READ bit set to one (1).

Implementations may support other permissions bits, with corresponding _FILE_PERM_XXX constants, the meanings of which are implementation-defined.

time_t fi_revised

This specifies the time that control information about the file was last modified. (Note that this time is not necessarily the same as the time that the contents of the file were last modified; this control information may refer to other accounting data kept by the implementation.) If this information cannot be determined (or if no such concept is supported by the implementation), this has a value equal to _TIME_ERROR.

[Note]
This corresponds to the st_mtime member of the stat structure on POSIX implementations, which indicates the time of the last i-node status change for the file).

Other implementations may not keep track of the time that file system information is updated for a given file. These implementations must therefore set this member to -1.

long long int fi_size

This specifies the size of the file. The size is represented in bytes (characters). Implementations may represent the file size as a value rounded up to the next multiple of an implementation-dependent block size. Note that the total file size might not include any pending (unflushed) writes to the file. If this information cannot be determined (or if no such concept is supported by the implementation), this has a value equal to -1.

[Note]
This member is signed so that a unique "unknown" sentinel value of -1 can be represented.

The member is of type long long int, which should be large enough (at least 63 bits) for most implementations in the forseeable future.

int fi_type

This specifies the type of the file, which is equal to one of the _FILE_TYPE_XXX constants.

A value equal to _FILE_TYPE_FILE indicates a regular file.

A value equal to _FILE_TYPE_DIR indicates a directory.

If the type cannot be determined, this has a value equal to _FILE_TYPE_UNKNOWN.

Implementations may support other file types, with corresponding _FILE_TYPE_XXX constants, the meanings of which are implementation-defined.

The structure may contain other implementation-defined members.

[Note]
These structure members are considered the minimum amount of useful information about files while also covering the widest number of existing implementations.

However, implementations may provide additional members to reflect their support of other file information, such as:

  • owner user-ID
  • owner group-ID
  • device ID
  • number of links to the file
  • number of blocks allocated to the file
  • lock control bits
  • last backup/archival time
  • system access permissions
  • network identification


5. Functions

The standard header <stdio.h> contains declarations for the following library functions.

[Note]
These functions have names with a leading underscore, because such names are explicitly reserved for the implementation and (presumably) for the ISO standard library.

5.1 Function _getfileinfo()

Synopsis
    #include <stdio.h>

    extern int  _getfileinfo(const char *fname, struct _fileinfo *info);

Description

This function retrieves information about the file with the name fname, placing the information into the structure pointed to by info.

The contents of the character string pointed to by fname are implementation-defined (and typically conform to the same rules dictated by the fopen() function). If pointer fname is null, the function fails.

If pointer info is null, the only meaningful result of the function is its return value (which can be used to determine if the file exists and is accessible by the execution unit).

Returns

If the named file exists and is accessible by the execution unit, and the retrieval of the information for the file is successful, the function returns a positive value. If unsuccessful, the function returns a negative value after modifying the value of errno (which is defined in the <errno.h> standard header).


5.2 Function _fgetfileinfo()

Synopsis
    #include <stdio.h>

    extern int  _fgetfileinfo(FILE *fp, struct _fileinfo *info);

Description

This function retrieves information about the I/O stream pointed to by fp, placing the information into the structure pointed to by info.

Pointer fp points to a previously opened I/O stream. If the stream pointed to by fp has been closed by a prior call to fclose(), the behavior is undefined. If pointer fp is null, the function fails.

If pointer info is null, the only meaningful result of the function is its return value (which can be used to determine if the file exists and is accessible by the execution unit).

Returns

If the retrieval of the information for the stream is successful, the function returns a positive value. If unsuccessful, the function returns a negative value after modifying the value of errno (which is defined in the <errno.h> standard header).


6. Examples

Example 1

The following program displays information about a given file name.

    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>

    void print_file_info(const char *fname)
    {
        struct _fileinfo    info;
        char                tbuf[40];

        // Retrieve information about the file name
        if (_getfileinfo(fname, &info) < 0)
        {
            // Failed
            printf("Can't get info for: %s, %s\n",
                fname, strerror(errno));
            return;
        }

        // Display the file type
        switch (info.fi_type)
        {
        case _FILE_TYPE_FILE:
            printf("f");
            break;
        case _FILE_TYPE_DIR:
            printf("d");
            break;
        case _FILE_TYPE_UNKNOWN:
        default:
            printf("?");
        }

        // Display the file permissions
        if ((info.fi_perms & _FILE_PERM_READ) != 0)
            printf("r");
        else
            printf("-");

        if ((info.fi_perms & _FILE_PERM_WRITE) != 0)
            printf("w");
        else
            printf("-");

        if (info.fi_type == _FILE_TYPE_FILE  &&
            info.fi_perms & _FILE_PERM_EXEC
            printf("x");
        else if (info.fi_type == _FILE_TYPE_DIR  &&
            info.fi_perms & _FILE_PERM_SEARCH)
            printf("s");
        else
            printf("-");

        // Display the file size
        printf(" %12lld", info.fi_size);

        // Display the file modification time
        if (info.fi_modified != _TIME_ERROR)
        {
            struct tm   ts;

            ts = *localtime(&info.fi_modified);
            strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M", &ts);
        }
        else
            sprintf(tbuf, "unknown");
        printf(" %16s", tbuf);

        // Display the file serial number
        if (info.fi_id != -1)
            printf(" %5ld", info.fi_id);
        else
            printf(" %5s", "-");

        // Display the file name
        printf("  %s\n", fname);
    }

    int main(int argc, char **argv)
    {
        // Print information about each filename arg
        for (int i = 1;  i < argc;  i++)
            print_file_info(argv[i]);

        return (EXIT_SUCCESS);
    }

Appendix A

This proposal defines a minimum useful set of file types. However, implementations are free to provide additional file types.

For example, POSIX (Unix) systems could provide the following macros:

_FILE_TYPE_CHAR
A character device.
_FILE_TYPE_BLOCK
A block device.
_FILE_TYPE_PIPE
A pipe (FIFO).
_FILE_TYPE_SOCKET
A socket.
_FILE_TYPE_SYMLINK
A symbolic link.

Microsoft DOS and Windows systems could provide the following macros:

_FILE_TYPE_VOLUME
A volume (hard disk) label.
_FILE_TYPE_DEV
An I/O device, e.g., "con", "lpt1:", etc.

Appendix B

This proposal defines a minimum useful set of file permissions. However, implementations are free to provide additional permissions bits.

For example, the following values could be provided by POSIX and Unix implementations:

_FILE_PERM_READ_USER
The file is readable by its owner (user).
_FILE_PERM_READ_GROUP
The file is readable by its owner's group.
_FILE_PERM_READ_OTHER
The file is readable by all other users.

_FILE_PERM_WRITE_USER
_FILE_PERM_WRITE_GROUP
_FILE_PERM_WRITE_OTHER
The file is readable.

_FILE_PERM_EXEC_USER
_FILE_PERM_EXEC_GROUP
_FILE_PERM_EXEC_OTHER
The file is executable.

_FILE_PERM_SEARCH_USER
_FILE_PERM_SEARCH_GROUP
_FILE_PERM_SEARCH_OTHER
The directory is searchable.

_FILE_PERM_STICKY
Corresponds to the POSIX "sticky" execution bit, which keeps an executable program image in memory after it terminates.

_FILE_PERM_SETUSER
An executable program file that assumes the user-ID of the user that owns the file.

_FILE_PERM_SETGROUP
An executable program file that assumes the group-ID of the user that owns the file.

The following values could be provided by Microsoft Windows and DOS implementations:

_FILE_PERM_ARCHIVE
The file has not been archived (backed up) since it was last modified.

_FILE_PERM_SYSTEM
The file can only be accessed by system tasks.

_FILE_PERM_HIDDEN
The file is hidden, i.e., it is not normally visible in directory searches.

_FILE_PERM_COMPRESSED
The file (or device) is compressed.

_FILE_PERM_TEMP
The file is a temporary file, and will be removed after the program that created it terminates.


Prior Art

  1. POSIX [2] defines the stat() and fstat() system library functions which retrieve information about a file, filling a stat structure.

    There are difficulties with trying to integrate the POSIX stat structure into the ISO C library, however. While it is reasonable to exclude the structure members that are not general enough for all hosted implementations (e.g., st_gid) and simply allow these to be implemented in POSIX as extensions to ISO C, a few problems still remain.

    1. The st_mode member actually represents two attributes of a file, its type (file, directory, etc.) and its access permissions (read, write, etc.). It is a cleaner approach to split the two attributes into separate members (thus fi_type and fi_perms). Adding an additional member would force a change to the existing POSIX structure specification.

    2. There is no member in the stat structure that represents the creation time of the file (the st_ctime member represents the time of the last i-node status change). While this omission is fine for POSIX, it ignores the capabilities of many other operating systems. Adding such a member (fi_created, or st_otime) would force a change to the existing POSIX structure specification.

    3. The st_mode permissions bits reflect a Unix-centric concept of user/group/other access levels. It does not seem reasonable to add these concepts to ISO C, since they are of use nowhere else in the standard. The simpler approach is to ignore the multi-level access concepts and provide simple, single-level READ/WRITE permissions. This approach is universally acceptable on all hosted implementations, for the simple reason that these permissions must already be checked by the fopen() function.

    4. While the POSIX stat() function could be accepted into ISO C, the fstat() function could not because it takes a file descriptor argument, a concept that does not exist anywhere in ISO C (note that there is no standard fileno() function). The corresponding capability would be a function that takes a file pointer argument (of type FILE *), which would of course have to have a name other than fstat(), e.g., fpstat(). Adding such a function would force a change to POSIX, albeit a minor one.

    Unless the same functionality (or a proper subset of the functionality) as POSIX is provided by a new ISO C function named stat(), that function name cannot be added to the standard, because this would render existing POSIX systems nonconforming.

    Additions of the members described in items (a) and (b) above force POSIX to be modified in order to conform to ISO C, meaning that even a stripped-down version of the current struct stat specification could not be accepted into ISO C.

    The conclusion is that rather than choosing one implementation (widespread as it is) as the model to standardize, it is better to invent a new, simpler model that (practically) all implementations can support.

  2. Several compilers for the Microsoft Windows (Win32 [4]) operating system support simplified versions of the POSIX stat() and fstat() functions, though imperfectly (e.g., the st_ino member has no defined value). Win32 also provides a native GetFileInformationByHandle() system call, which fills a BY_HANDLE_FILE_INFORMATION structure.

    Win32 also provides directory searching functions FindFirstFile() and FindNextFile() that fill a WIN32_FIND_DATA structure with file attributes.

    Win32 provides the creation time as one of the attributes of a file.


Source Code

Proof-of-concept source code is contained in these files:


Acknowledgements

The author wishes to express his gratitude to those who provided comments, suggestions, and critism on this proposal.

Further discussion can be found on the comp.std.c newsgroup, under the subject "C0X: File information funcs".


Related Proposals

[P1]  ISO C/200X Proposal: File System Inquiry Functions
David R. Tribble, Sep 2003.
http://david.tribble.com/text/c0xfilesys.html
A related proposal specifying functions for interrogating the implementation about a given file system.

[P2]  ISO C/200X Proposal: Directory Access Functions
David R. Tribble, Oct 2003.
http://david.tribble.com/text/c0xdir.html
A related proposal specifying functions for creating and reading directories, and for managing directory and file names.

[P3]  ISO C 200X Proposal: Long Time Type
David R. Tribble, Jun 2004.
http://david.tribble.com/text/c0xlongtime.html
A related proposal specifying a long time type and supporting functions for manipulating system time values. Defines an extended-precision, extended-range longtime_t time type.


References

[1]  Programming Language C - ISO/IEC 9899:1999 - International Standard
1999, ISO/EIC.
International Standards Organization, http://www.iso.ch.
Available from the American National Standards Institute (ANSI) site at http://www.ansi.org.
The ISO C (C99) standard.

[2]  Portable Operating System Interface for Computer Environments - IEEE Standard
IEEE Std 1003.1-1998, ISBN 1-55937-003-3.
Sep 1988, The Institute of Electrical and Electronics Engineers (IEEE), Inc.
The standard POSIX definition.

[3]  Open Group Single Unix Specification
The Open Group.
Available online at http://www.opengroup.org
The standard Unix definition.

[4]  Microsoft Windows API Reference
1995, Microsoft, http://www.microsoft.com.
The API reference is available online at http://www.msdn.com
The Win32 definition.


Revision History

2.4, 2005-08-10
Renamed the _TIME_UNKNOWN constant to _TIME_ERROR.
Added member fi_revised to the _fileinfo structure.
Added the "Related Proposals" section.
Minor corrections made.

2.3, 2003-12-30
Minor corrections made.
Changed the contents of member fi_filesys to be a null-terminated character string.

2.2, 2003-10-10
Added the "Problems Addressed" section.
Added member fi_filesys.
Added a detailed explanation in the "Prior Art" section on the rationale of not using the POSIX stat structure as the basis for this proposal.
Added the "Acknowledgements" section.

2.1, 2003-10-07
Minor corrections made.
Changed the type of member fi_id to long int.
Added the "Source Code" section.
The functions modify errno.

2.0, 2003-10-06
Rewrote the entire document.

1.1, 1998-10-15
HTML additions.

1.0, 1998-02-15
First cut.


This document is in the public domain. Permission is granted to freely redistribute, copy, or reference this document.

This document: http://david.tribble.com/text/c0xfstat.html.

Author's email address: david@tribble.com.
Author's home page: http://david.tribble.com.