/***********************************************************************1* *2* This software is part of the ast package *3* Copyright (c) 1990-2012 AT&T Intellectual Property *4* and is licensed under the *5* Eclipse Public License, Version 1.0 *6* by AT&T Intellectual Property *7* *8* A copy of the License is available at *9* http://www.eclipse.org/org/documents/epl-v10.html *10* (with md5 checksum b35adb5213ca9657e911e9befb180842) *11* *12* Information and Software Systems Research *13* AT&T Research *14* Florham Park NJ *15* *16* Glenn Fowler <[email protected]> *17* *18***********************************************************************/19#pragma prototyped20/*21* Glenn Fowler22* AT&T Research23*24* sync all outstanding file operations for file opened on fd25* if file==0 then fd used26* if fd<0 then file used27* if mode<0 then fd not created28*29* NOTE: this is an unfortunate NFS workaround that should be done by fsync()30*/3132#include "colib.h"3334#include <ls.h>3536#include "FEATURE/nfsd"3738int39cosync(Coshell_t* co, const char* file, int fd, int mode)40{41#if defined(_cmd_nfsd)42if (!co || (co->flags & CO_SERVER))43{44char tmp[PATH_MAX];4546if (file && *file)47{48register const char* s;49register char* t;50register char* b;51int td;5253/*54* writing to a dir apparently flushes the55* attribute cache for all entries in the dir56*/5758s = file;59b = t = tmp;60while (t < &tmp[sizeof(tmp) - 1])61{62if (!(*t = *s++)) break;63if (*t++ == '/') b = t;64}65s = "..nfs..botch..";66t = b;67while (t < &tmp[sizeof(tmp) - 1] && (*t++ = *s++));68*t = 0;69if ((td = open(tmp, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, 0)) >= 0)70close(td);71unlink(tmp);72if (fd >= 0 && mode >= 0)73{74if ((td = open(file, mode|O_cloexec)) < 0)75return(-1);76close(fd);77dup2(td, fd);78close(td);79}80}81#if defined(F_SETLK)82else83{84int clean = 0;85struct flock lock;8687if (fd < 0)88{89if (!file || mode < 0 || (fd = open(file, O_RDONLY|O_cloexec)) < 0) return(-1);90clean = 1;91}9293/*94* this sets the VNOCACHE flag across NFS95*/9697lock.l_type = F_RDLCK;98lock.l_whence = 0;99lock.l_start = 0;100lock.l_len = 1;101if (!fcntl(fd, F_SETLK, &lock))102{103lock.l_type = F_UNLCK;104fcntl(fd, F_SETLK, &lock);105}106if (clean) close(fd);107108/*109* 4.1 has a bug that lets VNOCACHE linger after unlock110* VNOCACHE inhibits mapping which kills exec111* the double rename flushes the incore vnode (and VNOCACHE)112*113* this kind of stuff doesn't happen with *real* file systems114*/115116if (file && *file)117{118strcpy(tmp, file);119fd = strlen(tmp) - 1;120tmp[fd] = (tmp[fd] == '*') ? '?' : '*';121if (!rename(file, tmp)) rename(tmp, file);122}123}124#endif125}126#endif127return(0);128}129130131