1 /* syncdir -- emulate synchronous directories
2 Copyright (C) 1998 Bruce Guenter
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 You can reach me at bruce.guenter@qcc.sk.ca
21 #include <sys/types.h>
31 #include <bits/syscall.h>
33 #define SYS_OPEN(FILE,FLAG,MODE) syscall(SYS_open, FILE, FLAG, MODE)
34 #define SYS_CLOSE(FD) syscall(SYS_close, FD)
35 #define SYS_LINK(OLD,NEW) syscall(SYS_link, OLD, NEW)
36 #define SYS_UNLINK(PATH) syscall(SYS_unlink, PATH)
37 #define SYS_RENAME(OLD,NEW) syscall(SYS_rename, OLD, NEW)
38 #define SYS_FSYNC(FD) syscall(SYS_fsync, FD)
40 static int fdirsync(const char* filename
, unsigned length
)
42 char dirname
[length
+1];
43 /* This could also be:
44 * char* dirname = alloca(length+1); */
47 memcpy(dirname
, filename
, length
);
49 if((dirfd
= SYS_OPEN(dirname
,O_RDONLY
,0)) == -1)
51 retval
= (SYS_FSYNC(dirfd
) == -1 && errno
== EIO
) ? -1 : 0;
56 static int fdirsyncfn(const char *filename
)
58 const char *slash
= filename
+strlen(filename
)-1;
60 /* Skip over trailing slashes, which would be ignored by some
62 while(slash
> filename
&& *slash
== '/')
65 /* Skip back to the next slash */
66 while(slash
> filename
&& *slash
!= '/')
69 /* slash now either points to a '/' character, or no slash was found */
71 return fdirsync(filename
,
72 (slash
== filename
) ? 1 : slash
-filename
);
74 return fdirsync(".", 1);
77 int open(const char *file
,int oflag
,mode_t mode
)
79 int fd
= SYS_OPEN(file
, oflag
, mode
);
83 if (fdirsyncfn(file
) == -1) {
90 int link(const char *oldpath
,const char *newpath
)
92 if(SYS_LINK(oldpath
,newpath
) == -1)
94 return fdirsyncfn(newpath
);
97 int unlink(const char *path
)
99 if(SYS_UNLINK(path
) == -1)
101 return fdirsyncfn(path
);
104 int rename(const char *oldpath
,const char *newpath
)
106 if (SYS_RENAME(oldpath
,newpath
) == -1)
108 if (fdirsyncfn(newpath
) == -1)
110 return fdirsyncfn(oldpath
);