LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   file existnse (http://www.linuxquestions.org/questions/programming-9/file-existnse-4175435271/)

akshay_satish 11-02-2012 08:34 AM

file existnse
 
Hi Guys, I seem to stumble upon something really weird.
Code:

char a[512] = "";
char *dir = NULL;
int k;

if(NULL == dir) {
sprintf(a, "%s/%s", <#def1>,<#def2>);
}

if(access(a, F_OK) == 0) {
k = unlink(a);
if(k != 0) {
printf("unable to del. file %s: %d(%s).\n", a, errno, strerror(errno));
}
}

The output I am getting is ->
unable to del. file /: 2(No such file or directory).

errno 2 indicates ENOENT which is no such file or directory.

Any idea why the o/p is showing the filename as "/" (thoughts??).
Also, i am wondering how it executed the printf(....) statement. If the filename was infact "/", it shouldn't have even tried the "unlink" operation according to the code logic right? It should have exit'd the "if" condition right after "access()".
Kindly help....

dwhitney67 11-02-2012 08:47 AM

Quote:

Originally Posted by akshay_satish (Post 4820486)
Kindly help....

I'm not sure how you were able to get the output you describe based on the code you posted. Surely there must be more to your application than you are indicating. For example, how is the array 'a' ever populated with something other than a Null-string?

Here's a complete program that mimics what you have posted, and it functions correctly.

Code:

#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char** argv)
{
    const char* pathname = "";

    if (argc > 1)
    {
        pathname = argv[1];
    }

    if (access(pathname, F_OK) == 0)
    {
        fprintf(stdout, "File %s is accessible.\n", pathname);

        if (unlink(pathname) == 0)
        {
            fprintf(stdout, "File %s has been removed.\n", pathname);
        }
        else
        {
            fprintf(stderr, "Unable to unlink (delete) file %s; reason -- %s [%d]\n", pathname, strerror(errno), errno);
        }
    }
    else
    {
        fprintf(stderr, "Failed to access file '%s'; reason -- %s [%d]\n", pathname, strerror(errno), errno);
    }

    return 0;
}

P.S. Under Linux, a file and a directory can be considered to be the same with respect to being "accessible". If you are looking to delete only files (and not directories), then I suggest you use stat() to determine the attributes of the file (ie. file type, permissions, etc.)

sundialsvcs 11-02-2012 09:26 AM

An empty file-name could possibly be interpreted as "/" but in any case it's a nonsensical situation as-writ.

akshay_satish 11-02-2012 10:07 AM

Thank you DWhitney.. Yes the intent is to delete a file. I think doing a "stat" would be better as you mentioned... Yes in the first few lines of the function there is a do while loop within which if this file "a" is NULL then we break out of the loop and hit the deletion code which I've pasted above.
This confirms the issue right?
thanks again dWhitney. ur thoughts are just priceless..cheerio :)

akshay_satish 11-02-2012 10:35 AM

Quote:

Originally Posted by dwhitney67 (Post 4820500)
I'm not sure how you were able to get the output you describe based on the code you posted. Surely there must be more to your application than you are indicating. For example, how is the array 'a' ever populated with something other than a Null-string?

Here's a complete program that mimics what you have posted, and it functions correctly.

Code:

#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char** argv)
{
    const char* pathname = "";

    if (argc > 1)
    {
        pathname = argv[1];
    }

    if (access(pathname, F_OK) == 0)
    {
        fprintf(stdout, "File %s is accessible.\n", pathname);

        if (unlink(pathname) == 0)
        {
            fprintf(stdout, "File %s has been removed.\n", pathname);
        }
        else
        {
            fprintf(stderr, "Unable to unlink (delete) file %s; reason -- %s [%d]\n", pathname, strerror(errno), errno);
        }
    }
    else
    {
        fprintf(stderr, "Failed to access file '%s'; reason -- %s [%d]\n", pathname, strerror(errno), errno);
    }

    return 0;
}

P.S. Under Linux, a file and a directory can be considered to be the same with respect to being "accessible". If you are looking to delete only files (and not directories), then I suggest you use stat() to determine the attributes of the file (ie. file type, permissions, etc.)

I populated the pathname with "/" and performed a stat instead of access but it still hit the unlink's else case. can i know a little more about wht you were saying pls?

dwhitney67 11-02-2012 01:18 PM

Quote:

Originally Posted by akshay_satish (Post 4820628)
I populated the pathname with "/" and performed a stat instead of access but it still hit the unlink's else case. can i know a little more about wht you were saying pls?

stat() can tell you if a file (or directory) exists based on its return value. However, you should pass a 'struct stat' object to the function to obtain additional information about the file you are querying about. For example:
Code:

#include <errno.h>
#include <string.h>
#include <stdio.h>

int main()
{
    const char* pathname = "/";
    struct stat pathInfo;

    if (stat(pathname, &pathInfo) == 0)
    {
        if (S_ISDIR(pathInfo.st_mode))
        {
            fprintf(stdout, "pathname '%s' is a directory.\n", pathname);
        }
        else if (S_ISREG(pathInfo.st_mode))
        {
            fprintf(stdout, "pathname '%s' is a regular file.\n", pathname);
        }
        else /* ... */
        {
            /* ... */
        }
    }
    else
    {
        fprintf(stderr, "Cannot obtain status about '%s'; reason -- %s [%d]\n",
                pathname, strerror(errno), errno);
    }

    return 0;
}

For more comprehensive information about stat(), it actually is more helpful to read the man-page for fstat().

akshay_satish 11-05-2012 12:11 AM

Quote:

Originally Posted by dwhitney67 (Post 4820863)
stat() can tell you if a file (or directory) exists based on its return value. However, you should pass a 'struct stat' object to the function to obtain additional information about the file you are querying about. For example:
Code:

#include <errno.h>
#include <string.h>
#include <stdio.h>

int main()
{
    const char* pathname = "/";
    struct stat pathInfo;

    if (stat(pathname, &pathInfo) == 0)
    {
        if (S_ISDIR(pathInfo.st_mode))
        {
            fprintf(stdout, "pathname '%s' is a directory.\n", pathname);
        }
        else if (S_ISREG(pathInfo.st_mode))
        {
            fprintf(stdout, "pathname '%s' is a regular file.\n", pathname);
        }
        else /* ... */
        {
            /* ... */
        }
    }
    else
    {
        fprintf(stderr, "Cannot obtain status about '%s'; reason -- %s [%d]\n",
                pathname, strerror(errno), errno);
    }

    return 0;
}

For more comprehensive information about stat(), it actually is more helpful to read the man-page for fstat().

Thank you very much. Really appreciate your timely help~ cheerio.

akshay_satish 11-05-2012 04:22 AM

Hi Dwhitney67, i really appreciate your timely response. I have one more connected problem that I need some pointers. Pls assist:

In my header file I have a macro defined as;
Code:

#define QWE 1
....
#ifdef QWE
    #define ABC(params...) {
    fprintf(stderr, params);
    }
#else
    #define ABC(params...) {
    /*writes to a file*/
    }
#endif
....

Now in my C file, I use another macro to log statements either onto the console or into a file.

Code:

void abc() {
....
ABC("something\n");
....
}

int main()
{
abc();
}

From the above code logic, when abc() is called in main(), "something" is printed onto the console due to "STDERR". I need to find a way to log the line to the trace file without actually changing QWE to 0 in the #define. I have a switch case within which each case statements log to the stderr because of the QWE = 1 value. I need to print to the file only for one particular case. I hope u got my intent? Appreciate your response.

dwhitney67 11-05-2012 11:17 AM

fprintf() can be used to write to stdout, stderr, or any other stream (such as a file).

So I'm not sure why you require different implementations for the ABC() function, unless you are doing something drastically different when writing to a file (for example, in lieu of writing the data in ASCII format, you are writing it in binary).

So, if you are not doing anything different, then implement something like the following:
Code:

void ABC(FILE* stream, params...)
{
  fprintf(stream, ...);
}

void abc(FILE* stream)
{
    ...

    ABC(stream, ...);

    ...
}

int main()
{
    abc(stderr);

    FILE* myFile = fopen("SomeFile.txt", "w+");

    abc(myFile);

    fclose(myFile);
}


akshay_satish 11-05-2012 11:45 PM

Quote:

Originally Posted by dwhitney67 (Post 4822724)
fprintf() can be used to write to stdout, stderr, or any other stream (such as a file).

So I'm not sure why you require different implementations for the ABC() function, unless you are doing something drastically different when writing to a file (for example, in lieu of writing the data in ASCII format, you are writing it in binary).

So, if you are not doing anything different, then implement something like the following:
Code:

void ABC(FILE* stream, params...)
{
  fprintf(stream, ...);
}

void abc(FILE* stream)
{
    ...

    ABC(stream, ...);

    ...
}

int main()
{
    abc(stderr);

    FILE* myFile = fopen("SomeFile.txt", "w+");

    abc(myFile);

    fclose(myFile);
}


cool! that was a silly question that shouldnt have been asked. Sorry!

akshay_satish 11-05-2012 11:55 PM

Quote:

Originally Posted by dwhitney67 (Post 4820863)
stat() can tell you if a file (or directory) exists based on its return value. However, you should pass a 'struct stat' object to the function to obtain additional information about the file you are querying about. For example:
Code:

#include <errno.h>
#include <string.h>
#include <stdio.h>

int main()
{
    const char* pathname = "/";
    struct stat pathInfo;

    if (stat(pathname, &pathInfo) == 0)
    {
        if (S_ISDIR(pathInfo.st_mode))
        {
            fprintf(stdout, "pathname '%s' is a directory.\n", pathname);
        }
        else if (S_ISREG(pathInfo.st_mode))
        {
            fprintf(stdout, "pathname '%s' is a regular file.\n", pathname);
        }
        else /* ... */
        {
            /* ... */
        }
    }
    else
    {
        fprintf(stderr, "Cannot obtain status about '%s'; reason -- %s [%d]\n",
                pathname, strerror(errno), errno);
    }

    return 0;
}

For more comprehensive information about stat(), it actually is more helpful to read the man-page for fstat().

Okay so my actual problem here really is pathname should be getting a file. I am surprised why it is getting a directory!

dwhitney67 11-06-2012 05:08 AM

Quote:

Originally Posted by akshay_satish (Post 4823135)
Okay so my actual problem here really is pathname should be getting a file. I am surprised why it is getting a directory!

Getting a file (name/path) from where? From the user, from another file, through a network socket??

If you are referring to '/', then that is a directory. It is the root (not to be confused with the user 'root') directory of a Linux/Unix system.

akshay_satish 11-20-2012 04:37 AM

Hello I would to get confirmation on this piece of code that I've written. I am basically trying do an "scp" and trying to log useful information onto the console if it fails:

Code:

error = WEXITSTATUS(status);
                if (WIFEXITED(status) && error == 0) {
                    "blah blah"
                } else {
                    "blah blah"
 
                    switch (...) {
                    case a:
                    case b:
                        printf("WHOOPS: scp exited with status %d\n", error);
                        break;
                    default:
                        break;

now the return value for error at the last line is 1 which means WEXITSTATUS failed and returned 1. I am basically trying to do an scp.
Now i want to make the error more readable not throw a print saying "scp exited with status 1"...
is this better?->
Code:

printf( "WHOOPS: scp exited with status %s\n", strerror(error));
With this I get an error saying, "operation is not permitted".. I wanted to get your thoughts whether I am doing the right thing by using strerror or am I printing a string that is not coherent with the return value?

dwhitney67 11-20-2012 05:09 AM

akshay_satish -

You should have created a new thread for your latest query; it is unrelated to the one that you used to open this thread.

But to answer your question, the command 'scp' returns 0 on success, and some number greater than 0 (this could be any number!) on a failure. If a failure occurs, I don't believe the error number corresponds to anything other than to denote that an error occurred. Thus the use of strerror() would not be wise in this situation.

On my system, a failed 'scp' request, using the system() command, returns a status of 256; this translates to "Unknown error" when passed to strerror().

My recommendation is to avoid using system(), and instead use popen() so that you may read the output produced by the system command.

akshay_satish 11-20-2012 07:14 AM

I am extremely sorry DWhitney67.. Should I create one more now or can you forgive me for this question? I'll make sure to create unique threads for separate questions. Thank you very again for your valuable thoughts...Adding on...
Actually this is how I am doing the scp;

Code:

//argv will contain the scp cmd
      ret = posix_spawnp(
            &pid,
            argv[0],
            NULL, NULL,
            argv,
            NULL);                      //After this i perform a waitpid();

ret = waitpid(pid,&status,0);
if(ret != pid) {
/*failed*/
}
else{
error = WEXITSTATUS(status);
                if (WIFEXITED(status) && error == 0) {
                    "blah blah"
                } else {
                    "blah blah" //failed the downld.
 
                    switch (...) {
                    case a:
                    case b:
                        printf("WHOOPS: scp exited with status %d\n", error);
                        break;
                    default:
                        break;
}
}

Can you pls suggest now. You examples are always intriguing.. thanks again for your help. Hi, I am not able to see my replies or ur new replies anymore, i.e., page 2 onwards. has it been removed?


All times are GMT -5. The time now is 07:55 PM.