2

First of all hi everyone,

my problem is, that my program creates a file, which is read by another program and after hat my program should delete the file.

I use the following code below to check if the file exists and if any other program uses the file. After the that I want to delete the file with:

if(isFileRdy("C:\\test\\foo.txt"))remove("C:\\test\\foo.txt");

Does anyone have any idea, where the problem could be. Interestingly this works for other files. And the foo.txt is also created by this program without special access rights.

Thanks :)

/* just suppose the things with argc and argv work, I know it's uggly
   but I need it as a call back function later in the code */

BOOL isFileRdy(char *filePath)
{
    int argc = 1;
    void *argv[1];
    argv[0]= (void*) filePath;
    return isFileRdyCBF(argv, argc);
}


BOOL isFileRdyCBF(void *argv[], int argc)
{
/* I used */
    char *filePath = (char*) argv[0];
    FILE *fDes = NULL;
    BOOL _fileExists = FALSE;
    BOOL _fileBussy = TRUE;

    _fileExists = fileExists(filePath);

    if(_fileExists)
    {
        fDes = fopen(filePath, "a+");
        if(fDes!=NULL)
        {
            _fileBussy = FALSE;
            if(fclose(fDes)!=0)
            {
                printf("\nERROR could not close file stream!");
                printf("\n      '%s'\n\n", filePath);
                return FALSE;
            }
        }
    }

    return (_fileExists==TRUE && _fileBussy==FALSE) ? TRUE : FALSE;
}
Dominik
  • 25
  • 5
  • 2
    Completely unrelated the the subsequent code, the first, most obvious problem is the backslashes in your hard-coded filename are not escaped. – WhozCraig Jan 03 '17 at 11:56
  • 2
    \ has special meaning and specially if u are in windows platform. Can you please provide us the complete code along with the error that you have faced.? – Vimal Bhaskar Jan 03 '17 at 11:57
  • 1
    Example: `remove("C:\\test\\foo.txt");` This should also work: `remove("c:/test/foo.txt");` – Prof. Falken Jan 03 '17 at 11:59
  • 2
    Similar to other functions, `remove` *tells* you why it cannot function. First of all, you don't check if it succeeded (so you can only see it didn't work because it didn't do anything to your file system). Second, more important, it says why it could not: "On success, zero is returned. On error, -1 is returned, and `errno` is set appropriately." This would probably have told you it cannot find such a file. – Jongware Jan 03 '17 at 12:15
  • What @RadLexus said is perhaps the most important thing here to learn, Dominik! ALWAYS check return values and think about them. You will learn programming very fast if you do. :) – Prof. Falken Jan 03 '17 at 12:19
  • 1
    Also, checking if the file exists then trying to open it is a [time-of-check, time-of-use (TOCTOU) bug](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use). What happens if the file is deleted between your check and your attempt to open it? – Andrew Henle Jan 03 '17 at 12:19
  • 1
    Thanks for the fast answers, in the real code I tried to use error handling with errno and so on but leave it out to improve readability. For further questions, should I copy and paste the whole code or leave out 'irrelevant' code like error handling? @Androw, I understand what you mean but how could I implement this? – Dominik Jan 03 '17 at 12:50
  • If your error checking stated an error occurred, then yes: you should have included it! If you leave it out (because you believe it is not a factor in the current problem), all you have to do is state you did so. But since an error *should have been reported*, it was an omission this time. ... I think I'd like to see your handling, even in case it does not report an error. Perhaps there is something wrong with that part. – Jongware Jan 03 '17 at 13:48

2 Answers2

4

This seems to be the problematic line (given that this is a snippet from int main(int argc, char **argv):

char *filePath = (char*) argv[0];

Here you assign the program executable file to filePath, but not the first argument to the program. The first parameter is in argv[1], but you must check first that argc >= 2.

When you try to delete the file via a static path entry, you must escape the \-signs in your string with a second \:

remove("C:\\test\\foo.txt");
Rudi
  • 19,366
  • 3
  • 55
  • 77
3

You say that it works for other files. What do these paths which work for you look like? Your whole problem could be that you are not using backslash \ correctly.

In C, \t means the tab character. So you wrote C:<TAB>test. To actually express the backslash character \ in C, you write \\. (This business of putting backslash before various characters to express special codes is called "escaping".)

For example, instead of remove("C:\test\foo.txt"); you would write remove("C:\\test\\foo.txt");

This should also work: remove("c:/test/foo.txt"); since Windows can also accept the forward slash / instead of backslash \in paths.

Also what Rudi said about argv.

Community
  • 1
  • 1
Prof. Falken
  • 24,226
  • 19
  • 100
  • 173