summarylogtreecommitdiffstats
path: root/0007-Revert-util-drop-old-utimensat-compat-code.patch
blob: 04fd236ed420e2b56583368f2de5fa9120e173a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Frajo Haider <f_haider@gmx.at>
Date: Wed, 29 Jan 2020 11:21:54 +0000
Subject: [PATCH] Revert "util: drop old utimensat() compat code"

This reverts commit fcdcf1eed2fd26bfe836080755ba4322d3c1f2cc.

Conflicts:
	slirp
---
 configure                 | 52 +++++++++++++++++++++++++++++++++++++++
 include/sysemu/os-posix.h | 11 +++++++++
 util/oslib-posix.c        | 47 +++++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+)

diff --git a/configure b/configure
index 7c08c18358becf49779c876b0f3d17329df053c6..7a45cb3f87367a1d7d5149e143fe54b9787b6de0 100755
--- a/configure
+++ b/configure
@@ -2312,6 +2312,55 @@ EOF
   fi
 fi
 
+# check if utimensat and futimens are supported
+utimens=no
+cat > $TMPC << EOF
+#define _ATFILE_SOURCE
+#include <stddef.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+int main(void)
+{
+    utimensat(AT_FDCWD, "foo", NULL, 0);
+    futimens(0, NULL);
+    return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  utimens=yes
+fi
+
+##########################################
+# libnuma probe
+
+if test "$numa" != "no" ; then
+  cat > $TMPC << EOF
+#include <numa.h>
+int main(void) { return numa_available(); }
+EOF
+
+  if compile_prog "" "-lnuma" ; then
+    numa=yes
+    numa_libs="-lnuma"
+  else
+    if test "$numa" = "yes" ; then
+      feature_not_found "numa" "install numactl devel"
+    fi
+    numa=no
+  fi
+fi
+
+malloc=system
+if test "$tcmalloc" = "yes" && test "$jemalloc" = "yes" ; then
+    echo "ERROR: tcmalloc && jemalloc can't be used at the same time"
+    exit 1
+elif test "$tcmalloc" = "yes" ; then
+    malloc=tcmalloc
+elif test "$jemalloc" = "yes" ; then
+    malloc=jemalloc
+fi
+
 # check for usbfs
 have_usbfs=no
 if test "$linux_user" = "yes"; then
@@ -2829,6 +2878,9 @@ fi
 if test "$module_upgrades" = "yes"; then
   echo "CONFIG_MODULE_UPGRADES=y" >> $config_host_mak
 fi
+if test "$utimens" = "yes" ; then
+  echo "CONFIG_UTIMENSAT=y" >> $config_host_mak
+fi
 if test "$have_usbfs" = "yes" ; then
   echo "CONFIG_USBFS=y" >> $config_host_mak
 fi
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index dd64fb401dfb8b7ffcaf6013ef3316a74b4d3c0d..f99c812f6c456fc40ed4bdaaac0b5ffc93642b86 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -56,6 +56,17 @@ typedef struct timeval qemu_timeval;
 #define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
 
 int os_set_daemonize(bool d);
+#ifndef CONFIG_UTIMENSAT
+#ifndef UTIME_NOW
+# define UTIME_NOW     ((1l << 30) - 1l)
+#endif
+#ifndef UTIME_OMIT
+# define UTIME_OMIT    ((1l << 30) - 2l)
+#endif
+#endif
+typedef struct timespec qemu_timespec;
+int qemu_utimens(const char *path, const qemu_timespec *times);
+
 bool is_daemonized(void);
 
 /**
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 2ebfb7505787ec342773b12999ea85fd13c81040..6ff0d50d8c1d6bb95a31201a776c095b7f52797a 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -298,6 +298,53 @@ int qemu_pipe(int pipefd[2])
     return ret;
 }
 
+int qemu_utimens(const char *path, const struct timespec *times)
+{
+    struct timeval tv[2], tv_now;
+    struct stat st;
+    int i;
+#ifdef CONFIG_UTIMENSAT
+    int ret;
+
+    ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW);
+    if (ret != -1 || errno != ENOSYS) {
+        return ret;
+    }
+#endif
+    /* Fallback: use utimes() instead of utimensat() */
+
+    /* happy if special cases */
+    if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) {
+        return 0;
+    }
+    if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) {
+        return utimes(path, NULL);
+    }
+
+    /* prepare for hard cases */
+    if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) {
+        gettimeofday(&tv_now, NULL);
+    }
+    if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) {
+        stat(path, &st);
+    }
+
+    for (i = 0; i < 2; i++) {
+        if (times[i].tv_nsec == UTIME_NOW) {
+            tv[i].tv_sec = tv_now.tv_sec;
+            tv[i].tv_usec = tv_now.tv_usec;
+        } else if (times[i].tv_nsec == UTIME_OMIT) {
+            tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime;
+            tv[i].tv_usec = 0;
+        } else {
+            tv[i].tv_sec = times[i].tv_sec;
+            tv[i].tv_usec = times[i].tv_nsec / 1000;
+        }
+    }
+
+    return utimes(path, &tv[0]);
+}
+
 char *
 qemu_get_local_state_pathname(const char *relative_pathname)
 {