Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcoshell/cosync.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1990-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* sync all outstanding file operations for file opened on fd
26
* if file==0 then fd used
27
* if fd<0 then file used
28
* if mode<0 then fd not created
29
*
30
* NOTE: this is an unfortunate NFS workaround that should be done by fsync()
31
*/
32
33
#include "colib.h"
34
35
#include <ls.h>
36
37
#include "FEATURE/nfsd"
38
39
int
40
cosync(Coshell_t* co, const char* file, int fd, int mode)
41
{
42
#if defined(_cmd_nfsd)
43
if (!co || (co->flags & CO_SERVER))
44
{
45
char tmp[PATH_MAX];
46
47
if (file && *file)
48
{
49
register const char* s;
50
register char* t;
51
register char* b;
52
int td;
53
54
/*
55
* writing to a dir apparently flushes the
56
* attribute cache for all entries in the dir
57
*/
58
59
s = file;
60
b = t = tmp;
61
while (t < &tmp[sizeof(tmp) - 1])
62
{
63
if (!(*t = *s++)) break;
64
if (*t++ == '/') b = t;
65
}
66
s = "..nfs..botch..";
67
t = b;
68
while (t < &tmp[sizeof(tmp) - 1] && (*t++ = *s++));
69
*t = 0;
70
if ((td = open(tmp, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, 0)) >= 0)
71
close(td);
72
unlink(tmp);
73
if (fd >= 0 && mode >= 0)
74
{
75
if ((td = open(file, mode|O_cloexec)) < 0)
76
return(-1);
77
close(fd);
78
dup2(td, fd);
79
close(td);
80
}
81
}
82
#if defined(F_SETLK)
83
else
84
{
85
int clean = 0;
86
struct flock lock;
87
88
if (fd < 0)
89
{
90
if (!file || mode < 0 || (fd = open(file, O_RDONLY|O_cloexec)) < 0) return(-1);
91
clean = 1;
92
}
93
94
/*
95
* this sets the VNOCACHE flag across NFS
96
*/
97
98
lock.l_type = F_RDLCK;
99
lock.l_whence = 0;
100
lock.l_start = 0;
101
lock.l_len = 1;
102
if (!fcntl(fd, F_SETLK, &lock))
103
{
104
lock.l_type = F_UNLCK;
105
fcntl(fd, F_SETLK, &lock);
106
}
107
if (clean) close(fd);
108
109
/*
110
* 4.1 has a bug that lets VNOCACHE linger after unlock
111
* VNOCACHE inhibits mapping which kills exec
112
* the double rename flushes the incore vnode (and VNOCACHE)
113
*
114
* this kind of stuff doesn't happen with *real* file systems
115
*/
116
117
if (file && *file)
118
{
119
strcpy(tmp, file);
120
fd = strlen(tmp) - 1;
121
tmp[fd] = (tmp[fd] == '*') ? '?' : '*';
122
if (!rename(file, tmp)) rename(tmp, file);
123
}
124
}
125
#endif
126
}
127
#endif
128
return(0);
129
}
130
131