How can I open directory with open() function in C? - c

I want to open a directory without using <dirent.h>.
I tried this:
#include <fcntl.h>
int fd = open("dir", O_RDONLY, 0);
But it returns fd = -1. Why? As I know, the directory is a file too, it just stores the location of children files and directories.

You can open directories with open, but what you probably want is the function opendir.
You will benefit from reading the manual page for open, especially the parts about O_PATH and O_DIRECTORY.
To learn the details of the directory reading ABI, read the source of opendir/readdir in your C library.

Related

What is the relation between fopen and open?

I am working on a project for a class and we were given a .c file containing the following code:
int fd = -1;
if (fd < 0)
{
fd = open ("my_dev", O_RDWR);
if (fd < 0)
{
perror ("open");
return -1;
}
...
So I understand that it is trying to open a file "my_dev" with read/write permissions, and then is returning the file descriptor on success or a negative value on failure, but what I dont understand is why it is giving me "permission denied" consistently. I tried to use this code:
int des = open("my_dev", O_CREAT | O_RDWR, 0777);
...
close(des)
to open/create the file (this is called before the other block), but this does not work, and yet if I just use this instead:
FILE* file = fopen("my_dev","w+");
fprintf(file,str);
fclose(file);
I can write to the file, meaning I have write permissions. Now normally, I would just use fopen and fprintf for everything, but for this project, we sort of have to use the teacher's .c file which is going to try to use
open()
which is going to give a "permission denied" error which is in turn going to screw up my code.
I guess my question is how fopen and open relate to each other? Everyone seems to be able to recite that open is a system call whereas fopen is a standard lib function, but I cant seem to find a clear answer for how I can create a file with fopen() that can be opened by open() without a "permission denied" error, or how I can create a file with open() which I can then write to, close and open again with open().
In short, how do I create a file in C that I can write to and open later with open(O_RDWR)?
Sorry if this is a little piecey, im super tired.
PS: It should be noted that I am compiling and running on a university computer, so permissions may be "weird" BUT it should be noted that if I create the file with the terminal command "dd" open() will work, and furthermore, I clearly have SOME write permissions since I can indeed write to the file with fopen and fprintf
fopen is a library function that provided by the standard C runtime, it returns a stream and you can call stream functions on it, like fscanf, fprintf, or fread, fwrite.
open is usually a system call on unix-like systems, provided by the operating system kernel, it returns an file descriptor, you can call IO functions with the fd, like read, write.
Generally fopen is implemented using open underline.
If you want to use standard stream functions on a file descriptor, you can use the posix api, fdopen, which takes a fd, and returns a FILE* stream.

Basics questions regarding File and I/O System Calls in C (on Linux/UNIX)

I'm working on improving my C programming knowledge, but I am having trouble understanding the man pages for the following Unix system calls:
open
create
close
unlink
read
write
lseek
The man pages for each of these are, for lack of a better term, completely confusing and unintelligible. For example, here is the man page for open:
"Given a pathname for a file, open() returns a file descriptor, a small, nonnegative integer for use in subsequent system calls (read(2), write(2), lseek(2), fcntl(2), etc.). The file descriptor returned by a successful call will be the lowest-numbered file descriptor not currently open for the process.
By default, the new file descriptor is set to remain open across an execve(2) (i.e., the FD_CLOEXEC file descriptor flag described in fcntl(2) is initially disabled; the O_CLOEXEC flag, described below, can be used to change this default). The file offset is set to the beginning of the file (see lseek(2)).
A call to open() creates a new open file description, an entry in the system-wide table of open files. This entry records the file offset and the file status flags (modifiable via the fcntl(2) F_SETFL operation). A file descriptor is a reference to one of these entries; this reference is unaffected if pathname is subsequently removed or modified to refer to a different file. The new open file description is initially not shared with any other process, but sharing may arise via fork(2)."
I have no idea what this all means. From my understanding, if open returns a negative integer, an error occurred, and if it returns a positive integer, then that integer can be used in further system calls (???). That is, unfortunately, basically the extent of my knowledge and what I can attempt to parse from the man page. I need some help.
What does it mean that it "returns the lowest-numbered file descriptor not currently open for the process"? What process is it referring to? Why is it the lowest-numbered file descriptor, and why does this matter/how would I use this? I hate to sound like an idiot but I honestly have no clue what it's talking about.
Let's take an example. Let's say I wanted to create a new file in a directory, and open up a file from another directory, and copy the file I opened into the file I created, while checking for errors along the way. This is my attempt:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int XYZ = creat("XYZ.doc", 0 );
if (XYZ < 0)
printf("file creating error");
int file = open("/usr/.../xx.xx", 0);
if(file < 0)
printf("file opening error");
}
How would I copy the file that I opened into the file that I created? That should be easy. But what if I wanted to copy the file that I opened in reverse to the file that I created? (Maybe that example will illuminate how to use the file offset stuff mentioned in the man page, which I don't currently understand...)
I would like to edit this post to write a layman's terms description next to each of these system calls, thus creating a good online resource for people to study from. Also, if anyone has any good references for these system calls in C, that would be much appreciated as well.
Error checking left out for simplicity sake:
char data[1024]; /* size of this chosen more or less on a whim */
ssize_t n;
while ((n = read(file, data, sizeof(data))) > 0) {
write(XYZ, data, n);
}
close(file);
close(XYZ);

Negative return value in open system call for file created in /proc file system

I have created a file in /proc named "test" (it was created in kernel). The file exists. When I want to open it in user level it returns negative.
int fd;
if((fd=open("/proc/test","O_RDONLY"))<0){
perror("open");
}
The error that I see is open: File exists. I have seen this question but it is not my case.
You need parentheses in there (now fixed in the question), and the second argument to open() is not a string:
#include <fcntl.h>
int fd;
if ((fd = open("/proc/test", O_RDONLY)) < 0)
perror("open");
I'm not convinced it was a good idea to create a file of any sort in the /proc file system. In fact, I'm a bit surprised you were allowed to. If you are learning to program as root, I hope you have good backups.

How to lock files correctly in ANSI C

I am writing an ANSI C cgi-bin server program.
Each instance of program can access to the same files simultaneously.
I do as follows:
handle = fopen(name,type);
fd = fileno(handle);
MyLockFile(fd) //I use fcntl
.....
The problem is that I open file with "fopen", not with "open".
Will "locking" work in such manner?
I can lock "fd", not "handle".
The reason is that I can't write workable "fd=open..." code.
My code below creates the executable file, write permissions were not set.
I don't know why
fd = open(name,O_CREAT|O_WRONLY|S_IREAD|S_IWRITE|S_IRGRP|
S_IWGRP|S_IROTH|S_IWOTH);
write(fd,data,strlen(data));
close(fd);
I can neither write nor append to this file.
Your open() function is wrong, when you specify O_CREAT, the permission bits needs to be the 3. argument, e.g.
open(name,O_CREAT|O_WRONLY,
S_IREAD|S_IWRITE|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);

Retrieving the path from a file descriptor or FILE *?

Is there a way to retrieve path information from a file descriptor or FILE pointer?
I'm aware that this data may not always be relevant/useful for case where the file descriptor is a socket, pipe, etc.
I don't believe there's any portable way, but e.g. on Linux you can call readlink on "/proc/self/fd/fileno" and the kernel will give you a path if it can, or one of various kinds of funny-looking strings if not.
If you're lucky enough to be using Mac OS X you can use the following code:
#define _DARWIN_C_SOURCE
#include <sys/fcntl.h>
.
.
.
char pathbuf[PATH_MAX];
if (fcntl(fd, F_GETPATH, pathbuf) >= 0) {
// pathbuf now contains *a* path to the open file descriptor
}
Note that the path you get back is not necessarily the one used to open the file... If there are hard links, especially, the path you get back will be a valid path to the file.
There can be one or many names for a file, so no std way.
I am not sure if there can be something OS specific.

Resources