touch.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
ad2e68e571352b6759441733df697e075ceed341Robert Savu/***********************************************************************
ad2e68e571352b6759441733df697e075ceed341Robert Savu* *
ad2e68e571352b6759441733df697e075ceed341Robert Savu* This software is part of the ast package *
ad2e68e571352b6759441733df697e075ceed341Robert Savu* Copyright (c) 1989-2012 AT&T Intellectual Property *
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu* and is licensed under the *
ad2e68e571352b6759441733df697e075ceed341Robert Savu* Eclipse Public License, Version 1.0 *
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu* by AT&T Intellectual Property *
ad2e68e571352b6759441733df697e075ceed341Robert Savu* *
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu* A copy of the License is available at *
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu* http://www.eclipse.org/org/documents/epl-v10.html *
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu* *
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu* Information and Software Systems Research *
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu* AT&T Research *
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu* Florham Park NJ *
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu* *
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu* Glenn Fowler <gsf@research.att.com> *
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu* David Korn <dgk@research.att.com> *
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu* Eduardo Krell <ekrell@adexus.cl> *
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu* *
ad2e68e571352b6759441733df697e075ceed341Robert Savu***********************************************************************/
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu#pragma prototyped
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu/*
d0adfa619575f357a79e0075cab46f68201379d2Robert Savu * NOTE: obsolete touch() for 3d private use
ad2e68e571352b6759441733df697e075ceed341Robert Savu * -last touch() handles subsecond times
ad2e68e571352b6759441733df697e075ceed341Robert Savu * via tvtouch()
ad2e68e571352b6759441733df697e075ceed341Robert Savu */
ad2e68e571352b6759441733df697e075ceed341Robert Savu
ad2e68e571352b6759441733df697e075ceed341Robert Savu/*
ad2e68e571352b6759441733df697e075ceed341Robert Savu * Glenn Fowler
ad2e68e571352b6759441733df697e075ceed341Robert Savu * AT&T Research
ad2e68e571352b6759441733df697e075ceed341Robert Savu *
ad2e68e571352b6759441733df697e075ceed341Robert Savu * touch file access and modify times of file
ad2e68e571352b6759441733df697e075ceed341Robert Savu * if force>0 then file will be created if it doesn't exist
ad2e68e571352b6759441733df697e075ceed341Robert Savu * if force<0 then times are taken verbatim
ad2e68e571352b6759441733df697e075ceed341Robert Savu * times have one second granularity
ad2e68e571352b6759441733df697e075ceed341Robert Savu *
ad2e68e571352b6759441733df697e075ceed341Robert Savu * (time_t)(-1) retain old time
ad2e68e571352b6759441733df697e075ceed341Robert Savu * 0 use current time
ad2e68e571352b6759441733df697e075ceed341Robert Savu */
ad2e68e571352b6759441733df697e075ceed341Robert Savu
ad2e68e571352b6759441733df697e075ceed341Robert Savu#if defined(__STDPP__directive) && defined(__STDPP__hide)
ad2e68e571352b6759441733df697e075ceed341Robert Savu__STDPP__directive pragma pp:hide utime
ad2e68e571352b6759441733df697e075ceed341Robert Savu#else
ad2e68e571352b6759441733df697e075ceed341Robert Savu#define utime ______utime
ad2e68e571352b6759441733df697e075ceed341Robert Savu#endif
ad2e68e571352b6759441733df697e075ceed341Robert Savu
ad2e68e571352b6759441733df697e075ceed341Robert Savu#include <ast.h>
ad2e68e571352b6759441733df697e075ceed341Robert Savu#include <ls.h>
ad2e68e571352b6759441733df697e075ceed341Robert Savu#include <times.h>
ad2e68e571352b6759441733df697e075ceed341Robert Savu#include <error.h>
ad2e68e571352b6759441733df697e075ceed341Robert Savu
ad2e68e571352b6759441733df697e075ceed341Robert Savu#if _hdr_utime && _lib_utime
ad2e68e571352b6759441733df697e075ceed341Robert Savu#include <utime.h>
ad2e68e571352b6759441733df697e075ceed341Robert Savu#endif
ad2e68e571352b6759441733df697e075ceed341Robert Savu
ad2e68e571352b6759441733df697e075ceed341Robert Savu#if defined(__STDPP__directive) && defined(__STDPP__hide)
ad2e68e571352b6759441733df697e075ceed341Robert Savu__STDPP__directive pragma pp:nohide utime
ad2e68e571352b6759441733df697e075ceed341Robert Savu#else
ad2e68e571352b6759441733df697e075ceed341Robert Savu#undef utime
ad2e68e571352b6759441733df697e075ceed341Robert Savu#endif
ad2e68e571352b6759441733df697e075ceed341Robert Savu
ad2e68e571352b6759441733df697e075ceed341Robert Savu#if _lib_utime
ad2e68e571352b6759441733df697e075ceed341Robert Savu#if _hdr_utime
ad2e68e571352b6759441733df697e075ceed341Robert Savuextern int utime(const char*, const struct utimbuf*);
ad2e68e571352b6759441733df697e075ceed341Robert Savu#else
e09066e7b76cea97557974b825bb057455b24ab0Robert Savuextern int utime(const char*, const time_t*);
e09066e7b76cea97557974b825bb057455b24ab0Robert Savu#endif
ad2e68e571352b6759441733df697e075ceed341Robert Savu#endif
ad2e68e571352b6759441733df697e075ceed341Robert Savu
ad2e68e571352b6759441733df697e075ceed341Robert Savuint
ad2e68e571352b6759441733df697e075ceed341Robert Savutouch(const char* file, time_t atime, time_t mtime, int force)
ad2e68e571352b6759441733df697e075ceed341Robert Savu{
ad2e68e571352b6759441733df697e075ceed341Robert Savu int n;
ad2e68e571352b6759441733df697e075ceed341Robert Savu int fd;
ad2e68e571352b6759441733df697e075ceed341Robert Savu int oerrno = errno;
ad2e68e571352b6759441733df697e075ceed341Robert Savu int mode;
ad2e68e571352b6759441733df697e075ceed341Robert Savu#if _lib_utime
ad2e68e571352b6759441733df697e075ceed341Robert Savu time_t now;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu struct stat st;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#if _hdr_utime
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu struct utimbuf ut;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#else
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu time_t ut[2];
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#endif
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (force >= 0)
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu {
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu if (atime == (time_t)(-1) || mtime == (time_t)(-1))
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu {
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu if (stat(file, &st)) st.st_atime = st.st_mtime = 0;
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu if (atime == (time_t)(-1)) atime = st.st_atime;
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu if (mtime == (time_t)(-1)) mtime = st.st_mtime;
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu }
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (!atime || !mtime)
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#if _hdr_utime && _lib_utime_now
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (atime || mtime)
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#endif
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu {
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu time(&now);
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (!atime) atime = now;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (!mtime) mtime = now;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu }
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu }
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#if _hdr_utime
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu ut.actime = atime;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu ut.modtime = mtime;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#if _lib_utime_now
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu n = utime(file, (force < 0 || atime || mtime) ? &ut : (struct utimbuf*)0);
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#else
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu n = utime(file, &ut);
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#endif
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#else
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu ut[0] = atime;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu ut[1] = mtime;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu n = utime(file, ut);
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#endif
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (n)
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#else
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (mtime)
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu {
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu /*
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu * NOTE: the emulation allows atime to change
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu * for mtime only requests
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu */
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu errno = EINVAL;
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu return(-1);
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu }
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#endif
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu {
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#if _lib_utime
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (errno == ENOENT || errno == EPERM)
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#else
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (access(file, F_OK))
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu#endif
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu {
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu if (!force) return(-1);
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu umask(mode = umask(0));
a9c461443a740732a62d58c1c465b88cba3c606bRobert Savu mode = (~mode) & (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu if ((fd = open(file, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, mode)) < 0) return(-1);
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu close(fd);
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu errno = oerrno;
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#if _lib_utime
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#if _hdr_utime
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#if _lib_utime_now
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu return((force < 0 || atime || mtime) ? utime(file, &ut) : 0);
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#else
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu return(0);
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#endif
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#else
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu return((atime != now || mtime != now) ? utime(file, ut) : 0);
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#endif
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#else
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu return(0);
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#endif
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu }
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#if !_hdr_utime || !_lib_utime
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#if _lib_utime
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu if (atime == now && mtime == now && (fd = open(file, O_RDWR|O_cloexec)) >= 0)
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#else
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu if ((fd = open(file, O_RDWR|O_cloexec)) >= 0)
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu#endif
37dd4c99dbe470cce3fe0d89a011186f080e8910Robert Savu {
char c;
if (read(fd, &c, 1) == 1)
{
if (lseek(fd, 0L, 0) == 0L && write(fd, &c, 1) == 1)
{
errno = oerrno;
n = 0;
}
close(fd);
}
else
{
close(fd);
umask(mode = umask(0));
mode = (~mode) & (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
if ((fd = open(file, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, mode)) >= 0)
{
close(fd);
errno = oerrno;
n = 0;
}
}
}
#endif
}
return(n);
}