1 /*******************************************************************************
2 this code is protected by the GNU affero GPLv3
3 author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
4 *******************************************************************************/
5 #include <ulinux/compiler_types.h>
6 #include <ulinux/types.h>
7 #include <ulinux/error.h>
9 #include <ulinux/file.h>
10 #include <ulinux/dirent.h>
11 #include <ulinux/utils/mem.h>
12 #include <ulinux/utils/ascii/string/string.h>
13 #include <ulinux/sysc.h>
16 #include "ulinux_namespace.h"
19 #define DIRENTS_BUF_SZ 8192
21 static u8
is_current(u8
*n
)
23 if(n
[0]=='.'&&n
[1]==0) return 1;
27 static u8
is_parent(u8
*n
)
29 if(n
[0]=='.'&&n
[1]=='.'&&n
[2]==0) return 1;
33 static u8
is_newroot(u8
*n
)
35 #define NEWROOT (u8*)"newroot"
36 return strncmp(n
,NEWROOT
,sizeof(NEWROOT
)-1)?0:1;
39 static void unlink(i parent_fd
,u8
*n
,i flgs
)
41 l r
=unlinkat(parent_fd
,n
,flgs
);
43 OUT("ERROR(%ld):unable to remove dir entry:%s\n",r
,n
);
48 static void dir_del(i parent_fd
);
49 static void dirent_del(i parent_fd
,struct dirent64
*d
)
52 if(!is_current(d
->name
)&&!is_parent(d
->name
)){
55 dir_fd
=(i
)openat(parent_fd
,d
->name
,ULINUX_O_RDONLY
|ULINUX_O_NONBLOCK
);
56 if(dir_fd
!=-EINTR
) break;
59 OUT("ERROR(%d):unable to open subdir:%s\n",dir_fd
,d
->name
);
69 OUT("ERROR(%ld):unable to close dir fd\n",r
);
73 unlink(parent_fd
,d
->name
,AT_REMOVEDIR
);
75 }else unlink(parent_fd
,d
->name
,0);
78 static void dir_del(i parent_fd
)
80 u8 dirents
[DIRENTS_BUF_SZ
];
83 l r
=getdents64(parent_fd
,dirents
,DIRENTS_BUF_SZ
);
85 OUT("ERROR(%ld):getdents error\n",r
);
96 d
=(struct dirent64
*)(dirents
+idx
);
97 dirent_del(parent_fd
,d
);
103 void ramfs_cleanup(void)
105 OUT(PRE
"cleaning ramfs...");
108 root_fd
=(i
)open("/",ULINUX_O_RDONLY
|ULINUX_O_NONBLOCK
);
109 if(root_fd
!=-EINTR
) break;
112 OUT("ERROR(%d):unable to open root dir\n",root_fd
);
116 u8 dirents
[DIRENTS_BUF_SZ
];
119 l r
=getdents64(root_fd
,dirents
,DIRENTS_BUF_SZ
);
121 OUT("ERROR(%ld):getdents error\n",r
);
125 if(!r
) break;/*empty*/
133 d
=(struct dirent64
*)(dirents
+idx
);
134 if(!is_newroot(d
->name
)) dirent_del(root_fd
,d
);
144 OUT("ERROR(%ld):unable to root dir fd\n",r
);