Fix Android compile failure: st_mtim, UTIME_OMIT

Use utimes(2) instead of utimensat(2), use struct timeval instead of
struct timespec

Add strbuf helper functions for struct timeval and time_ms_t
This commit is contained in:
Andrew Bettison 2014-05-02 15:45:01 +09:30
parent 8e7d13fd27
commit 60201d78c9
3 changed files with 51 additions and 10 deletions

16
os.c
View File

@ -230,7 +230,7 @@ int get_file_meta(const char *path, struct file_meta *metap)
*metap = FILE_META_NONEXIST;
} else {
metap->size = st.st_size;
metap->mtime = st.st_mtim;
metap->mtime.tv_sec = st.st_mtime;
// Truncate to whole seconds to ensure that this code will work on file systems that only have
// whole-second time stamp resolution.
metap->mtime.tv_nsec = 0;
@ -319,12 +319,14 @@ int alter_file_meta(const char *path, const struct file_meta *origp, struct file
return 0;
meta.mtime = origp->mtime;
add_timespec(&meta.mtime, sec, nsec);
struct timespec times[2];
times[0].tv_sec = 0;
times[0].tv_nsec = UTIME_OMIT;
times[1] = meta.mtime;
if (utimensat(AT_FDCWD, path, times, 0) == -1)
return WHYF_perror("utimensat(AT_FDCWD,%s,[UTIME_OMIT,%s],0)", alloca_str_toprint(path), alloca_timespec(&times[1]));
struct timeval times[2];
time_ms_t now = gettime_ms();
times[0].tv_sec = now / 1000;
times[0].tv_usec = (now % 1000) * 1000;
times[1].tv_sec = meta.mtime.tv_sec;
times[1].tv_usec = meta.mtime.tv_nsec / 1000;
if (utimes(path, times) == -1)
return WHYF_perror("utimes(%s,[%s,%s])", alloca_str_toprint(path), alloca_timeval(&times[0]), alloca_timeval(&times[1]));
nsec = 0;
++sec;
}

View File

@ -460,6 +460,31 @@ strbuf strbuf_append_time_t(strbuf sb, time_t time)
return sb;
}
strbuf strbuf_append_time_ms_t(strbuf sb, time_ms_t ms)
{
struct tm tm;
time_t time = ms / 1000;
localtime_r(&time, &tm);
strbuf_append_strftime(sb, "%Y/%m/%d %H:%M:%S", &tm);
strbuf_sprintf(sb, ".%.03u", (unsigned)(ms % 1000));
strbuf_append_strftime(sb, " %z", &tm);
return sb;
}
strbuf strbuf_append_timeval(strbuf sb, const struct timeval *tv)
{
if (tv->tv_sec < 0 || tv->tv_usec < 0 || tv->tv_usec > 999999) {
strbuf_sprintf(sb, "INVALID{tv_sec=%ld,tv_usec=%ld}", (long)tv->tv_sec, (long)tv->tv_usec);
} else {
struct tm tm;
localtime_r(&tv->tv_sec, &tm);
strbuf_append_strftime(sb, "%Y/%m/%d %H:%M:%S", &tm);
strbuf_sprintf(sb, ".%.06lu", (long)tv->tv_usec);
strbuf_append_strftime(sb, " %z", &tm);
}
return sb;
}
strbuf strbuf_append_timespec(strbuf sb, const struct timespec *tv)
{
if (tv->tv_sec < 0 || tv->tv_nsec < 0 || tv->tv_nsec > 999999999) {

View File

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#endif
#include "strbuf.h"
#include "os.h"
/* Append a representation of the given chars in a given buffer (including nul
* chars) in printable format, ie, with non-printable characters expanded to \n
@ -161,18 +162,31 @@ struct iovec;
strbuf strbuf_append_iovec(strbuf sb, const struct iovec *iov, int iovcnt);
#define alloca_iovec(iov,cnt) strbuf_str(strbuf_append_iovec(strbuf_alloca(200), (iov), (cnt)))
/* Append a representation of a time_t value.
/* Append a representation of a time_t value (second resolution).
* @author Andrew Bettison <andrew@servalproject.com>
*/
strbuf strbuf_append_time_t(strbuf sb, time_t);
#define alloca_time_t(t) strbuf_str(strbuf_append_time_t(strbuf_alloca(40), (t)))
/* Append a representation of a struct timespec.
/* Append a representation of a time_ms_t value (millisecond resolution).
* @author Andrew Bettison <andrew@servalproject.com>
*/
strbuf strbuf_append_time_ms_t(strbuf sb, time_ms_t);
#define alloca_time_ms_t(t) strbuf_str(strbuf_append_time_ms_t(strbuf_alloca(45), (t)))
/* Append a representation of a struct timeval (microsecond resolution).
* @author Andrew Bettison <andrew@servalproject.com>
*/
struct timeval;
strbuf strbuf_append_timeval(strbuf sb, const struct timeval *tv);
#define alloca_timeval(tv) strbuf_str(strbuf_append_timeval(strbuf_alloca(50), (tv)))
/* Append a representation of a struct timespec (nanosecond resolution).
* @author Andrew Bettison <andrew@servalproject.com>
*/
struct timespec;
strbuf strbuf_append_timespec(strbuf sb, const struct timespec *tv);
#define alloca_timespec(tv) strbuf_str(strbuf_append_timespec(strbuf_alloca(50), (tv)))
#define alloca_timespec(tv) strbuf_str(strbuf_append_timespec(strbuf_alloca(55), (tv)))
/* Append a representation of a struct file_meta.
* @author Andrew Bettison <andrew@servalproject.com>