linux mkdir function can't authorize full permission - c

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

Related

Generating unique log files when running SnowSQL

(submitting on behalf of a Snowflake User)
I understand that you can configure log files by following this documentation (https://docs.snowflake.net/manuals/user-guide/snowsql-config.html#configuration-options-section) and the following snippet:
| log_bootstrap_file | ~/.snowsql/log_... | SnowSQL bootstrap log file location |
| log_file | ~/.snowsql/log | SnowSQL main log file location
BUT(!) is there a way to save log file of different jobs under different paths?
Any recommendations would be greatly appreciated! THANKS!
I would do something like the following, where I add the log file location to the snowsql command and my config file has a config called configName.
snowsql -c configName -o log_file=~/.snowsql/"$(date +'%Y%m%d_%H%M%S')"log
This example uses a pretty-close-to-unique-name for the logfile name, assuming you don't have two processes starting at the same second, this should work.
If you need to modify the path (e.g. /tmp/log/uniqueName/logfile.log), you could use OS environment variables in the same fashion, note however you'd likely have to create that folder/directory first.
I hope this helps...Rich

Why does creat("foo", S_IRUSR|S_IRGRP|S_IROTH) result in -r--------- permission?

I created a file foo using creat("foo",S_IRUSR|S_IRGRP|S_IROTH).
After the file creation, ls -l shows -r--------. Should not the read access for group and others also be set?

How to detect a user logged in through GUI in Linux

I would like to capture the user name logged in through GUI in my program. My program is running as a daemon from root login. If a non root user logs in through GUI my program should be notified.
I am pasting my current program which calls a perl script making use of system call to check who is the current user logged in. I am pasting my perl script too for reference.
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xfuncs.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
int main()
{
char *user;
char buf[1024];
int fd, ret;
fd = open("/tmp/log", O_TRUNC|O_RDWR|O_CREAT);
if (!fd) {
printf("Error opening file\n");
exit(1);
}
chmod("/tmp/log", S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP
| S_IROTH | S_IWOTH | S_IXOTH);
daemon(0, 0);
while (1) {
system("perl /home/curr-usr.pl");
sleep(5);
}
return 0;
}
The perl script which is used to get the current user logged in.
#!/usr/bin/perl
my $result;
$result = `whoami`;
open FH, "+>>", "/tmp/log" or die $!;
print FH "$result ";
close (FH);
In the c program above I am calling the perl script in a while loop every 5 seconds. The perl script makes use of the command "whoami" to get the current user logged in & dumps it into the /tmp/log file.
What I want to achieve is if user1 logs in the perl script should give me the current user to be user1. Instead the perl script gives me root as the current user irrespective of the user I am logged in through GUI as I am running the C program & perl script with root user.
Could anyone please advise me with a mechanism by which the C program could get to know the current user logged in through GUI ?
Any help is greatly appreciated.
You can detect the user using the main display like this:
#!/bin/bash
#Detect the name of the display in use
display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
#Detect the user using such display
user=$(who | grep '('$display')' | awk '{print $1}')
#Detect the id of the user
uid=$(id -u $user)
I am using XFCE4 and LXDM. "who" and "users" report only users that are logged on a terminal. GUI logon is not reported as Nominal Animal pointed out (Thanks!). I use "pgrep xfce" to check if XFCE4 is running. Following prints out current xfce-user:
#!/usr/bin/perl
# Get all processes
my #xfce_processes = `pgrep xfce`;
# If processes exist, get user of first process in list.
if(scalar #xfce_processes) {
print `ps -o user h $xfce_processes[0]`;
}
else
{
# No xfce processes.
;
}
As you mentioned your program runs as a daemon. Consequently any process it spawns would be run as the same user as one that started that daemon. The user that logs in via UI (or any other method) would never be the user you can get by calling whoami from your daemon.
Instead what you should do is explicitly notify your daemon of a login event or, if that is not an option, keep a list of all the logged-in sessions currently running on the box and see if new sessions appear - that would be a session of a newly logged-in user.
The programms who and users get their information from the file /var/run/utmp.
The file contains N entries of the size of "struct utmp", defined in <utmp.h>
You are interested in the USER_PROCESS type entries. The host field contains the display.
Note that there are multiple entries for the same display if the user opened some terminal emulations (xterm, konsole...).
You could monitor this file or /var/log/wtmp for a history
struct utmp ut_entry;
FILE *fp = fopen(UTMP_FILE, "r");
if( !fp )
{
printf("Could not open utmp file!");
return;
}
while(fread(&ut_entry, sizeof(struct utmp), 1, fp) == 1)
{
if(ut_entry.ut_type != USER_PROCESS)
continue;
// string entries are not 0 terminated if too long...
// copy user name to make sure it is 0 terminated
char tmpUser[UT_NAMESIZE+1] = {0};
strncpy(tmpUser, ut_entry.ut_user, UT_NAMESIZE);
// do more stuff... read the display from ut_entry.host
}
For more information see the utmp manual page
You probably want to investigate either ConsoleKit or its newer incarnation loginctl.
These tools are specifically designed for managing seats and sessions, while maintaining distinction between local text console, GUI and remote sessions. They are not guaranteed to be present on every X11 machine, but if yours is relatively recent, chances are it uses either one or the other tool.
For anyone else coming here for xfce4, what I had to do was run ps -aux | grep xfce4 then there was a line:
root 2497 0.0 0.3 323052 13408 ? Sl 01:24 0:00 xfce4-session
I run kill -9 2497 and that got rid of it. For me this was a hung instance I wanted to kill from SSH.

How do I give write permission to file in Linux?

How can I (programmatically) give write permission on a file to a particular user in Linux? Like, for example, its owner? Everyone has read access to this file.
In a shell or shell script simply use:
chmod u+w <filename>
This only modifies the write bit for the user, all other flags remain untouched.
If you want to do it in a C program, you need to use:
int chmod(const char *path, mode_t mode);
First query the existing mode via
int stat(const char *path, struct stat *buf);
... and just set the write bit by doing newMode = oldMode | S_IWUSR. See man 2 chmod and man 2 stat for details.
The octal mode 644 will give the owner read and write permissions, and just read permissions for the rest of the group, as well as other users.
read = 4
write = 2
execute = 1
owner = read | write = 6
group = read = 4
other = read = 4
The basic syntax of the command to set the mode is
chmod 644 [file name]
In C, that would be
#include <sys/stat.h>
chmod("[file name]", 0644);
chmod 644 FILENAME
6 is read and write, 4 is read only. Assuming the owner of the file is the user you wish to grant write access to.
You can do that using chmod, on ubuntu you can try out
$sudo chmod 666
This would give read/write permissions to all...check this out for more details:
http://catcode.com/teachmod/
You can use chmod 777 <filename>

mkfifo file permissions not being executed correctly

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 .

Resources