@@ -62,14 +62,17 @@ OF SUCH DAMAGE.
62
62
63
63
64
64
65
+ #ifndef _GNU_SOURCE
66
+ #define _GNU_SOURCE /* O_DIRECT */
67
+ #endif
68
+
65
69
#include <errno.h>
66
70
#include <fcntl.h>
67
71
#include <stdio.h>
68
72
#include <string.h>
69
73
#include <sys/stat.h>
70
74
#include <unistd.h>
71
75
72
- #include "dbutils.h"
73
76
#include "external.h"
74
77
#include "template_db.h"
75
78
#include "utils.h"
@@ -78,7 +81,7 @@ OF SUCH DAMAGE.
78
81
int init_template_db (struct template_db * tdb ) {
79
82
/* Not checking argument */
80
83
81
- tdb -> fd = -1 ;
84
+ tdb -> buf = NULL ;
82
85
tdb -> size = -1 ;
83
86
return 0 ;
84
87
}
@@ -112,75 +115,60 @@ int create_dbdb_tables(const char *name, sqlite3 *db, void *args) {
112
115
int close_template_db (struct template_db * tdb ) {
113
116
/* Not checking argument */
114
117
115
- close (tdb -> fd );
118
+ sqlite3_free (tdb -> buf );
116
119
return init_template_db (tdb );
117
120
}
118
121
119
122
/* create the database file to copy from */
120
- int create_template (struct template_db * tdb , int (* create_tables )(const char * , sqlite3 * , void * ),
121
- const char * name ) {
122
- if (!tdb || (tdb -> fd != -1 ) ||
123
- !create_tables || !name ) {
123
+ int create_template (struct template_db * tdb , int (* create_tables )(const char * , sqlite3 * , void * )) {
124
+ if (!tdb || tdb -> buf ||
125
+ !create_tables ) {
124
126
return -1 ;
125
127
}
126
128
127
- sqlite3 * db = opendb (name , SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , 0 , 0 , create_tables , NULL );
128
-
129
- /*
130
- * open before sqlite3_close to prevent potential race
131
- * condition where file is deleted before being reopened
132
- */
133
- tdb -> fd = open (name , O_RDONLY );
134
-
135
- sqlite3_close (db );
136
-
137
- /* no need for the file to remain on the filesystem */
138
- remove (name );
139
-
140
- if (tdb -> fd == -1 ) {
141
- fprintf (stderr , "Could not open template file '%s'\n" , name );
142
- return -1 ;
143
- }
144
-
145
- tdb -> size = lseek (tdb -> fd , 0 , SEEK_END );
146
- return !tdb -> size ;
129
+ sqlite3 * db = opendb (SQLITE_MEMORY , SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , 0 , 0 , create_tables , NULL );
130
+ tdb -> buf = sqlite3_serialize (db , "main" , & tdb -> size , 0 );
131
+ closedb (db );
132
+ return !tdb -> buf ;
147
133
}
148
134
149
135
/* create the initial xattrs database file to copy from */
150
136
int create_xattrs_template (struct template_db * tdb ) {
151
- static const char name [] = "xattrs_tmp.db" ;
152
- return create_template (tdb , create_xattr_tables , name );
137
+ return create_template (tdb , create_xattr_tables );
153
138
}
154
139
155
140
/* create the initial main database file to copy from */
156
141
int create_dbdb_template (struct template_db * tdb ) {
157
- static const char name [] = "tmp.db" ;
158
- return create_template (tdb , create_dbdb_tables , name );
142
+ return create_template (tdb , create_dbdb_tables );
159
143
}
160
144
161
145
/* copy the template file instead of creating a new database and new tables for each work item */
162
146
/* the ownership and permissions are set too */
163
147
int copy_template (struct template_db * tdb , const char * dst , uid_t uid , gid_t gid ) {
164
148
/* Not checking arguments */
165
149
166
- int err = 0 ;
167
- const int src_db = dup (tdb -> fd );
168
- err = err ?err :errno ;
169
- const int dst_db = open (dst , O_WRONLY | O_CREAT , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH );
170
- err = err ?err :errno ;
171
- const ssize_t sf = copyfd (src_db , 0 , dst_db , 0 , tdb -> size );
172
- err = err ?err :errno ;
173
- fchown (dst_db , uid , gid );
174
- err = err ?err :errno ;
175
- close (src_db );
176
- err = err ?err :errno ;
177
- close (dst_db );
178
- err = err ?err :errno ;
179
-
180
- if (sf == -1 ) {
181
- fprintf (stderr , "Could not copy template file (%d) to %s (%d): %s (%d)\n" ,
182
- src_db , dst , dst_db , strerror (err ), err );
183
- remove (dst );
150
+ const int fd = open (dst , O_WRONLY | O_CREAT | O_DIRECT , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH );
151
+ if (fd < 0 ) {
152
+ return -1 ;
153
+ }
154
+
155
+ ssize_t written = 0 ;
156
+ while (written < tdb -> size ) {
157
+ const ssize_t w = pwrite (fd , tdb -> buf + written , tdb -> size - written , 0 );
158
+ if (w < 1 ) {
159
+ break ;
160
+ }
161
+
162
+ written += w ;
163
+ }
164
+
165
+ close (fd );
166
+
167
+ if (written != tdb -> size ) {
168
+ return -1 ;
169
+ }
170
+
171
+ if (chown (dst , uid , gid ) != 0 ) {
184
172
return -1 ;
185
173
}
186
174
0 commit comments