MCPcopy Create free account
hub / github.com/F-Stack/f-stack / vflopenat

Function vflopenat

tools/libutil/flopen.c:50–123  ·  view source on GitHub ↗

* Reliably open and lock a file. * * Please do not modify this code without first reading the revision history * and discussing your changes with . Don't be fooled by the * code's apparent simplicity; there would be no need for this function if it * was easy to get right. */

Source from the content-addressed store, hash-verified

48 * was easy to get right.
49 */
50static int
51vflopenat(int dirfd, const char *path, int flags, va_list ap)
52{
53 int fd, operation, serrno, trunc;
54 struct stat sb, fsb;
55 mode_t mode;
56
57#ifdef O_EXLOCK
58 flags &= ~O_EXLOCK;
59#endif
60
61 mode = 0;
62 if (flags & O_CREAT) {
63 mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */
64 }
65
66 operation = LOCK_EX;
67 if (flags & O_NONBLOCK)
68 operation |= LOCK_NB;
69
70 trunc = (flags & O_TRUNC);
71 flags &= ~O_TRUNC;
72
73 for (;;) {
74 if ((fd = openat(dirfd, path, flags, mode)) == -1)
75 /* non-existent or no access */
76 return (-1);
77 if (flock(fd, operation) == -1) {
78 /* unsupported or interrupted */
79 serrno = errno;
80 (void)close(fd);
81 errno = serrno;
82 return (-1);
83 }
84 if (fstatat(dirfd, path, &sb, 0) == -1) {
85 /* disappeared from under our feet */
86 (void)close(fd);
87 continue;
88 }
89 if (fstat(fd, &fsb) == -1) {
90 /* can't happen [tm] */
91 serrno = errno;
92 (void)close(fd);
93 errno = serrno;
94 return (-1);
95 }
96 if (sb.st_dev != fsb.st_dev ||
97 sb.st_ino != fsb.st_ino) {
98 /* changed under our feet */
99 (void)close(fd);
100 continue;
101 }
102 if (trunc && ftruncate(fd, 0) != 0) {
103 /* can't happen [tm] */
104 serrno = errno;
105 (void)close(fd);
106 errno = serrno;
107 return (-1);

Callers 2

flopenFunction · 0.85
flopenatFunction · 0.85

Calls 3

flockClass · 0.50
closeFunction · 0.50
fcntlFunction · 0.50

Tested by

no test coverage detected