Skip to content

Commit 99a839d

Browse files
Merge pull request #35 from dreamer-coding/add_tempfile_feature
2 parents c86fcd1 + 222d7c9 commit 99a839d

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

code/logic/fossil/io/stream.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,15 @@ int32_t fossil_fstream_delete(const char *filename);
288288
*/
289289
int fossil_fstream_get_type(const char *filename);
290290

291+
/**
292+
* Create a temporary file.
293+
*
294+
* This function creates a temporary file and returns its name.
295+
*
296+
* @return A pointer to the name of the temporary file, or NULL on failure.
297+
*/
298+
fossil_fstream_t fossil_fstream_tempfile(void);
299+
291300
/**
292301
* Check if a file is readable.
293302
*
@@ -798,6 +807,17 @@ namespace fossil {
798807
return fossil_fstream_get_type(filename.c_str());
799808
}
800809

810+
/**
811+
* Create a temporary file.
812+
*
813+
* This function creates a temporary file and returns its name.
814+
*
815+
* @return A pointer to the name of the temporary file, or NULL on failure.
816+
*/
817+
static fossil_fstream_t tempfile() {
818+
return fossil_fstream_tempfile();
819+
}
820+
801821
/**
802822
* Check if a file is readable.
803823
*

code/logic/stream.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#include <windows.h>
2525
#else
2626
#include <unistd.h>
27+
#ifndef _POSIX_C_SOURCE
28+
extern int mkstemp(char *);
29+
#endif
2730
#include <fcntl.h>
2831
#endif
2932

@@ -530,6 +533,34 @@ int32_t fossil_fstream_is_readable(const char *filename) {
530533
#endif
531534
}
532535

536+
fossil_fstream_t fossil_fstream_tempfile(void) {
537+
fossil_fstream_t temp_stream;
538+
char temp_filename[FOSSIL_BUFFER_MEDIUM];
539+
540+
#ifdef _WIN32
541+
if (GetTempFileNameA(".", "fossil", 0, temp_filename) == 0) {
542+
fprintf(stderr, "Error: Failed to create temporary file\n");
543+
return (fossil_fstream_t){NULL, ""};
544+
}
545+
#else
546+
char template[] = "fossil_tempfile_XXXXXX";
547+
int fd = mkstemp(template);
548+
if (fd == -1) {
549+
fprintf(stderr, "Error: Failed to create temporary file\n");
550+
return (fossil_fstream_t){NULL, ""};
551+
}
552+
close(fd); // Close the file descriptor as it's no longer needed
553+
strncpy(temp_filename, template, FOSSIL_BUFFER_MEDIUM);
554+
#endif
555+
556+
if (fossil_fstream_open(&temp_stream, temp_filename, "wb+") != FOSSIL_ERROR_OK) {
557+
fprintf(stderr, "Error: Failed to open temporary file - %s\n", temp_filename);
558+
return (fossil_fstream_t){NULL, ""};
559+
}
560+
561+
return temp_stream;
562+
}
563+
533564
int32_t fossil_fstream_is_writable(const char *filename) {
534565
#ifdef _WIN32
535566
DWORD attrs = GetFileAttributesA(filename);

code/tests/cases/test_stream.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,31 @@ FOSSIL_TEARDOWN(c_stream_suite) {
4545
// as samples for library usage.
4646
// * * * * * * * * * * * * * * * * * * * * * * * *
4747

48+
FOSSIL_TEST_CASE(c_test_stream_tempfile_creation) {
49+
// Create a temporary file
50+
fossil_fstream_t temp_stream = fossil_fstream_tempfile();
51+
52+
// Check if the temporary file is open
53+
ASSUME_ITS_TRUE(fossil_fstream_is_open(&temp_stream));
54+
55+
// Close the temporary file
56+
fossil_fstream_close(&temp_stream);
57+
}
58+
59+
FOSSIL_TEST_CASE(c_test_stream_tempfile_cleanup) {
60+
// Create a temporary file
61+
fossil_fstream_t temp_stream = fossil_fstream_tempfile();
62+
63+
// Get the temporary file name
64+
const char *temp_filename = temp_stream.filename;
65+
66+
// Close the temporary file
67+
fossil_fstream_close(&temp_stream);
68+
69+
// Verify the temporary file is deleted
70+
ASSUME_NOT_EQUAL_I32(0, fossil_fstream_file_exists(temp_filename));
71+
}
72+
4873
FOSSIL_TEST_CASE(c_test_stream_let_write_and_read_file) {
4974
const char *filename = "testfile.txt";
5075
const char *content = "This is a test.";
@@ -266,6 +291,8 @@ FOSSIL_TEST_CASE(c_test_stream_setpos_and_getpos) {
266291
// * * * * * * * * * * * * * * * * * * * * * * * *
267292

268293
FOSSIL_TEST_GROUP(c_file_tests) {
294+
FOSSIL_TEST_ADD(c_stream_suite, c_test_stream_tempfile_creation);
295+
FOSSIL_TEST_ADD(c_stream_suite, c_test_stream_tempfile_cleanup);
269296
FOSSIL_TEST_ADD(c_stream_suite, c_test_stream_let_write_and_read_file);
270297
FOSSIL_TEST_ADD(c_stream_suite, c_test_stream_let_open_and_close_file);
271298
FOSSIL_TEST_ADD(c_stream_suite, c_test_stream_redirect_to_devnull);

code/tests/cases/test_stream.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,31 @@ FOSSIL_TEARDOWN(cpp_stream_suite) {
4545
// as samples for library usage.
4646
// * * * * * * * * * * * * * * * * * * * * * * * *
4747

48+
FOSSIL_TEST_CASE(cpp_test_stream_tempfile_creation) {
49+
// Create a temporary file
50+
fossil_fstream_t temp_stream = fossil_fstream_tempfile();
51+
52+
// Check if the temporary file is open
53+
ASSUME_ITS_TRUE(fossil_fstream_is_open(&temp_stream));
54+
55+
// Close the temporary file
56+
fossil_fstream_close(&temp_stream);
57+
}
58+
59+
FOSSIL_TEST_CASE(cpp_test_stream_tempfile_cleanup) {
60+
// Create a temporary file
61+
fossil_fstream_t temp_stream = fossil_fstream_tempfile();
62+
63+
// Get the temporary file name
64+
const char *temp_filename = temp_stream.filename;
65+
66+
// Close the temporary file
67+
fossil_fstream_close(&temp_stream);
68+
69+
// Verify the temporary file is deleted
70+
ASSUME_NOT_EQUAL_I32(0, fossil_fstream_file_exists(temp_filename));
71+
}
72+
4873
FOSSIL_TEST_CASE(cpp_test_stream_let_write_and_read_file) {
4974
const char *filename = "testfile.txt";
5075
const char *content = "This is a test.";
@@ -233,6 +258,31 @@ FOSSIL_TEST_CASE(cpp_test_stream_setpos_and_getpos) {
233258
fossil_fstream_close(&cpp_stream);
234259
}
235260

261+
FOSSIL_TEST_CASE(cpp_test_stream_class_tempfile_creation) {
262+
// Create a temporary file using the class method
263+
fossil_fstream_t temp_stream = fossil::io::Stream::tempfile();
264+
265+
// Check if the temporary file is open
266+
ASSUME_ITS_TRUE(fossil::io::Stream::is_open(&temp_stream));
267+
268+
// Close the temporary file
269+
fossil::io::Stream::close(&temp_stream);
270+
}
271+
272+
FOSSIL_TEST_CASE(cpp_test_stream_class_tempfile_cleanup) {
273+
// Create a temporary file using the class method
274+
fossil_fstream_t temp_stream = fossil::io::Stream::tempfile();
275+
276+
// Get the temporary file name
277+
const char *temp_filename = temp_stream.filename;
278+
279+
// Close the temporary file
280+
fossil::io::Stream::close(&temp_stream);
281+
282+
// Verify the temporary file is deleted
283+
ASSUME_NOT_EQUAL_I32(0, fossil::io::Stream::file_exists(temp_filename));
284+
}
285+
236286
FOSSIL_TEST_CASE(cpp_test_stream_class_write_and_read_file) {
237287
const char *filename = "testfile.txt";
238288
const char *content = "This is a test.";
@@ -373,6 +423,8 @@ FOSSIL_TEST_CASE(cpp_test_stream_class_get_permissions) {
373423
// * * * * * * * * * * * * * * * * * * * * * * * *
374424

375425
FOSSIL_TEST_GROUP(cpp_file_tests) {
426+
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_tempfile_creation);
427+
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_tempfile_cleanup);
376428
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_let_write_and_read_file);
377429
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_let_open_and_close_file);
378430
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_multiple_files);
@@ -387,6 +439,8 @@ FOSSIL_TEST_GROUP(cpp_file_tests) {
387439
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_flush_file);
388440
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_setpos_and_getpos);
389441

442+
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_class_tempfile_creation);
443+
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_class_tempfile_cleanup);
390444
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_class_write_and_read_file);
391445
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_class_open_and_close_file);
392446
FOSSIL_TEST_ADD(cpp_stream_suite, cpp_test_stream_class_multiple_files);

0 commit comments

Comments
 (0)