2020#include "fd-util.h"
2121#include "fileio.h"
2222#include "fs-util.h"
23- #include "hexdecoct.h"
2423#include "log.h"
2524#include "macro.h"
2625#include "missing.h"
2726#include "parse-util.h"
2827#include "path-util.h"
2928#include "process-util.h"
30- #include "random-util.h"
3129#include "stdio-util.h"
3230#include "string-util.h"
3331#include "strv.h"
34- #include "time-util.h"
35- #include "umask-util.h"
32+ #include "tmpfile-util.h"
3633#include "utf8.h"
3734
3835#define READ_FULL_BYTES_MAX (4U*1024U*1024U)
@@ -1128,39 +1125,6 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *root
11281125 return search_and_fopen_internal (path , mode , root , s , _f );
11291126}
11301127
1131- int fopen_temporary (const char * path , FILE * * _f , char * * _temp_path ) {
1132- FILE * f ;
1133- char * t ;
1134- int r , fd ;
1135-
1136- assert (path );
1137- assert (_f );
1138- assert (_temp_path );
1139-
1140- r = tempfn_xxxxxx (path , NULL , & t );
1141- if (r < 0 )
1142- return r ;
1143-
1144- fd = mkostemp_safe (t );
1145- if (fd < 0 ) {
1146- free (t );
1147- return - errno ;
1148- }
1149-
1150- f = fdopen (fd , "we" );
1151- if (!f ) {
1152- unlink_noerrno (t );
1153- free (t );
1154- safe_close (fd );
1155- return - errno ;
1156- }
1157-
1158- * _f = f ;
1159- * _temp_path = t ;
1160-
1161- return 0 ;
1162- }
1163-
11641128int fflush_and_check (FILE * f ) {
11651129 assert (f );
11661130
@@ -1192,163 +1156,6 @@ int fflush_sync_and_check(FILE *f) {
11921156 return 0 ;
11931157}
11941158
1195- /* This is much like mkostemp() but is subject to umask(). */
1196- int mkostemp_safe (char * pattern ) {
1197- _cleanup_umask_ mode_t u = 0 ;
1198- int fd ;
1199-
1200- assert (pattern );
1201-
1202- u = umask (077 );
1203-
1204- fd = mkostemp (pattern , O_CLOEXEC );
1205- if (fd < 0 )
1206- return - errno ;
1207-
1208- return fd ;
1209- }
1210-
1211- int fmkostemp_safe (char * pattern , const char * mode , FILE * * ret_f ) {
1212- int fd ;
1213- FILE * f ;
1214-
1215- fd = mkostemp_safe (pattern );
1216- if (fd < 0 )
1217- return fd ;
1218-
1219- f = fdopen (fd , mode );
1220- if (!f ) {
1221- safe_close (fd );
1222- return - errno ;
1223- }
1224-
1225- * ret_f = f ;
1226- return 0 ;
1227- }
1228-
1229- int tempfn_xxxxxx (const char * p , const char * extra , char * * ret ) {
1230- const char * fn ;
1231- char * t ;
1232-
1233- assert (ret );
1234-
1235- if (isempty (p ))
1236- return - EINVAL ;
1237- if (path_equal (p , "/" ))
1238- return - EINVAL ;
1239-
1240- /*
1241- * Turns this:
1242- * /foo/bar/waldo
1243- *
1244- * Into this:
1245- * /foo/bar/.#<extra>waldoXXXXXX
1246- */
1247-
1248- fn = basename (p );
1249- if (!filename_is_valid (fn ))
1250- return - EINVAL ;
1251-
1252- extra = strempty (extra );
1253-
1254- t = new (char , strlen (p ) + 2 + strlen (extra ) + 6 + 1 );
1255- if (!t )
1256- return - ENOMEM ;
1257-
1258- strcpy (stpcpy (stpcpy (stpcpy (mempcpy (t , p , fn - p ), ".#" ), extra ), fn ), "XXXXXX" );
1259-
1260- * ret = path_simplify (t , false);
1261- return 0 ;
1262- }
1263-
1264- int tempfn_random (const char * p , const char * extra , char * * ret ) {
1265- const char * fn ;
1266- char * t , * x ;
1267- uint64_t u ;
1268- unsigned i ;
1269-
1270- assert (ret );
1271-
1272- if (isempty (p ))
1273- return - EINVAL ;
1274- if (path_equal (p , "/" ))
1275- return - EINVAL ;
1276-
1277- /*
1278- * Turns this:
1279- * /foo/bar/waldo
1280- *
1281- * Into this:
1282- * /foo/bar/.#<extra>waldobaa2a261115984a9
1283- */
1284-
1285- fn = basename (p );
1286- if (!filename_is_valid (fn ))
1287- return - EINVAL ;
1288-
1289- extra = strempty (extra );
1290-
1291- t = new (char , strlen (p ) + 2 + strlen (extra ) + 16 + 1 );
1292- if (!t )
1293- return - ENOMEM ;
1294-
1295- x = stpcpy (stpcpy (stpcpy (mempcpy (t , p , fn - p ), ".#" ), extra ), fn );
1296-
1297- u = random_u64 ();
1298- for (i = 0 ; i < 16 ; i ++ ) {
1299- * (x ++ ) = hexchar (u & 0xF );
1300- u >>= 4 ;
1301- }
1302-
1303- * x = 0 ;
1304-
1305- * ret = path_simplify (t , false);
1306- return 0 ;
1307- }
1308-
1309- int tempfn_random_child (const char * p , const char * extra , char * * ret ) {
1310- char * t , * x ;
1311- uint64_t u ;
1312- unsigned i ;
1313- int r ;
1314-
1315- assert (ret );
1316-
1317- /* Turns this:
1318- * /foo/bar/waldo
1319- * Into this:
1320- * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
1321- */
1322-
1323- if (!p ) {
1324- r = tmp_dir (& p );
1325- if (r < 0 )
1326- return r ;
1327- }
1328-
1329- extra = strempty (extra );
1330-
1331- t = new (char , strlen (p ) + 3 + strlen (extra ) + 16 + 1 );
1332- if (!t )
1333- return - ENOMEM ;
1334-
1335- if (isempty (p ))
1336- x = stpcpy (stpcpy (t , ".#" ), extra );
1337- else
1338- x = stpcpy (stpcpy (stpcpy (t , p ), "/.#" ), extra );
1339-
1340- u = random_u64 ();
1341- for (i = 0 ; i < 16 ; i ++ ) {
1342- * (x ++ ) = hexchar (u & 0xF );
1343- u >>= 4 ;
1344- }
1345-
1346- * x = 0 ;
1347-
1348- * ret = path_simplify (t , false);
1349- return 0 ;
1350- }
1351-
13521159int write_timestamp_file_atomic (const char * fn , usec_t n ) {
13531160 char ln [DECIMAL_STR_MAX (n )+ 2 ];
13541161
@@ -1412,71 +1219,6 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
14121219 return fputs (s , f );
14131220}
14141221
1415- int open_tmpfile_unlinkable (const char * directory , int flags ) {
1416- char * p ;
1417- int fd , r ;
1418-
1419- if (!directory ) {
1420- r = tmp_dir (& directory );
1421- if (r < 0 )
1422- return r ;
1423- } else if (isempty (directory ))
1424- return - EINVAL ;
1425-
1426- /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
1427-
1428- /* Try O_TMPFILE first, if it is supported */
1429- fd = open (directory , flags |O_TMPFILE |O_EXCL , S_IRUSR |S_IWUSR );
1430- if (fd >= 0 )
1431- return fd ;
1432-
1433- /* Fall back to unguessable name + unlinking */
1434- p = strjoina (directory , "/systemd-tmp-XXXXXX" );
1435-
1436- fd = mkostemp_safe (p );
1437- if (fd < 0 )
1438- return fd ;
1439-
1440- (void ) unlink (p );
1441-
1442- return fd ;
1443- }
1444-
1445- int open_tmpfile_linkable (const char * target , int flags , char * * ret_path ) {
1446- _cleanup_free_ char * tmp = NULL ;
1447- int r , fd ;
1448-
1449- assert (target );
1450- assert (ret_path );
1451-
1452- /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
1453- assert ((flags & O_EXCL ) == 0 );
1454-
1455- /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
1456- * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
1457- * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
1458-
1459- fd = open_parent (target , O_TMPFILE |flags , 0640 );
1460- if (fd >= 0 ) {
1461- * ret_path = NULL ;
1462- return fd ;
1463- }
1464-
1465- log_debug_errno (fd , "Failed to use O_TMPFILE for %s: %m" , target );
1466-
1467- r = tempfn_random (target , NULL , & tmp );
1468- if (r < 0 )
1469- return r ;
1470-
1471- fd = open (tmp , O_CREAT |O_EXCL |O_NOFOLLOW |O_NOCTTY |flags , 0640 );
1472- if (fd < 0 )
1473- return - errno ;
1474-
1475- * ret_path = TAKE_PTR (tmp );
1476-
1477- return fd ;
1478- }
1479-
14801222int open_serialization_fd (const char * ident ) {
14811223 int fd ;
14821224
@@ -1496,35 +1238,6 @@ int open_serialization_fd(const char *ident) {
14961238 return fd ;
14971239}
14981240
1499- int link_tmpfile (int fd , const char * path , const char * target ) {
1500- int r ;
1501-
1502- assert (fd >= 0 );
1503- assert (target );
1504-
1505- /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
1506- * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
1507- * on the directory, and renameat2() is used instead.
1508- *
1509- * Note that in both cases we will not replace existing files. This is because linkat() does not support this
1510- * operation currently (renameat2() does), and there is no nice way to emulate this. */
1511-
1512- if (path ) {
1513- r = rename_noreplace (AT_FDCWD , path , AT_FDCWD , target );
1514- if (r < 0 )
1515- return r ;
1516- } else {
1517- char proc_fd_path [STRLEN ("/proc/self/fd/" ) + DECIMAL_STR_MAX (fd ) + 1 ];
1518-
1519- xsprintf (proc_fd_path , "/proc/self/fd/%i" , fd );
1520-
1521- if (linkat (AT_FDCWD , proc_fd_path , AT_FDCWD , target , AT_SYMLINK_FOLLOW ) < 0 )
1522- return - errno ;
1523- }
1524-
1525- return 0 ;
1526- }
1527-
15281241int read_nul_string (FILE * f , char * * ret ) {
15291242 _cleanup_free_ char * x = NULL ;
15301243 size_t allocated = 0 , n = 0 ;
@@ -1565,33 +1278,6 @@ int read_nul_string(FILE *f, char **ret) {
15651278 return 0 ;
15661279}
15671280
1568- int mkdtemp_malloc (const char * template , char * * ret ) {
1569- _cleanup_free_ char * p = NULL ;
1570- int r ;
1571-
1572- assert (ret );
1573-
1574- if (template )
1575- p = strdup (template );
1576- else {
1577- const char * tmp ;
1578-
1579- r = tmp_dir (& tmp );
1580- if (r < 0 )
1581- return r ;
1582-
1583- p = strjoin (tmp , "/XXXXXX" );
1584- }
1585- if (!p )
1586- return - ENOMEM ;
1587-
1588- if (!mkdtemp (p ))
1589- return - errno ;
1590-
1591- * ret = TAKE_PTR (p );
1592- return 0 ;
1593- }
1594-
15951281DEFINE_TRIVIAL_CLEANUP_FUNC (FILE * , funlockfile );
15961282
15971283int read_line (FILE * f , size_t limit , char * * ret ) {
0 commit comments