I am trying to create a 'test.txt' file in root directory. Currently I am not a root user. my code is as follows:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int fd;
fd=open("/test.txt",O_CREAT|O_RDWR|O_TRUNC,0777);
perror("error: ");
close(fd);
return 0;
}
however, when I compile and execute it, I get the error:
error: : Permission denied
how can I make my code to have the permission to create a file in root directory?
P.S. I am trying to make this work so that I can use it later on to apply this method to my linux daemon program.
fd=open("/test.txt",O_CREAT|O_RDWR|O_TRUNC,0777);
In this line specify path correctly.(i.e) It is current working directory means, keep (dot) . before / like./test.txt
Related
I'm new to C programming and I'm trying to experiment with setting the permissions of a file to Read Only. I'm sure that I don't have the directives correct and when I try to compile I get the error on the line that #include <io.h> is on "fatal error: io.h no such file or directory". The file 'time.log' is in a directory called 'time_logs' and the program will run from the same directory that the directory 'time_logs' is in.
OS is Rasbian for Raspberry Pi 4 Arm Using GCC
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <io.h>
#include <sys.h>
struct stat st = {0};
int main(void){
if(_chmod("time_logs/time.log", _S_IREAD) == -1)
perror("Not found");
else{
_chmod("time_logs/time.log", _S_IREAD);
}
}
It looks like you used a Windows manual trying to code for Linux.
#include <unistd.h>
#include <sys/stat.h>
if(chmod("time_logs/time.log", S_IRUSR | S_IRGRP | S_IROTH) == -1)
perror("time_logs/time.log");
But most people just type the permission bits directly. This would be 0444. Adjust to taste.
Basically, this should be a simple piece of code that opens a directory stream and looks for symbolic links. Whenever a symbolic link is found, it should print ("Symbolic link found");
However, the lstat(dirp->d_name,&bufcall always returns a value < 0, and I don't know why.
I created the two symbolic link opening the file folder, opening a terminal window inside the folder and running
ln -s ciao.txt link1 and
ln -s ciao2.txt link2
I know I should call closedir() later in my code, please don't care about this.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
void main (int argc, char* argv[])
{
char buffer[100],dir[100];
struct stat buf;
int x;
DIR *dp;
struct dirent *dirp;
if((dp=opendir(argv[1]))==NULL)
{
printf("\nError opening directory stream, now exiting...\n");
exit(-1);
}
while((dirp=readdir(dp))!=NULL)
{
lstat(dirp->d_name,&buf);
if(S_ISLNK(buf.st_mode))
printf("\n%s Is a symbolic link\n",dirp->d_name);
else
printf("\n%s Is not a symbolic link\n",dirp->d_name);
}
}
Some help would be appreciated. Thanks.
d_name is the file name in the directory, not a full path name. You must eather chdir into the directory you are looking at, or construct full path names for the files.
The simplest solution is to add this line just before your while loop:
chdir(argv[1]);
I just want to write a program which takes a directory name as argument
Validate that it is in fact a directory
Get a listing of all files in the directory and print it
The word directory doesn't even appear in the C standard. This is an OS concept.
Look at stat. It will provide you with the information you want; all you have to do is interpret it.
Edit: A brief example.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int is_dir(char *path)
{
struct stat dir_stats;
stat(path, &dir_stats);
if (S_ISDIR(dir_stats.st_mode))
return TRUE;
return FALSE;
}
For the list of files in the directory, use readdir.
I was reading through this Advanced Linux Programming tutorial when I encountered a problem. I was trying to eject the CD-ROM drive using this code:
int fd = open(path_to_cdrom, O_RDONLY);
// Eject the CD-ROM drive
ioctl(fd, CDROMEJECT);
close(fd);
Then I try to compile this code and get the following output:
In file included from /usr/include/linux/cdrom.h:14,
from new.c:2:
/usr/include/asm/byteorder.h: In function ‘___arch__swab32’:
/usr/include/asm/byteorder.h:19: error: expected ‘)’ before ‘:’ token
/usr/include/asm/byteorder.h: In function ‘___arch__swab64’:
/usr/include/asm/byteorder.h:43: error: expected ‘)’ before ‘:’ token
So what am I doing wrong?
The error message you're seeing looks like something is wrong in your #include lines, not with the code you posted. I tried compiling http://www.advancedlinuxprogramming.com/listings/chapter-6/cdrom-eject.c and it compiles just fine.
According to this, you need to specify O_NONBLOCK when opening the device, otherwise it won't work.
From that page:
cdrom = open(CDDEVICE,O_RDONLY | O_NONBLOCK)
You are missing a #include, I think. Do you have:
#include <fcntl.h>
#include <linux/cdrom.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
Those are the ones in the example...
In the previous examples the following includes are not needed.
#include <sys/stat.h>
#include <sys/types.h>
Also as stated before you may need to open with O_NONBLOCK
You can find more options for interacting with the CDROM device in the header file located at '/usr/include/linux/cdrom.h' or here https://github.com/torvalds/linux/blob/master/include/uapi/linux/cdrom.h
Also here is another example for opening and closing the CD tray with the mentioned changes.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/cdrom.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main (int argc, char* argv[])
{
// Path to CD-ROM drive
char *dev = "/dev/dvd";
int fd = open(dev, O_RDONLY | O_NONBLOCK);
if(fd == -1){
printf("Failed to open '%s'\n", dev);
exit(1);
}
printf("fd :%d\n", fd);
// Eject the CD-ROM tray
ioctl (fd, CDROMEJECT);
sleep(2);
// Close the CD-ROM tray
ioctl (fd, CDROMCLOSETRAY);
close(fd);
return 0;
}
The open syscall has some unwanted behaviours which must be handled by setting it to Not blocking ie O_NONBLOCK
Also check that you have included the header file
#include <linux/cdrom.h>
I'm completely new to C and I use it very rarely. This time i need it for a university project. I have to write a small c app that tests some modifications we made on the Linux kernel (on the scheduler).
Inside the script I'd like to switch to another user to see the distribution of CPU times among the different users. So I start my small C prog with root rights (i.e. with sudo ./myapp). Inside the prog - after I performed some operations which need root rights - I would like to switch back to another uid by calling seteuid(1000) or setuid(1000) where 1000 is the ID of an existing user (the one I used to log on). However the call doesn't seem to have any effect, it doesn't throw any exception neither.
Here's a sample I wrote, just to test the uid switching:
#define _POSIX_SOURCE
#include <pwd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <unistd.h>
#include <string>
#include <time.h>
using namespace std;
int main(int argc, char *argv[])
{
int uid;
struct passwd *p;
if ((p = getpwuid(uid = getuid())) == NULL){
perror("getpwuid() error");
exit(1);
}
printf("***************************************\n");
printf("Executing user: %s (%d)\n", p->pw_name, p->pw_uid);
printf("***************************************\n");
seteuid(1000);
if ((p = getpwuid(uid = getuid())) == NULL){
perror("getpwuid() error");
exit(1);
}
printf("***************************************\n");
printf("Executing user: %s (%d)\n", p->pw_name, p->pw_uid);
printf("***************************************\n");
return 0;
}
Does anyone know why it won't work?? Any help is highly appreciated! Thx
//Edit:
Corrected code as mentioned by chsh
I think it is working just fine, there's just a problem with the logic in the code because you're capturing the value of getuid() into the passwd struct, and then just displaying it twice without retrieving it again after calling seteuid().