utime(2)

๐Ÿ’– utime(2) โ€” the "bestie, let me touch up your timestamps" page ๐Ÿ’…

okay so pookie, you know how every file has lil timestamps attached to it? this is the manual page for utime and utimes, two system calls from the System Calls Manual section 2, and they're literally just "change when this file was last read and last edited." iconic behaviour fr fr. ๐Ÿฆ‹


๐ŸŒธ NAME ๐ŸŒธ

utime, utimes โ€” change file last access and modification times


๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library โ€” that's libc, -lc. the og bestie that's always there for you. ๐Ÿซถ


โœจ SYNOPSIS โœจ

no cap, this is the whole shape of it:

#include <utime.h>

int utime(const char *path,
          const struct utimbuf *_Nullable times);

#include <sys/time.h>

int utimes(const char *path,
           const struct timeval times[_Nullable 2]);

yes bestie there are two of them and yes they want different headers, we don't make the rules ๐Ÿ’€


๐Ÿ’œ DESCRIPTION ๐Ÿ’œ

Note: modern applications may prefer to use the interfaces described in utimensat(2). like, that's the new main character. but utime is still here, still serving.

The utime() system call changes the access and modification times of the inode specified by path to the actime and modtime fields of times respectively. and here's the bit that trips people up: the status change time (ctime) gets set to the current time, even if the other time stamps don't actually change. so it's not a quiet little stealth edit, the universe notices. ๐Ÿ‘€

If times is NULL, then the access and modification times of the file are set to the current time. bloop. done. ๐Ÿ•

So when is changing timestamps even permitted? strict permission check, vibe check, whatever you wanna call it. you're allowed when:

  • the process has appropriate privileges,
  • or the effective user ID equals the user ID of the file,
  • or times is NULL and the process has write permission for the file.

That's the whole guest list. no plus-ones. ๐Ÿ™ˆ

The utimbuf structure is:

struct utimbuf {
    time_t actime;       /* access time */
    time_t modtime;      /* modification time */
};

The utime() system call allows specification of timestamps with a resolution of 1 second. seconds only, bestie. it's giving sundial energy. ๐Ÿ˜ญ

The utimes() system call is similar, but the times argument refers to an array rather than a structure. The elements of this array are timeval structures, which allow a precision of 1 microsecond for specifying timestamps. glow-up from seconds to microseconds, we love to see it. โœจ

The timeval structure is:

struct timeval {
    long tv_sec;        /* seconds */
    long tv_usec;       /* microseconds */
};

times[0] specifies the new access time, and times[1] specifies the new modification time. first slot = read, second slot = write, keep the order straight bestie ๐Ÿ“

If times is NULL, then analogously to utime(), the access and modification times of the file are set to the current time.


๐ŸŽ€ RETURN VALUE ๐ŸŽ€

On success, zero is returned. slay, no notes. ๐Ÿ’…

On error, -1 is returned, and errno is set to indicate the error. so if you see the -1, go read errno, it's literally the receipts. ๐Ÿ”


๐Ÿ’€ ERRORS ๐Ÿ’€

okay here's the whole drama list. every single one, no skips:

  • EACCES โ€” Search permission is denied for one of the directories in the path prefix of path (see also path_resolution(7)). you can't even walk there. blocked at the door. ๐Ÿšช
  • EACCES โ€” times is NULL, the caller's effective user ID does not match the owner of the file, the caller does not have write access to the file, and the caller is not privileged (Linux: does not have either the CAP_DAC_OVERRIDE or the CAP_FOWNER capability). yeah it's EACCES twice, they're different crimes bestie, both valid. ๐Ÿ˜ค
  • EFAULT โ€” path points to an invalid address. that pointer is not pointing at anything real, it's living in a fantasy. ๐ŸŒซ๏ธ
  • ENOENT โ€” path does not exist. girl where. there's nothing there. ๐Ÿซ 
  • EPERM โ€” times is not NULL, the caller's effective UID does not match the owner of the file, and the caller is not privileged (Linux: does not have the CAP_FOWNER capability). nope, not your file, not your timestamps. ๐Ÿ”’
  • EROFS โ€” path resides on a read-only filesystem. the filesystem said "no take-backs" and honestly it meant it. โ„๏ธ

๐ŸŒˆ STANDARDS ๐ŸŒˆ

  • utime() None.
  • utimes() POSIX.1-2024.

one of them got into the standard and the other one is just... vibing historically. ๐Ÿ’€


๐Ÿ“œ HISTORY ๐Ÿ“œ

  • utime() SVr4, POSIX.1-2001. Obsoleted in POSIX.1-2008. Removed in POSIX.1-2024. she's retired, she served her time (pun intended), let her rest. ๐Ÿ˜ญ
  • utimes() 4.3BSD, POSIX.1-2001.

๐Ÿฆ‹ NOTES ๐Ÿฆ‹

Linux does not allow changing the timestamps on an immutable file, or setting the timestamps to something other than the current time on an append-only file. so if the file's vibe is locked down, the vibes stay locked down. ๐Ÿ”


๐Ÿ‘‘ SEE ALSO ๐Ÿ‘‘

chattr(1), touch(1), futimesat(2), stat(2), utimensat(2), futimens(3), futimes(3), inode(7)

iykyk, go read utimensat(2) if you want the modern one. ๐Ÿ’œ


and that's the page bestie!! this lil hyperpop masterpiece came to you straight from Linux man-pages 6.20, dated 2026-02-08 โ€” so yes, fresh, current, and still absolutely serving utime(2). mwah, go change some timestamps responsibly ๐Ÿซถ๐Ÿ’–โœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms