@node _use_lfn, file system @findex _use_lfn @vindex LFN@r{ environment variable} @subheading Syntax @example #include char _use_lfn(const char *path); @end example @subheading Description The @code{_use_lfn} function returns a nonzero value if the low level libc routines will use the @dfn{Long File Name} (LFN) functions provided with Windows 9x (and other advanced filesystems), when accessing files and directories on the same filesystem as @var{path}. @var{path} may be any legal pathname; however, the function only needs the name of the root directory on the particular drive in question. If @var{path} is a @code{NULL} pointer, the function assumes that all the filesystems support (or do not support) LFN in the same manner, and returns the info pertinent to the last filesystem that was queried; this usually makes the call faster. Note that on Windows 95 you don't need to distinguish between different drives: they all support LFN API. If @var{path} does not specify the drive explicitly, the current drive is used. The header @file{fcntl.h} defines a macro @code{_USE_LFN}; applications should use this macro instead of calling @code{_use_lfn} directly. That is so this routine could be replaced with one which always returns 0 to disable using long file names. Calling @code{_USE_LFN} also makes the code more portable to other operating systems, where the macro can be redefined to whatever is appropriate for that environment (e.g., it should be a constant 1 on Unix systems and constant 0 for environments that don't support LFN API, like some other MSDOS compilers). Currently, @code{_USE_LFN} assumes that LFN API does @emph{not} depend on a drive. Long file names can also be disabled by setting the flag @code{_CRT0_FLAG_NO_LFN} in @code{_crt0_startup_flags} for an image which should not allow use of long file names. Long names can be suppressed at runtime on a global basis by setting the environment variable @code{LFN} to @code{N}, i.e. @samp{SET LFN=N}. This might be needed if a distribution expected the truncation of long file names to 8.3 format to work. For example, if a C source routine included the file exception.h (9 letters) and the file was unzipped as exceptio.h, then GCC would not find the file unless you set @samp{LFN=n}. The environment variable can be set in the @file{DJGPP.ENV} file to always disable LFN support on any system, or can be set in the DOS environment for a short term (single project) basis. If you dual boot a system between Windows 95 and DOS, you probably should set @samp{LFN=n} in your @file{DJGPP.ENV} file, since long file names would not be visible under DOS, and working with the short names under DOS will damage the long names when returning to Windows 95. @subheading Return Value If LFN APIs are supported and should be used, it returns 1, else 0. Note that if the @code{_CRT0_FLAG_NO_LFN} bit is set, or @code{LFN} is set to @code{N} or @code{n} in the environment, both @code{_use_lfn} and @code{_USE_LFN} will always return 0 without querying the filesystem. You can reset the @code{_CRT0_FLAG_NO_LFN} bit at runtime to force filesystem to be queried. @subheading Portability @portability !ansi, !posix @subheading Example @example #include #include int fd = creat (_USE_LFN ? "MyCurrentJobFile.Text" : "currjob.txt", S_IRUSR | S_IWUSR); @end example @c -------------------------------------------------------------------- @node _get_volume_info, file system @findex _get_volume_info @subheading Syntax @example #include unsigned _get_volume_info (const char *path, int *max_file_len, int *max_path_len, char *fsystype); @end example @subheading Description This function returns filesystem information about the volume where @var{path} resides. Only the root directory name part is actually used; if @var{path} does not specify the drive explicitly, or is a @code{NULL} pointer, the current drive is used. Upon return, the variable pointed to by @var{max_file_len} contains the maximum length of a filename (including the terminating zero), the variable pointed to by @var{max_path_len} contains the maximum length of a pathname (including the terminating zero), and a string that identifies the filesystem type (e.g., ``FAT'', ``NTFS'' etc.) is placed into the buffer pointed to by @var{fsystype}, which should be long enough (32 bytes are usually enough). If any of these pointers is a @code{NULL} pointer, it will be ignored. The function returns various flags that describe features supported by the given filesystem as a bit-mapped number. The following bits are currently defined: @table @code @item _FILESYS_CASE_SENSITIVE Specifies that file searches are case-sensitive. @item _FILESYS_CASE_PRESERVED Filename letter-case is preserved in directory entries. @item _FILESYS_UNICODE Filesystem uses Unicode characters in file and directory names. @item _FILESYS_LFN_SUPPORTED Filesystem supports the @dfn{Long File Name} (LFN) API. @item _FILESYS_VOL_COMPRESSED This volume is compressed. @item _FILESYS_UNKNOWN The underlying system call failed. This usually means that the drive letter is invalid, like when a floppy drive is empty or a drive with that letter doesn't exist. @end table @subheading Return value A combination of the above bits if the LFN API is supported, or 0 (and @code{errno} set to @code{ENOSYS}) if the LFN API is not supported by the OS. If the LFN API is supported, but the drive letter is invalid, the function returns @code{_FILESYS_UNKNOWN} and sets @code{errno} to either @code{ENODEV} or @code{ENXIO}. @subheading Portability @portability !ansi, !posix @c ----------------------------------------------------------------------- @node _preserve_fncase, file system @findex _preserve_fncase @vindex FNCASE@r{ environment variable} @vindex LFN@r{ environment variable, and file-name case} @subheading Syntax @example #include char _preserve_fncase (void); @end example @subheading Description This function returns a non-zero value if letter-case in filenames should be preserved. It is used by library functions that get filenames from the operating system (like @code{readdir}, @code{_fixpath} and others). The usual behavior of these functions (when @code{_preserve_fncase} returns zero) is to down-case 8+3 DOS-style filenames, but leave alone the letter-case in long filenames when these are supported (@pxref{_use_lfn}). This can be changed by either setting @code{_CRT0_FLAG_PRESERVE_FILENAME_CASE} bit in the @code{_crt0_startup_flags} variable (@pxref{_crt0_startup_flags}), or by setting the @code{FNCASE} environment variable to @kbd{Y} at run time. You might need such a setup e.g. on Windows 95 if you want to see files with names like @file{README} and @file{FAQ} listed in upper-case (for this to work, you will have to manually rename all the other files with 8+3 DOS-style names to lower-case names). When the case in filenames is preserved, all filenames will be returned in upper case on MSDOS (and other systems that don't support long filenames), or if the environment variable @code{LFN} is set to @kbd{N} on systems that support LFN. That is because this is how filenames are stored in the DOS directory entries. @subheading Return value Zero when 8+3 filenames should be converted to lower-case, non-zero otherwise. @subheading Portability @portability !ansi, !posix @c ----------------------------------------------------------------------- @node _lfn_gen_short_fname, file system @findex _lfn_gen_short_fname @subheading Syntax @example #include char * _lfn_gen_short_fname (const char *long_fname, char *short_fname); @end example @subheading Description This function generates a short (8+3) filename alias for the long filename pointed to by @var{long_fname} and puts it into the buffer pointed to by @var{short_fname}. It uses the same algorithm that Windows 9x uses, with the exception that the returned short name will never have a numeric tail, because this function doesn't check the directory to see whether the generated short name will collide with any other file in the directory. Note that @var{long_fname} must contain only the name part of a file; elements of a full pathname (like @kbd{:} or @kbd{/} are not allowed (they will cause the function to fail). @var{short_fname} will be returned upper-cased, since that is how 8+3 filenames are stored in directory entries. When the LFN API is not supported (@pxref{_use_lfn}), the function simply converts up to 12 characters of @var{long_fname} to upper-case and returns that. It will do the same if @var{long_fname} includes any characters illegal in a filename. This function returns incorrect results on Windows 2000 and Windows XP due to bugs in the implementation of the DPMI call on those platforms. Do not use this function in those environments. You might need to call this function if you want to know whether a given filename is valid on MSDOS: if a case-sensitive string comparison function such as @code{strcmp} (@pxref{strcmp}) returns a 0 when it compares the original long filename with the short one returned by @code{_lfn_gen_short_fname}, then the filename is a valid DOS name. (Note that if @var{long_fname} is in lower case, it might not compare equal with @var{short_fname} because of the case difference.) @subheading Return value The function returns a pointer to @var{short_fname}. @subheading Portability @portability !ansi, !posix @subheading Example @example #include #include #include int dos_check (char *fname) @{ char fshort[13]; int retval; if (stricmp (_lfn_gen_short_fname (fname, fshort), fname) == 0) @{ printf ("%s is a valid MSDOS 8+3 filename\n", fname); retval = 1; @} else @{ printf ("%s will have to be changed for MSDOS\n", fname); retval = 0; @} return retval; @} @end example @c ----------------------------------------------------------------------- @node _lfn_get_ftime, file system @findex _lfn_get_ftime @subheading Syntax @example #include char _lfn_get_ftime (int fhandle, int flag); @end example @subheading Description This function returns creation and access time for files that reside on a filesystem which supports long filenames (such as Windows 95). Files which reside on native FAT filesystems will cause this function to fail. The @var{fhandle} parameter is the file handle as returned by one of the functions which open or create files. The @var{flag} parameter determines which time (creation or access) is returned. It can be set to one of the following: @table @code @item _LFN_ATIME Causes @code{_lfn_get_ftime} to return the time when the file was last accessed. (Currently, it actually only returns the @emph{date} of last access; the time bits are all zeroed.) @item _LFN_CTIME Causes @code{_lfn_get_ftime} to return the time when the file was created. Note that if the file was created by a program which doesn't support long filenames, this time will be zero. @end table @subheading Return value The file time stamp, as a packed unsigned int value: @table @code @item Bits 0-4 seconds divided by 2 @item Bits 5-10 minutes (0-59) @item Bits 11-15 hours (0-23) @item Bits 16-20 day of the month (1-31) @item Bits 21-24 month (1 = January) @item Bits 25-31 year offset from 1980 (add 1980 to get the actual year) @end table If the underlying system calls fail, the function will return 0 and set @code{errno} to an appropriate value. @subheading Portability @portability !ansi, !posix @subheading Example @example unsigned file_stamp = _lfn_get_ftime (handle, _LFN_CTIME); @end example @c ----------------------------------------------------------------------- @node _is_DOS83, file system @findex _is_DOS83 @subheading Syntax @example #include int _is_DOS83 (const char *fname); @end example @subheading Description This function checks the filename pointed to by @var{fname} to determine if it is a standard short (8+3) form file name. The filename should only include the name part of the file. It is expected the filename will contain a valid long or short file name (no validation is done to exclude path characters or characters always illegal in any file name). Note: If the filename contains lower case characters the name is considered to be a long name and not a standard short name (and the function will return 0). The function will return 0 (failure) if there are more than 8 characters before a period, more than 3 characters after a period, more than one period, starts with a period, any lower case characters, or any of the special characters @samp{+} @samp{,} @samp{;} @samp{=} @samp{[} @samp{]}, or a space. The special names @file{.} and @file{..} are exceptions and will return success. This function could be called to determine if a filename is valid on DOS before long file name support. If this function returns 1 the filename probably does not have a long name entry on a FAT file system. The library internally calls this function to determine if a file should have its name lower cased when @pxref{_preserve_fncase} is false. @subheading Return value The function returns an integer 0 (not DOS 8.3) or 1 (DOS 8.3) @subheading Portability @portability !ansi, !posix