Tcl Source Code

Check-in [1c12ee9e45]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:closes [270f78ca95b642fb]: fix the race condition for `file mkdir` if some worker deletes directory immediately after the succeded create inside 3rd worker.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-branch
Files: files | file ages | folders
SHA3-256: 1c12ee9e45222d6c8d900d4ceab1d576926e1862b3871b9b9762f21392373e5f
User & Date: sebres 2018-07-09 17:18:07
References
2018-07-12
10:21 Open ticket [270f78ca95]: file mkdir: race condition if two workers creates same directory and one worker deletes it immediately plus 6 other changes artifact: 82c7c42d7f user: aspect
2018-07-09
17:38 Closed ticket [270f78ca95]. artifact: 3bc605cd57 user: sebres
Context
2018-07-12
14:17
win: closes [3f7af0e21e13f1f5] - avoid "permissions denied" by `file delete`, if file stat (TclpObjS... check-in: 4af9ff473e user: sebres tags: core-8-5-branch
2018-07-09
18:15
merge 8.5 check-in: ad71fa8ca4 user: sebres tags: core-8-6-branch
17:47
merge 8.5 (after fix of three-point race condition) check-in: 87ce4cf1e0 user: sebres tags: rfe-4f322b9d21
17:18
closes [270f78ca95b642fb]: fix the race condition for `file mkdir` if some worker deletes directory ... check-in: 1c12ee9e45 user: sebres tags: core-8-5-branch
2018-06-15
18:31
Align common install locations in SC_PATH_TCLCONFIG and SC_PATH_TKCONFIG. Add FreeBSD (closes [d6d60... check-in: 4790e733ef user: jan.nijtmans tags: core-8-5-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclFCmd.c.

239
240
241
242
243
244
245


246
247


248
249
250
251
252
253
254
...
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287

288
289
290
291
292
293

294
295
296
297
298
299
300
	Tcl_IncrRefCount(split);
	if (pobjc == 0) {
	    errno = ENOENT;
	    errfile = objv[i];
	    break;
	}
	for (j = 0; j < pobjc; j++) {


	    target = Tcl_FSJoinPath(split, j + 1);
	    Tcl_IncrRefCount(target);



	    /*
	     * Call Tcl_FSStat() so that if target is a symlink that points to
	     * a directory we will create subdirectories in that directory.
	     */

	    if (Tcl_FSStat(target, &statBuf) == 0) {
................................................................................
		/*
		 * Create might have failed because of being in a race
		 * condition with another process trying to create the same
		 * subdirectory.
		 */

		if (errno == EEXIST) {
		    if ((Tcl_FSStat(target, &statBuf) == 0)
			    && S_ISDIR(statBuf.st_mode)) {
			/*
			 * It is a directory that wasn't there before, so keep
			 * going without error.
			 */


			Tcl_ResetResult(interp);
		    } else {
			errfile = target;
			goto done;
		    }

		} else {
		    errfile = target;
		    goto done;
		}
	    }


	    /*
	     * Forget about this sub-path.
	     */

	    Tcl_DecrRefCount(target);
	    target = NULL;
	}






>
>


>
>







 







|
|
|
|
|
<
>
|
|
|
<
|
|
>
|
|
|
|
|
<
>







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
273
274
275
276
277
278
279
280
281
282
283
284

285
286
287
288

289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
	Tcl_IncrRefCount(split);
	if (pobjc == 0) {
	    errno = ENOENT;
	    errfile = objv[i];
	    break;
	}
	for (j = 0; j < pobjc; j++) {
	    int errCount = 2;

	    target = Tcl_FSJoinPath(split, j + 1);
	    Tcl_IncrRefCount(target);

	createDir:

	    /*
	     * Call Tcl_FSStat() so that if target is a symlink that points to
	     * a directory we will create subdirectories in that directory.
	     */

	    if (Tcl_FSStat(target, &statBuf) == 0) {
................................................................................
		/*
		 * Create might have failed because of being in a race
		 * condition with another process trying to create the same
		 * subdirectory.
		 */

		if (errno == EEXIST) {
		    /* Be aware other workers could delete it immediately after
		     * creation, so give this worker still one chance (repeat once),
		     * see [270f78ca95] for description of the race-condition.
		     * Don't repeat the create always (to avoid endless loop). */
		    if (--errCount > 0) {

			goto createDir;
		    }
		    /* Already tried, with delete in-between directly after
		     * creation, so just continue (assume created successful). */

		    goto nextPart;
		}

		/* return with error */
		errfile = target;
		goto done;
	    }


	nextPart:
	    /*
	     * Forget about this sub-path.
	     */

	    Tcl_DecrRefCount(target);
	    target = NULL;
	}