Question: I am trying to write a message to an existing file.
The check is performed to see certain variable values and then append a message accordingly to file, but $data value is not written to a file.
Please let me know is something wrong with my code?

```
proc run_sanity {} {
    global rundir typep corner_name reflib compLib
    cd $rundir
    set filename "sanity.txt"
    set fileId [open $filename "w"]
    if {[file exists $filename]} {
        exec rm -rf $rundir/sanity.txt
    }
    exec grep operating_conditions -A 3 $compLib | grep -v default | grep -v lu | grep -v variable > $rundir/sanity.txt
    exec grep nom $compLib >> $rundir/sanity.txt
    exec grep library $compLib | grep -v slew | grep -v features >> $rundir/sanity.txt
    set driver [exec grep -c driver_waveform $compLib]
    set recovery [exec grep -c recovery $compLib]
    set removal [exec grep -c removal $compLib]
    if {$driver > 0 && $recovery > 0 && $removal > 0} {
        set data "No data found for Driver waveform, Recovery and Removal Table.\n"
        puts $fileId $data
    } else {
        set data "Driver waveform, Recovery and Removal table is present in .lib.\n"
        puts $fileId $data
    }
    close $fileId
    exec emacs $rundir/sanity.txt &
}

```

Thanks
Dan

Answer: 
Basically, your code is

```
set fileId [open $filename "w"]      ; 1
if {[file exists $filename]} {       ; 2
    exec rm -rf $rundir/sanity.txt   ; 3
}
puts $fileId $data                   ; 4

```

So,

1. You open the file for writing.

The "w" mode makes sure the file is created if it does not exist
or is truncated if it does.
2. You then check if the file exists.

This check always passes because of the first step
(and unless you have a race on your filesystem—with some other 
process deleting the file before this check happens).
3. You delete the file.

Since this supposedly happens on a filesystem with POSIX semantics
(that is, on some Unix-y OS), any file descriptor opened to that
deleted file counts as a live reference to that file, so while the file
entry is removed from its directory on the file system *its data is not,*
and reading and writing of this data happens just OK—it's just
inaccessible outside of your process because this data no more has any
name on the filesystem.

By the way, this trick is routinely used by Unix software to keep
temporary data: a file is created and then immediately removed from
the file system while keeping an open file descriptor to it.
4. You write to the file. Writing happens OK and the data is actually
stored on the file system.

Once you close your file, its data loses the last live reference to it
and so at that very moment that data gets deleted.

So you should supposedly reconsider your approach to managing this file.
So far, there's little sanity in handling "sanity.txt". ;-)

---

By the way, why do you use `rm -rf` (and why `-r`?) instead of just `file delete` right from Tcl? That would be a tad faster.
This code works as i moved the fileId inside the if loop, taking care of POSIX semantics.

```
proc run_sanity {} {
global rundir typep corner_name reflib compLib
cd $rundir
set Sname "sanity.txt"
##set fileId [open $filename "a"]
if {[file exists $Sname]} {
file delete $rundir/sanity.txt
}
after 10000 {destroy .dialog4}
   tk_dialog .dialog4 "Running Sanity:" "SANITY TEST RUNNING" info 0 OK
exec grep operating_conditions -A 3 $compLib | grep -v default | grep -v lu | grep -v variable > $rundir/sanity.txt
exec grep nom $compLib >> $rundir/sanity.txt
exec echo "" >>  $rundir/sanity.txt
exec grep library $compLib | grep -v slew | grep -v features >> $rundir/sanity.txt
exec echo "" >>  $rundir/sanity.txt
set driver [exec grep -c driver_waveform $compLib]
set recovery [exec grep -c recovery $compLib]
set removal [exec grep -c removal $compLib]
cd $rundir
if {$driver > 0 && $recovery > 0 && $removal > 0} {
set filename "sanity.txt"
set fileId [open $filename "a"]
set msg "Driver waveform, Recovery and Removal table is present in .lib.\n"
puts $fileId $msg
close $fileId
} else {
set filename "sanity.txt"
set fileId [open $filename "a"]
set msg "No data found for Driver waveform, Recovery and Removal Table.\n"
puts $fileId $msg
close $fileId
}
exec emacs $rundir/sanity.txt &
}

```