I have a small snippet
fd = open("data", O_RDONLY | O_CREAT, 0666) is giving me the permission wrongly.
When I did the ls -l data I got this
-rw------- 1 mayukhsarkar staff 0 Aug 17 11:44 data
can some tell what's wrong?
Note: In koding.com I am getting permission like this
-rw-r--r-- 1 mayukh mayukh 0 Aug 17 06:11 data
SOLVED: umask(000) before the open syscall did the trick
You're passing the mode incorrectly. It needs to be passed as a third argument:
open("data", O_RDONLY | O_CREAT, 0666);
Note that creating a file with O_RDONLY doesn't make a lot of sense, as you won't be able to write to it after creating it...
Related
I'm new on StackOverflow and learning about pipes in C. I'm trying to make a shell interpeter that allows introducing 2 commands linked by pipe like
/bin/ls -l | /bin/grep a
I have a main which have a function that reads a command, then main calls a function that searchs for a "|" and if it finds it, the function makes 2 commands from it, then that function calls another one which executes the commands. My problem is that it just works once. If I introduce a command with pipes it executes it perfectly, but if I do it again it doesn't work, like the directory had change. It doesn't matter that the first command has pipes or not, the second command (if it has pipes) wont execute correctly. I think it's because of the pipes, the code of the function that execute the pipes:
void execute_pipes(char *** command1, char *** command2){
pid_t son;
int tube2[2];
pipe(tube2);
son=fork();
if(son==0){//son1
dup2(tube2[1], STDOUT_FILENO);
close(tube2[0]);
if(execv((*command1)[0],*command1)==-1){
printf("Error");
exit(0);
}
}else{//father
son=fork();
if(son==0){//son2
dup2(tube2[0], STDIN_FILENO);
close(tube2[1]);
if(execv((*command2)[0],*command2)==-1){
printf("Error");
exit(0);
}
}else{//father
close(tube2[0]);
close(tube2[1]);
waitpid(son, NULL, 0);
}
}
}
I'm sure that the parameters are ok, ending with a NULL parameter (if not I guess it wouldnt execute one time). In each new read, a new pipe is created. I guess that the last pipe won't affect this new one but I don't know...
An example of this:
/home/user/Desktop$ /bin/ls -l | /bin/grep -
-rw-rw-r-- 1 user user 435 dec 18 02:33 filename
drwxrwsr-x 9 user user 4096 dec 20 19:23 filename
-rwxrwxr-x 1 user user 14464 dec 20 20:29 filename
-rw-rw-r-- 1 user user 3580430 dec 5 03:24 filename
-rw-rw-r-- 1 user user 6833 dec 20 20:05 filename
-rw-rw-r-- 1 user user 6772 dec 20 18:48 filename
-rw-rw-r-- 1 user user 1226 dec 19 21:48 filename
-rwxrwxr-x 1 user user 8704 dec 18 16:23 filename
-rw-rw-r-- 1 user user 33673847 oct 17 20:50 filename
/home/user/Desktop$ /bin/ls -l | /bin/grep -
-rwxr-xr-x 1 root root 126584 feb 18 2016 /bin/ls
/home/user/Desktop$
NOTE: I've changed my username for 'user' and the names of the files for 'filename'.
Thanks whoever who reads this.
Summarising: my code only executes a command correctly one time, the second time it doesn't work properly and I don't know why, but I guess the problem are the pipes.
I can't comment yet, so I'm posting it as an answer. Welcome to SO. It will be easier for people to help you if you provide a working example, which I think you can. Here is a guide How to create a Minimal, Complete, and Verifiable example
Unfortunately I can't get your code to work. Maybe looking at an example implementation of a lightweight shell will help you. Here is the source code for xv6 shell. Search for PIPE keyword.
xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix
Version 6 (v6).
Oke, I solved the problem, it was a problem of the initialization of the parameters. It was in a function I didn't write because I supposed it worked.
The only doubt I have now is why was even able to execute...
Thanks everyone for answering me .
I get a wierd Linux system message "Transport Endpoint is not connected" in response to a write call immediately after a successful open call. All this happens immediately after a Slackware Linux 2.6.33.4 reboot.
I'm writing a forms-handler in C and it runs under lighttpd and fastcgi (and before some smart alec pipes up and asks 'why am I not using his/her favourite language, it's because I like C --- OK? OK!).
I've got the major facilities of the application running - it displays index.htm (which is a form) and when the form is 'Submit'ted, finds the program I've written which correctly processes the contents returned and displays the next form. It's got complex enough that now I need to print some debugging statements somewhere, to give me some feedback from program additions. Thus arises the problem.
Research indicates that this message usually means that the endpoint of the file path is not or has become not mounted but /tmp/debug.log (which is the file I'm trying to create/append-to lives on the root partition. But then why is the open() successful but the write() is not?
The program fragment below is the bit which is giving trouble. The printf() statements send output to the web interface (for those unfamiliar with libfcgi) to give me some idea what's happening.
I can't get my (properly indented) code through this forum's demented code filter and I can't attach it in a zip file, so you'll just have to take my word that the syntax is correct.
Any clues?
This line
if(fd = open(DEBUG_FILE_NAME, (O_CREAT | O_APPEND | O_RDWR), (S_IWUSR | S_IRGRP | S_IROTH | S_IRUSR)) < 0)
results in fd being set to the result of open(DEBUG_FILE_NAME, (O_CREAT | O_APPEND | O_RDWR), (S_IWUSR | S_IRGRP | S_IROTH | S_IRUSR)) < 0 which most likely is 0.
So the write(fd, ... tries to write to stdin, which is weird, so you get a weird error ... ;-)
To fix this fix the parenthesis.
You could do this for example in save manner by using Yoda-Conditions:
if (0 > (fd = open(DEBUG_FILE_NAME, (O_CREAT | O_APPEND | O_RDWR), (S_IWUSR | S_IRGRP | S_IROTH | S_IRUSR))))
("save" in terms that everything important is at the left in one place: if (0 > (fd = open(...)
After I found a file on the disk , I now need to print out all its details , for example :
-rwxr-xr-x 1 1000 1000 8296 2010-01-06 22:29 ./Documents/exer4
-rwxr-xr-x 1 1000 1000 8517 2009-12-30 11:30 ./Documents/os/exer4
lrwxrwxrwx 1 1000 1000 8 2010-01-10 13:10 ./Documents/cs/2012/exer4 -> ../a.out
I need to print a file details without using ls -ln .Any idea how to do that ?
Thanks
You want the stat() function.
Here's a web page that documents *NIX file functions including stat():
http://rabbit.eng.miami.edu/info/functions/unixio.html
You can use this function:
int lstat(const char *path, struct stat *buf);
This works for me from the shell.
ls -l | grep -v "\->"
It simply filters out any line that has a -> in it.
Note however, that if you have any files/directories that for some reason have -> in their names, they will also be filtered out. Having said that, I've never seen that, nor would it be a good idea.
I am testing the mkdir function to create a new directory:
folder = mkdir("./linux", 511);
or
folder = mkdir("./linux", 0777);
or
folder = mkdir("./linux", S_IRWXU | S_IRWXG | S_IRWXO);
As you can see, I try to authorize the full permission to the directory but here's what comes up with ls -l | grep linux:
drwxr-xr-x 2 manuzhang manuzhang 4096 2012-01-04 06:53 linux
why can't I authorize write permission for group and others?
Updates:
weird thing, as you guys told me I tried umask. It works with either umask(S_IWGRP) or umask(S_IWOTH) but fails with umask(S_IWGRP | S_IWOTH), any ideas?
From man 2 mkdir:
The argument mode specifies the permissions to use. It is modified by the process's umask in the usual way: the permissions of the created directory are (mode & ~umask & 0777).
I suggest you look at your umask - it is probably set to 0022. Try a chmod post-mkdir.
Permissions set by system calls like mkdir and open are always masked against the current process's umask. You can change the current umask using the umask() function; make sure to set it back when you're done.
Check the umask function: man 2 umask
The following line in my C program should provided All/Group/Owner read and write permissions
mkfifo("/tmp/dumbPipe", 0666)
But once I execute the code and check out the permission non of the write bits were set, I end up with
prw-r--r--
The owners are the same, Is it a problem since I'm creating the pipe in the tmp directory? When I run chmod 666 from the cmd line all the permissions get set correctly.
This is a no-comments post, just quoting manuals. Brievity etc.
Quote from man 3 mkfifo:
It is modified by the process's umask in the usual way: the permissions of the created file are (mode & ~umask).
Quote from man 2 umask
The typical default value for the process umask is S_IWGRP | S_IWOTH (octal 022). In the usual case where the mode argument to
open(2) is specified as:
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
(octal 0666) when creating a new file, the permissions on the resulting file will be:
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
(because 0666 & ~022 = 0644; i.e., rw-r--r--).
Salam,
I know it is to late but for other users I choose to write this comment
Even if you precise 0666 as permission, you should know that there is an another factor that is called " process's file mode creation ", so the question is :
how to change current process file mode creation ?
Answer : use umask(permission) at beginning of your program - and give 0000 as permission
http://www.cyberciti.biz/tips/understanding-linux-unix-umask-value-usage.html
this should help .