@@ -1101,8 +1101,8 @@ abstract static class UtimeNode extends PythonBuiltinNode {
1101
1101
@ Specialization
1102
1102
Object utime (String path , PNone times , PNone ns , PNone dir_fd , PNone follow_symlinks ) {
1103
1103
long time = ((Double ) TimeModuleBuiltins .timeSeconds ()).longValue ();
1104
- setMtime (path , time );
1105
- setAtime (path , time );
1104
+ setMtime (getFile ( path , true ) , time );
1105
+ setAtime (getFile ( path , true ) , time );
1106
1106
return PNone .NONE ;
1107
1107
}
1108
1108
@@ -1111,8 +1111,8 @@ Object utime(String path, PNone times, PNone ns, PNone dir_fd, PNone follow_syml
1111
1111
Object utime (String path , PTuple times , PNone ns , PNone dir_fd , PNone follow_symlinks ) {
1112
1112
long atime = getTime (times , 0 , "times" );
1113
1113
long mtime = getTime (times , 1 , "times" );
1114
- setMtime (path , mtime );
1115
- setAtime (path , atime );
1114
+ setMtime (getFile ( path , true ) , mtime );
1115
+ setAtime (getFile ( path , true ) , atime );
1116
1116
return PNone .NONE ;
1117
1117
}
1118
1118
@@ -1121,8 +1121,18 @@ Object utime(String path, PTuple times, PNone ns, PNone dir_fd, PNone follow_sym
1121
1121
Object utime (String path , PNone times , PTuple ns , PNone dir_fd , PNone follow_symlinks ) {
1122
1122
long atime = getTime (ns , 0 , "ns" ) / 1000 ;
1123
1123
long mtime = getTime (ns , 1 , "ns" ) / 1000 ;
1124
- setMtime (path , mtime );
1125
- setAtime (path , atime );
1124
+ setMtime (getFile (path , true ), mtime );
1125
+ setAtime (getFile (path , true ), atime );
1126
+ return PNone .NONE ;
1127
+ }
1128
+
1129
+ @ SuppressWarnings ("unused" )
1130
+ @ Specialization
1131
+ Object utime (String path , PNone times , PTuple ns , PNone dir_fd , boolean follow_symlinks ) {
1132
+ long atime = getTime (ns , 0 , "ns" ) / 1000 ;
1133
+ long mtime = getTime (ns , 1 , "ns" ) / 1000 ;
1134
+ setMtime (getFile (path , true ), mtime );
1135
+ setAtime (getFile (path , true ), atime );
1126
1136
return PNone .NONE ;
1127
1137
}
1128
1138
@@ -1183,18 +1193,36 @@ private PException tupleError(String argname) {
1183
1193
return raise (TypeError , "utime: '%s' must be either a tuple of two ints or None" , argname );
1184
1194
}
1185
1195
1186
- private void setMtime (String path , long mtime ) {
1196
+ private void setMtime (TruffleFile truffleFile , long mtime ) {
1187
1197
try {
1188
- getContext ().getEnv ().getTruffleFile (path ).setLastModifiedTime (FileTime .from (mtime , TimeUnit .SECONDS ));
1189
- } catch (IOException e ) {
1198
+ truffleFile .setLastModifiedTime (FileTime .from (mtime , TimeUnit .SECONDS ));
1199
+ } catch (IOException | SecurityException e ) {
1200
+ throw raise ();
1190
1201
}
1191
1202
}
1192
1203
1193
- private void setAtime (String path , long mtime ) {
1204
+ private void setAtime (TruffleFile truffleFile , long mtime ) {
1194
1205
try {
1195
- getContext ().getEnv ().getTruffleFile (path ).setLastAccessTime (FileTime .from (mtime , TimeUnit .SECONDS ));
1196
- } catch (IOException e ) {
1206
+ truffleFile .setLastAccessTime (FileTime .from (mtime , TimeUnit .SECONDS ));
1207
+ } catch (IOException | SecurityException e ) {
1208
+ throw raise ();
1209
+ }
1210
+ }
1211
+
1212
+ private TruffleFile getFile (String path , boolean followSymlinks ) {
1213
+ TruffleFile truffleFile = getContext ().getEnv ().getTruffleFile (path );
1214
+ if (!followSymlinks ) {
1215
+ try {
1216
+ truffleFile = truffleFile .getCanonicalFile (LinkOption .NOFOLLOW_LINKS );
1217
+ } catch (IOException | SecurityException e ) {
1218
+ throw raise ();
1219
+ }
1197
1220
}
1221
+ return truffleFile ;
1222
+ }
1223
+
1224
+ private PException raise () {
1225
+ throw raise (ValueError , "Operation not allowed" );
1198
1226
}
1199
1227
1200
1228
private int getLength (PTuple times ) {
0 commit comments