comparison src/filepath.c @ 30083:a542dfb1c1a2 v9.0.0379

patch 9.0.0379: cleaning up after writefile() is a hassle Commit: https://github.com/vim/vim/commit/806a273f3c84ecd475913d901890bb1929be9a0a Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 4 15:40:36 2022 +0100 patch 9.0.0379: cleaning up after writefile() is a hassle Problem: Cleaning up after writefile() is a hassle. Solution: Add the 'D' flag to defer deleting the written file. Very useful in tests.
author Bram Moolenaar <Bram@vim.org>
date Sun, 04 Sep 2022 17:00:03 +0200
parents f005dea14c8b
children 0fe61fa4e5d1
comparison
equal deleted inserted replaced
30082:3dc03a877e86 30083:a542dfb1c1a2
2230 void 2230 void
2231 f_writefile(typval_T *argvars, typval_T *rettv) 2231 f_writefile(typval_T *argvars, typval_T *rettv)
2232 { 2232 {
2233 int binary = FALSE; 2233 int binary = FALSE;
2234 int append = FALSE; 2234 int append = FALSE;
2235 int defer = FALSE;
2235 #ifdef HAVE_FSYNC 2236 #ifdef HAVE_FSYNC
2236 int do_fsync = p_fs; 2237 int do_fsync = p_fs;
2237 #endif 2238 #endif
2238 char_u *fname; 2239 char_u *fname;
2239 FILE *fd; 2240 FILE *fd;
2283 return; 2284 return;
2284 if (vim_strchr(arg2, 'b') != NULL) 2285 if (vim_strchr(arg2, 'b') != NULL)
2285 binary = TRUE; 2286 binary = TRUE;
2286 if (vim_strchr(arg2, 'a') != NULL) 2287 if (vim_strchr(arg2, 'a') != NULL)
2287 append = TRUE; 2288 append = TRUE;
2289 if (vim_strchr(arg2, 'D') != NULL)
2290 defer = TRUE;
2288 #ifdef HAVE_FSYNC 2291 #ifdef HAVE_FSYNC
2289 if (vim_strchr(arg2, 's') != NULL) 2292 if (vim_strchr(arg2, 's') != NULL)
2290 do_fsync = TRUE; 2293 do_fsync = TRUE;
2291 else if (vim_strchr(arg2, 'S') != NULL) 2294 else if (vim_strchr(arg2, 'S') != NULL)
2292 do_fsync = FALSE; 2295 do_fsync = FALSE;
2295 2298
2296 fname = tv_get_string_chk(&argvars[1]); 2299 fname = tv_get_string_chk(&argvars[1]);
2297 if (fname == NULL) 2300 if (fname == NULL)
2298 return; 2301 return;
2299 2302
2303 if (defer && !in_def_function() && get_current_funccal() == NULL)
2304 {
2305 semsg(_(e_str_not_inside_function), "defer");
2306 return;
2307 }
2308
2300 // Always open the file in binary mode, library functions have a mind of 2309 // Always open the file in binary mode, library functions have a mind of
2301 // their own about CR-LF conversion. 2310 // their own about CR-LF conversion.
2302 if (*fname == NUL || (fd = mch_fopen((char *)fname, 2311 if (*fname == NUL || (fd = mch_fopen((char *)fname,
2303 append ? APPENDBIN : WRITEBIN)) == NULL) 2312 append ? APPENDBIN : WRITEBIN)) == NULL)
2304 { 2313 {
2305 semsg(_(e_cant_create_file_str), *fname == NUL ? (char_u *)_("<empty>") : fname); 2314 semsg(_(e_cant_create_file_str),
2315 *fname == NUL ? (char_u *)_("<empty>") : fname);
2306 ret = -1; 2316 ret = -1;
2307 } 2317 }
2308 else if (blob) 2318 else
2309 { 2319 {
2310 if (write_blob(fd, blob) == FAIL) 2320 if (defer)
2311 ret = -1; 2321 {
2322 typval_T tv;
2323
2324 tv.v_type = VAR_STRING;
2325 tv.v_lock = 0;
2326 tv.vval.v_string = vim_strsave(fname);
2327 if (tv.vval.v_string == NULL
2328 || add_defer((char_u *)"delete", 1, &tv) == FAIL)
2329 {
2330 ret = -1;
2331 fclose(fd);
2332 (void)mch_remove(fname);
2333 }
2334 }
2335
2336 if (ret == 0)
2337 {
2338 if (blob)
2339 {
2340 if (write_blob(fd, blob) == FAIL)
2341 ret = -1;
2342 }
2343 else
2344 {
2345 if (write_list(fd, list, binary) == FAIL)
2346 ret = -1;
2347 }
2312 #ifdef HAVE_FSYNC 2348 #ifdef HAVE_FSYNC
2313 else if (do_fsync) 2349 if (ret == 0 && do_fsync)
2314 // Ignore the error, the user wouldn't know what to do about it. 2350 // Ignore the error, the user wouldn't know what to do about
2315 // May happen for a device. 2351 // it. May happen for a device.
2316 vim_ignored = vim_fsync(fileno(fd)); 2352 vim_ignored = vim_fsync(fileno(fd));
2317 #endif 2353 #endif
2318 fclose(fd); 2354 fclose(fd);
2319 } 2355 }
2320 else
2321 {
2322 if (write_list(fd, list, binary) == FAIL)
2323 ret = -1;
2324 #ifdef HAVE_FSYNC
2325 else if (do_fsync)
2326 // Ignore the error, the user wouldn't know what to do about it.
2327 // May happen for a device.
2328 vim_ignored = vim_fsync(fileno(fd));
2329 #endif
2330 fclose(fd);
2331 } 2356 }
2332 2357
2333 rettv->vval.v_number = ret; 2358 rettv->vval.v_number = ret;
2334 } 2359 }
2335 2360