file/fat: add utime function
This emulates the traditional utime function from UNIX clones to allow for manual updates of the modification timestamp on files and directories. This should only prove useful for non-native targets as those usually have a libc version of utime. Change-Id: Iea8a1d328e78b92c400d3354ee80689c7cf53af8
This commit is contained in:
parent
e6ee3dd17c
commit
c174d3a544
6 changed files with 87 additions and 0 deletions
|
@ -1123,6 +1123,44 @@ file_error:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int utime(const char *path, const struct utimbuf* times)
|
||||
{
|
||||
DEBUGF("utime(path=\"%s\",times->modtime=%u)\n", path, times->modtime);
|
||||
|
||||
int rc, open1rc = -1;
|
||||
struct filestr_base pathstr;
|
||||
struct path_component_info pathinfo;
|
||||
|
||||
file_internal_lock_WRITER();
|
||||
|
||||
if (!times)
|
||||
FILE_ERROR(EINVAL, -1);
|
||||
|
||||
open1rc = open_stream_internal(path, FF_ANYTYPE | FF_PARENTINFO,
|
||||
&pathstr, &pathinfo);
|
||||
if (open1rc <= 0)
|
||||
{
|
||||
DEBUGF("Failed opening path: %d\n", open1rc);
|
||||
if (open1rc == 0)
|
||||
FILE_ERROR(ENOENT, -2);
|
||||
else
|
||||
FILE_ERROR(ERRNO, open1rc * 10 - 1);
|
||||
}
|
||||
|
||||
rc = fat_utime(&pathinfo.parentinfo.fatfile, pathstr.fatstr.fatfilep,
|
||||
times);
|
||||
if (rc < 0)
|
||||
{
|
||||
DEBUGF("I/O error during utime: %d\n", rc);
|
||||
FILE_ERROR(ERRNO, rc * 10 - 2);
|
||||
}
|
||||
|
||||
file_error:
|
||||
if (open1rc >= 0)
|
||||
close_stream_internal(&pathstr);
|
||||
file_internal_unlock_WRITER();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** Extensions **/
|
||||
|
||||
|
|
|
@ -2276,6 +2276,41 @@ fat_error:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int fat_utime(struct fat_file *parent, struct fat_file *file,
|
||||
const struct utimbuf *times)
|
||||
{
|
||||
struct bpb * const fat_bpb = FAT_BPB(parent->volume);
|
||||
|
||||
if (!fat_bpb)
|
||||
return -1;
|
||||
|
||||
int rc;
|
||||
|
||||
struct fat_filestr parentstr;
|
||||
fat_filestr_init(&parentstr, parent);
|
||||
|
||||
dc_lock_cache();
|
||||
|
||||
union raw_dirent *ent = cache_direntry(fat_bpb, &parentstr, file->e.entry);
|
||||
if (!ent)
|
||||
FAT_ERROR(-2);
|
||||
|
||||
uint16_t date;
|
||||
uint16_t time;
|
||||
dostime_localtime(times->modtime, &date, &time);
|
||||
|
||||
ent->wrttime = htole16(time);
|
||||
ent->wrtdate = htole16(date);
|
||||
ent->lstaccdate = htole16(date);
|
||||
|
||||
dc_dirty_buf(ent);
|
||||
|
||||
rc = 0;
|
||||
fat_error:
|
||||
dc_unlock_cache();
|
||||
cache_commit(fat_bpb);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** File stream functions **/
|
||||
|
||||
|
|
|
@ -140,6 +140,8 @@ enum fat_remove_op /* what should fat_remove(), remove? */
|
|||
int fat_remove(struct fat_file *file, enum fat_remove_op what);
|
||||
int fat_rename(struct fat_file *parent, struct fat_file *file,
|
||||
const unsigned char *newname);
|
||||
int fat_utime(struct fat_file *parent, struct fat_file *file,
|
||||
const struct utimbuf *utimes);
|
||||
|
||||
/** File stream functions **/
|
||||
int fat_closewrite(struct fat_filestr *filestr, uint32_t size,
|
||||
|
|
|
@ -85,6 +85,9 @@ int fdprintf(int fildes, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
|
|||
#ifndef rename
|
||||
#define rename FS_PREFIX(rename)
|
||||
#endif
|
||||
#ifndef utime
|
||||
#define utime FS_PREFIX(utime)
|
||||
#endif
|
||||
#ifndef filesize
|
||||
#define filesize FS_PREFIX(filesize)
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#define __OPEN_MODE_ARG
|
||||
#define __CREAT_MODE_ARG
|
||||
|
||||
#include <time.h>
|
||||
|
||||
int open(const char *name, int oflag);
|
||||
int creat(const char *name);
|
||||
int close(int fildes);
|
||||
|
@ -53,6 +55,7 @@ ssize_t read(int fildes, void *buf, size_t nbyte);
|
|||
ssize_t write(int fildes, const void *buf, size_t nbyte);
|
||||
int remove(const char *path);
|
||||
int rename(const char *old, const char *new);
|
||||
int utime(const char *path, const struct utimbuf* times);
|
||||
off_t filesize(int fildes);
|
||||
int fsamefile(int fildes1, int fildes2);
|
||||
int relate(const char *path1, const char *path2);
|
||||
|
|
|
@ -28,6 +28,12 @@ struct tm
|
|||
#if !defined(_TIME_T_DEFINED) && !defined(_TIME_T_DECLARED)
|
||||
typedef long time_t;
|
||||
|
||||
struct utimbuf
|
||||
{
|
||||
time_t actime;
|
||||
time_t modtime;
|
||||
};
|
||||
|
||||
/* this define below is used by the mingw headers to prevent duplicate
|
||||
typedefs */
|
||||
#define _TIME_T_DEFINED
|
||||
|
|
Loading…
Reference in a new issue