: '''file mkdir''' ''dir ?dir ...?'' Creates each directory specified. For each pathname ''dir'' specified, this command will create all non-existing parent directories as well as ''dir'' itself. If an existing directory is specified, then no action is taken and no error is returned. Trying to overwrite an existing file with a directory will result in an error. Arguments are processed in the order specified, halting at the first error, if any. ---- <> [Csan] When and how would it be possible to rewrite the following code into pure and simple Tcl while keeping the atomicity of the Unix mkdir?: ====== set unid $A while {[catch {exec mkdir uniqueids/$unid}]} { if {[incr unid]>$B} {set unid $A} } puts "$unid is available and has been locked." ====== The problem the above code is a solution for is: "Select the first available id between $A and $B. 'Available' is defined as 'not used by others'. When found, make sure you also lock it. When not used any more, unlock it." The best Tcl solution for the problem would be to have negative feedback when trying to create an already existing directory. E.g.: ====== file mkdir -booleanresult uniqueids/$unid ====== (or similar) which returned a boolean value depending on the success or failure of the directory creation would be a very good (best) improvement over the original code above. (Note that '-booleanresult' is only one of the possible names for the switch). [US] Unfortunately the code above does not work (see second sentence on this page). Dunno why. Maybe some obscure conformance to Windoze behaviour. [RS]: How about this variation? ====== # Assumptions: # A contains an integer value representing the low end of a range # B contains an integer value representing the high end of a range # Code rotates between A and B, looking for a directory that does not currently exist set unid $A while {[file exists uniqueids/$unid]} { if {[incr unid]>$B} {set unid $A} } file mkdir uniqueids/$unid puts "$unid is available and has been locked." ====== [Csan]: the variation is perfect code but not good for the purpose since the check and the creation is not happening at the same time (in other words they are not atomic: there is a time frame between the check and the creation of the directories when other similar code could interfere). E.g. how would you deal with concurrent processes or in case there is a (very) high I/O load which in turn causes several of this code to be enqueued? I don't feel like we get 100% unique ids (unique in the sense that there are not used by other processes). ---- [Csan] the perfect TCL equivalent hint was provided by [KBK] (thank you!): [open] has an EXCL option. From open(3tcl): EXCL: "If CREAT is also specified, an error is returned if the file already exists." So instead of ====== while {[catch {exec mkdir $uidd}]} {} ====== the following pure TCL can be used which provides the same functionality: ====== while {[catch {close [open $uidd {RDWR CREAT EXCL}]}]} {} ====== [pyk] 2012-11-11 - Not the same, the first creates a directory, the second creates a file. ---- <> **See also** * [file] * [file exists] * [file isdirectory] * [file isfile] <> Tcl syntax help | Command | File