Nelson.b.austin
Nelson.b.austin

Reputation: 3190

Check if input file is a valid file in C

I am trying to open a file in c using open() and I need to check that the file is a regular file (it can't be a directory or a block file). Every time I run open() my returned file discriptor is 3 - even when I don't enter a valid filename!

Here's what I have

/*
* Checks to see if the given filename is 
* a valid file
*/
int isValidFile(char *filename) {
    // We assume argv[1] is a filename to open
    int fd;
    fd = open(filename,O_RDWR|O_CREAT,0644);
    printf("fd = %d\n", fd);
    /* fopen returns 0, the NULL pointer, on failure */

}

Can anyone tell me how to validate input files? Thanks!

Upvotes: 3

Views: 10243

Answers (3)

user3642146
user3642146

Reputation: 9

int isValidFile(char *filename) {
    // We assume argv[1] is a filename to open
    int fd;
    fd = open(filename,O_RDWR|***O_CREAT***,0644);
    printf("fd = %d\n", fd);
    /* fopen returns 0, the NULL pointer, on failure */

}

you are using 0_CREAT which prompts the function to create if the file doesn't exist.this in the table its number is 3 (0,1,2 being std input std output and std error)

Upvotes: 1

pah
pah

Reputation: 4778

Try this:

int file_isreg(const char *path) {
    struct stat st;

    if (stat(path, &st) < 0)
        return -1;

    return S_ISREG(st.st_mode);
}

This code will return 1 if regular, 0 if not, -1 on error (with errno set).

If you want to check the file via its file descriptor returned by open(2), then try:

int fd_isreg(int fd) {
    struct stat st;

    if (fstat(fd, &st) < 0)
        return -1;

    return S_ISREG(st.st_mode);
}

You can find more examples here, (specifically in the path.c file).

You should also include the following headers in your code (as stated on stat(2) manual page):

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

For future reference, here is an excerpt of the stat(2) manpage regarding the POSIX macros available for st_mode field validations:

S_ISREG(m)  is it a regular file?

S_ISDIR(m)  directory?

S_ISCHR(m)  character device?

S_ISBLK(m)  block device?

S_ISFIFO(m) FIFO (named pipe)?

S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

Upvotes: 5

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

Wrong: check if the file is OK, then if it is, go open it and use it.

Right: go open it. If you can't, report the problem and bail out. Otherwise, use it (checking and reporting errors after each opetation).

Why: you have just checked that a file is OK. That's fine, but you cannot assume it will be OK in 0.000000017 seconds from now. Perhaps the disk wil overheat and break down. Perhaps some other process will mass-delete your entire file collection. Perhaps your cat will trip over the network cable. So let's just check if it's OK again, and then go open it. Wow, what a great idea! No wait...

Upvotes: 0

Related Questions