Add UTIME_NOW and UTIME_OMIT.

This commit is contained in:
Jonas 'Sortie' Termansen 2016-02-24 16:29:37 +01:00
parent 02c6316e95
commit ede0571926
11 changed files with 78 additions and 62 deletions

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2013, 2014, 2015, 2016.
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@ -243,10 +243,21 @@ void HandleUTimens(int chl, struct fsm_req_utimens* msg, Filesystem* fs)
if ( !fs->device->write ) { RespondError(chl, EROFS); return; }
Inode* inode = SafeGetInode(fs, msg->ino);
if ( !inode ) { RespondError(chl, errno); return; }
inode->BeginWrite();
inode->data->i_atime = msg->times[0].tv_sec;
inode->data->i_mtime = msg->times[1].tv_sec;
inode->FinishWrite();
if ( msg->times[0].tv_nsec != UTIME_OMIT ||
msg->times[1].tv_nsec != UTIME_OMIT )
{
time_t now = time(NULL);
inode->BeginWrite();
if ( msg->times[0].tv_nsec == UTIME_NOW )
inode->data->i_atime = now;
else if ( msg->times[0].tv_nsec != UTIME_OMIT )
inode->data->i_atime = msg->times[0].tv_sec;
if ( msg->times[1].tv_nsec == UTIME_NOW )
inode->data->i_mtime = now;
else if ( msg->times[1].tv_nsec != UTIME_OMIT )
inode->data->i_mtime = msg->times[1].tv_sec;
inode->FinishWrite();
}
inode->Unref();
RespondSuccess(chl);
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -337,12 +337,29 @@ ssize_t Descriptor::pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count, off_t
return vnode->pwrite(ctx, buf, count, off);
}
int Descriptor::utimens(ioctx_t* ctx,
const struct timespec* atime,
const struct timespec* ctime,
const struct timespec* mtime)
static inline bool valid_utimens_timespec(struct timespec ts)
{
return vnode->utimens(ctx, atime, ctime, mtime);
return ts.tv_nsec < 1000000000 ||
ts.tv_nsec == UTIME_NOW ||
ts.tv_nsec == UTIME_OMIT;
}
int Descriptor::utimens(ioctx_t* ctx, const struct timespec* user_times)
{
struct timespec times[2];
if ( !user_times )
{
times[0].tv_sec = 0;
times[0].tv_nsec = UTIME_NOW;
times[1].tv_sec = 0;
times[1].tv_nsec = UTIME_NOW;
}
else if ( !ctx->copy_from_src(&times, user_times, sizeof(times)) )
return -1;
if ( !valid_utimens_timespec(times[0]) ||
!valid_utimens_timespec(times[1]) )
return errno = EINVAL;
return vnode->utimens(ctx, times);
}
int Descriptor::isatty(ioctx_t* ctx)

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -213,9 +213,7 @@ public:
virtual ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count);
virtual ssize_t pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count,
off_t off);
virtual int utimens(ioctx_t* ctx, const struct timespec* atime,
const struct timespec* ctime,
const struct timespec* mtime);
virtual int utimens(ioctx_t* ctx, const struct timespec* times);
virtual int isatty(ioctx_t* ctx);
virtual ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent,
size_t size, off_t start);
@ -974,10 +972,7 @@ ssize_t Unode::pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count, off_t off)
return ret;
}
int Unode::utimens(ioctx_t* ctx,
const struct timespec* atime,
const struct timespec* /*ctime*/,
const struct timespec* mtime)
int Unode::utimens(ioctx_t* ctx, const struct timespec* times)
{
Channel* channel = server->Connect(ctx);
if ( !channel )
@ -985,8 +980,8 @@ int Unode::utimens(ioctx_t* ctx,
int ret = -1;
struct fsm_req_utimens msg;
msg.ino = ino;
msg.times[0] = atime ? *atime : timespec_nul();
msg.times[1] = mtime ? *mtime : timespec_nul();
msg.times[0] = times[0];
msg.times[1] = times[1];
if ( SendMessage(channel, FSM_REQ_UTIMENS, &msg, sizeof(msg)) &&
RecvMessage(channel, FSM_RESP_SUCCESS, NULL, 0) )
ret = 0;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -72,8 +72,7 @@ public:
ssize_t pread(ioctx_t* ctx, uint8_t* buf, size_t count, off_t off);
ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count);
ssize_t pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count, off_t off);
int utimens(ioctx_t* ctx, const struct timespec* atime,
const struct timespec* ctime, const struct timespec* mtime);
int utimens(ioctx_t* ctx, const struct timespec* times);
int isatty(ioctx_t* ctx);
ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, size_t size);
Ref<Descriptor> open(ioctx_t* ctx, const char* filename, int flags,

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -72,9 +72,7 @@ public:
virtual ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count) = 0;
virtual ssize_t pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count,
off_t off) = 0;
virtual int utimens(ioctx_t* ctx, const struct timespec* atime,
const struct timespec* ctime,
const struct timespec* mtime) = 0;
virtual int utimens(ioctx_t* ctx, const struct timespec* times) = 0;
virtual int isatty(ioctx_t* ctx) = 0;
virtual ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent,
size_t size, off_t start) = 0;
@ -167,9 +165,7 @@ public:
virtual ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count);
virtual ssize_t pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count,
off_t off);
virtual int utimens(ioctx_t* ctx, const struct timespec* atime,
const struct timespec* ctime,
const struct timespec* mtime);
virtual int utimens(ioctx_t* ctx, const struct timespec* times);
virtual int isatty(ioctx_t* ctx);
virtual ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent,
size_t size, off_t start);

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -69,8 +69,7 @@ public:
ssize_t pread(ioctx_t* ctx, uint8_t* buf, size_t count, off_t off);
ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count);
ssize_t pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count, off_t off);
int utimens(ioctx_t* ctx, const struct timespec* atime,
const struct timespec* ctime, const struct timespec* mtime);
int utimens(ioctx_t* ctx, const struct timespec* times);
int isatty(ioctx_t* ctx);
ssize_t readdirents(ioctx_t* ctx, struct dirent* dirent, size_t size,
off_t start);

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -89,6 +89,9 @@ struct stat
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#define UTIME_NOW 0x3FFFFFFF
#define UTIME_OMIT 0x3FFFFFFE
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -293,9 +293,10 @@ static void ExtractNode(struct initrd_context* ctx,
ExtractDir(ctx, inode, node);
if ( INITRD_S_ISREG(inode->mode) )
ExtractFile(ctx, inode, node);
struct timespec ctime = timespec_make((time_t) inode->ctime, 0);
struct timespec mtime = timespec_make((time_t) inode->mtime, 0);
if ( node->utimens(&ctx->ioctx, &mtime, &ctime, &mtime) < 0 )
struct timespec times[2];
times[0] = timespec_make((time_t) inode->mtime, 0);
times[1] = timespec_make((time_t) inode->mtime, 0);
if ( node->utimens(&ctx->ioctx, times) < 0 )
PanicF("initrd: utimens: %m");
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -180,17 +180,20 @@ ssize_t AbstractInode::pwrite(ioctx_t* /*ctx*/, const uint8_t* /*buf*/,
return errno = EBADF, -1;
}
int AbstractInode::utimens(ioctx_t* /*ctx*/, const struct timespec* atime,
const struct timespec* ctime,
const struct timespec* mtime)
int AbstractInode::utimens(ioctx_t* /*ctx*/, const struct timespec* times)
{
ScopedLock lock(&metalock);
if ( atime )
stat_atim = *atime;
if ( ctime )
stat_ctim = *ctime;
if ( mtime )
stat_mtim = *mtime;
struct timespec now = { 0, 0 };
if ( times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW )
now = Time::Get(CLOCK_REALTIME);
if ( times[0].tv_nsec == UTIME_NOW )
stat_atim = now;
else if ( times[0].tv_nsec != UTIME_OMIT )
stat_atim = times[0];
if ( times[1].tv_nsec == UTIME_NOW )
stat_mtim = now;
else if ( times[1].tv_nsec != UTIME_OMIT )
stat_mtim = times[1];
return 0;
}

View File

@ -507,14 +507,11 @@ int sys_fchmodat(int dirfd, const char* path, mode_t mode, int flags)
int sys_futimens(int fd, const struct timespec* user_times)
{
struct timespec times[2];
if ( !CopyFromUser(times, user_times, sizeof(times)) )
return -1;
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
if ( !desc )
return -1;
ioctx_t ctx; SetupUserIOCtx(&ctx);
return desc->utimens(&ctx, &times[0], NULL, &times[1]);
return desc->utimens(&ctx, user_times);
}
int sys_utimensat(int dirfd, const char* path,
@ -522,9 +519,6 @@ int sys_utimensat(int dirfd, const char* path,
{
if ( flags & ~(AT_SYMLINK_NOFOLLOW) )
return errno = EINVAL, -1;
struct timespec times[2];
if ( !CopyFromUser(times, user_times, sizeof(times)) )
return -1;
char* pathcopy = GetStringFromUser(path);
if ( !pathcopy )
return -1;
@ -537,7 +531,7 @@ int sys_utimensat(int dirfd, const char* path,
delete[] pathcopy;
if ( !desc )
return -1;
return desc->utimens(&ctx, &times[0], NULL, &times[1]);
return desc->utimens(&ctx, user_times);
}
int sys_linkat(int olddirfd, const char* oldpath,

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015, 2016.
This file is part of Sortix.
@ -269,11 +269,9 @@ ssize_t Vnode::pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count, off_t off)
return inode->pwrite(ctx, buf, count, off);
}
int Vnode::utimens(ioctx_t* ctx, const struct timespec* atime,
const struct timespec* ctime,
const struct timespec* mtime)
int Vnode::utimens(ioctx_t* ctx, const struct timespec* times)
{
return inode->utimens(ctx, atime, ctime, mtime);
return inode->utimens(ctx, times);
}
int Vnode::isatty(ioctx_t* ctx)