This was copied fro u9fs, with the issue filed in: https://github.com/golang/go/issues/39238
Unified · Split
| @@ -397,6 +397,13 @@ fswstat(Chan *c, uchar *buf, int n) · 396 unmodified lines | |||
| 397 | char strs[NAME_MAX*3]; | 397 | char strs[NAME_MAX*3]; |
| 398 | Ufsinfo *uif; | 398 | Ufsinfo *uif; |
| 399 | 399 | ||
| 400 | /* | ||
| 401 | * wstat is supposed to be atomic. | ||
| 402 | * we check all the things we can before trying anything. | ||
| 403 | * still, if we are told to truncate a file and rename it and only | ||
| 404 | * one works, we're screwed. in such cases we leave things | ||
| 405 | * half broken and return an error. it's hardly perfect. | ||
| 406 | */ | ||
| 400 | if(convM2D(buf, n, &d, strs) != n) | 407 | if(convM2D(buf, n, &d, strs) != n) |
| 401 | error(Ebadstat); | 408 | error(Ebadstat); |
| 402 | 409 | ||
| @@ -404,6 +411,13 @@ fswstat(Chan *c, uchar *buf, int n) · 1 unmodified line | |||
| 404 | if(stat(uif->path, &stbuf) < 0) | 411 | if(stat(uif->path, &stbuf) < 0) |
| 405 | error(strerror(errno)); | 412 | error(strerror(errno)); |
| 406 | 413 | ||
| 414 | /* | ||
| 415 | * try things in increasing order of harm to the file. | ||
| 416 | * mtime should come after truncate so that if you | ||
| 417 | * do both the mtime actually takes effect, but i'd rather | ||
| 418 | * leave truncate until last. | ||
| 419 | * (see above comment about atomicity). | ||
| 420 | */ | ||
| 407 | if(~d.mode != 0 && (int)(d.mode&0777) != (int)(stbuf.st_mode&0777)) { | 421 | if(~d.mode != 0 && (int)(d.mode&0777) != (int)(stbuf.st_mode&0777)) { |
| 408 | if(chmod(uif->path, d.mode&0777) < 0) | 422 | if(chmod(uif->path, d.mode&0777) < 0) |
| 409 | error(strerror(errno)); | 423 | error(strerror(errno)); |
| @@ -450,6 +464,10 @@ fswstat(Chan *c, uchar *buf, int n) · 40 unmodified lines | |||
| 450 | uif->gid = p->id; | 464 | uif->gid = p->id; |
| 451 | } | 465 | } |
| 452 | */ | 466 | */ |
| 467 | |||
| 468 | if((uvlong)d.length != (uvlong)~0 && truncate(uif->path, d.length) < 0) | ||
| 469 | error(strerror(errno)); | ||
| 470 | |||
| 453 | return n; | 471 | return n; |
| 454 | } | 472 | } |
| 455 | 473 | ||