Date: Tue, 24 Sep 1996 14:14:23 +0200 (IST) From: Eli Zaretskii To: djgpp-workers AT delorie DOT com Subject: `fstat' for Windows 95 Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII The following changes teach `fstat' about the other 2 time fields that Windows 95 offers (`stat' already knows about them). There is also a small LFN function that can be used on its own. With these, I was able to build GNU `touch' which can change the two times you get on Unix. *** src/libc/posix/sys/stat/fstat.c~1 Wed Jan 24 03:30:20 1996 --- src/libc/posix/sys/stat/fstat.c Sat Sep 21 18:26:48 1996 *************** *** 97,102 **** --- 97,103 ---- #include #include #include + #include #include #include *************** *** 330,335 **** --- 331,359 ---- return -2; } + /* On LFN platforms, we can get all the 3 time-related fields. */ + + static void + set_fstat_times (int fhandle, struct stat *stat_buf) + { + if (_USE_LFN) + { + time_t access_time; + unsigned int create_time; + + /* Access time is currently date only (time is zeroed). */ + access_time = _file_time_stamp (_lfn_get_ftime (fhandle, _LFN_ATIME)); + if (access_time > stat_buf->st_atime) + stat_buf->st_atime = access_time; + + /* Creation time might be zero if the file was created + by a DOS program which doesn't support LFN API. */ + create_time = _lfn_get_ftime (fhandle, _LFN_CTIME); + if (create_time) + stat_buf->st_ctime = _file_time_stamp (create_time); + } + } + /* fstat_assist() is where all the actual work is done. * It uses SFT entry, if available and its contents are verified. * Otherwise, it finds all the available info by conventional *************** *** 635,640 **** --- 659,666 ---- stat_buf->st_atime = stat_buf->st_ctime = stat_buf->st_mtime = _file_time_stamp(dos_ftime); + /* Additional time info for LFN platforms. */ + set_fstat_times (fhandle, stat_buf); return 0; } *************** *** 749,754 **** --- 775,783 ---- stat_buf->st_size = trusted_fsize; stat_buf->st_atime = stat_buf->st_ctime = stat_buf->st_mtime = _file_time_stamp(dos_ftime); + + /* Additional time info for LFN platforms. */ + set_fstat_times (fhandle, stat_buf); } return 0; } *************** *** 837,842 **** --- 866,874 ---- (long)stat_buf.st_size, (unsigned long)stat_buf.st_mtime, ctime(&stat_buf.st_mtime)); + fprintf (stderr, "\t\t\tTimes: %lu %lu\n", + (unsigned long)stat_buf.st_atime, + (unsigned long)stat_buf.st_ctime); _djstat_describe_lossage(stderr); } else *** src/libc/dos/lfn/lfnftime.c~0 Sat Sep 21 15:55:02 1996 --- src/libc/dos/lfn/lfnftime.c Sat Sep 21 15:15:48 1996 *************** *** 0 **** --- 1,30 ---- + #include + #include + #include + #include + #include + + unsigned + _lfn_get_ftime (int fhandle, int which) + { + unsigned xtime; + __dpmi_regs r; + + if (which != _LFN_CTIME && which != _LFN_ATIME) + { + errno = EINVAL; + return 0; + } + r.x.ax = which == _LFN_ATIME ? 0x5704 : 0x5706; + r.x.bx = fhandle; + __dpmi_int (0x21, &r); + if (r.x.flags & 1) + { + errno = __doserr_to_errno (r.x.ax); + return 0; + } + xtime = r.x.dx; + xtime = (xtime << 16) | r.x.cx; + return xtime; + } + *** src/libc/dos/lfn/_use_lfn.t~1 Sat Aug 17 13:00:20 1996 --- src/libc/dos/lfn/_use_lfn.txh Sat Sep 21 15:59:48 1996 *************** *** 228,230 **** --- 228,305 ---- return retval; @} @end example + + @c ----------------------------------------------------------------------- + + @node _lfn_get_ftime, file system + @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 Example + + @example + unsigned file_stamp = _lfn_get_ftime (handle, _LFN_CTIME); + @end example *** src/libc/dos/lfn/makefile.~1~ Fri Aug 16 15:15:42 1996 --- src/libc/dos/lfn/makefile Sat Sep 21 15:48:30 1996 *************** *** 4,8 **** --- 4,9 ---- SRC += _use_lfn.c SRC += lfnshort.c SRC += fncase.c + SRC += lfnftime.c include $(TOP)/../makefile.inc *** include/fcntl.h~1 Fri Aug 16 13:07:32 1996 --- include/fcntl.h Sat Sep 21 15:13:24 1996 *************** *** 104,109 **** --- 104,115 ---- unsigned _get_volume_info (const char *_path, int *_max_file_len, int *_max_path_len, char *_filesystype); char _use_lfn (const char *_path); char *_lfn_gen_short_fname (const char *_long_fname, char *_short_fname); + + #define _LFN_CTIME 1 + #define _LFN_ATIME 2 + + unsigned _lfn_get_ftime (int _handle, int _which); + char _preserve_fncase (void); #define _USE_LFN _use_lfn(0) /* assume it's the same on ALL drives */