FrostyWhite
FrostyWhite

Reputation: 29

C open() function fails. Are my parameters wrong?

This function fails to open the file. Are my parameters wrong or what could be causing this problem?

    int CreateFile(const char *filename){
        char filepath[strlen(filename) + 3];
        sprintf(filepath, "./%s", filename);
        int fd = open(filepath, O_CREAT, O_APPEND, S_IWGRP);
        if(fd == -1) printf("file read failed\n");
        return fd;
    }

Xcode prints only "file read failed" to the console. I tried to run this via Terminal aswell but that didn't help either.

I fixed an issue pointed by NetMage:

int CreateFile(const char *filename){
    char filepath[strlen(filename) + 3];
    sprintf(filepath, "./%s", filename);
    int fd = open(filepath, O_CREAT|O_APPEND, S_IWGRP);
    if(fd == -1) printf("file read failed\n");
    return fd;
}

Unfortunately that didn't fix the issue

Upvotes: 3

Views: 2466

Answers (3)

Andrew Henle
Andrew Henle

Reputation: 1

Per the POSIX documentation for open() (somewhat reformatted, and note the bolded text):

SYNOPSIS

#include <sys/stat.h> #include <fcntl.h>

int open(const char *path, int oflag, ...);

...

Values for oflag are constructed by a bitwise-inclusive OR of flags from the following list, defined in . Applications shall specify exactly one of the first five values (file access modes) below in the value of oflag:

  • O_EXEC Open for execute only (non-directory files). The result is unspecified if this flag is applied to a directory.
  • O_RDONLY Open for reading only.
  • O_RDWR Open for reading and writing. The result is undefined if this flag is applied to a FIFO.
  • O_SEARCH Open directory for search only. The result is unspecified if this flag is applied to a non-directory file.
  • O_WRONLY Open for writing only.

...

You need to include at least one of those five flags, perhaps like:

int fd = open(filepath, O_WRONLY|O_CREAT|O_APPEND, S_IWGRP);

Note that other failures may still occur. As noted in the comments, you're prepending "./" to the file name, which may cause problems if, for example, you get passed "/tmp/filename" and the tmp directory doesn't exist in your current working directory, as open() will not create missing directories in any path.

Upvotes: 0

NetMage
NetMage

Reputation: 26907

The open function takes only one parameter for oflags, which must be bit-ored together:

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

int fd = open(filepath, O_CREAT|O_APPEND, S_IWGRP);
if (fd == -1) printf("file read failed: %s\n", strerror(errno));

Upvotes: 1

John Bode
John Bode

Reputation: 123458

Step 1 - Verify that filepath is being set correctly, either by printing it to the terminal or examining it in a debugger.

Step 2 - Verify that the file exists in that path, and that its permissions are set so that you can open it. If filepath is "./foo", then a file named foo had better exist in the current working directory (the directory from which you ran the program), and it needs to have at least read permission.

Step 3 - If the file does not exist, verify that you have permission to create new files in the current working directory.

Step 4 - If after doing all of that you still get an error, check errno. It will give you some additional information beyond "it didn't work."

#include <errno.h>
...
if(fd == -1) 
{
  switch( errno )
  {
    case EACCESS: // permission issues
      handle_permission_issue();
      break;

    case EEXIST: // file already exists and you used O_CREAT and O_EXCL
      handle_already_exists_issue();
      break;

    case EFAULT: // bad path
      handle_bad_path_issue()
      break;

    ...
  }
  printf("file read failed\n");
}

NetMage has pointed out one problem - your flags need to be bitwise-OR'd together, rather than listed as separate arguments. Surprised the compiler didn't yell at you over that.

Upvotes: 2

Related Questions