Creating a filesystem in C [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
I want to create a ext4 filesystem in C
For example, my C code currently runs
system("mkfs.ext4 /dev/sdc1")
The problem is using system is not recommended and we don't want to have mkfs.ext4 utility in the root file system.
I saw mke2fs.c file in e2fsprog package, Do we need to copy directly the code understanding the implementation or is there any better way of using some library

That command mkfs.ext4 formats a filesystem on a partition, it does not create a partition. If you need to format a filesystem, the best way to do it is to run the mkfs.ext4 tool. It's not a good idea to copy code from e2fsprogs into your own program.
Why don't you want to have the utility there in the filesystem? If you need to use a certain utility, it should be there.
The system call is potentially unsafe because it passes a string to the shell, and it's difficult to safely escape dynamic arguments to avoid the possibility of shell attacks. If you are using a fixed device or a limited set of devices, and not accepting user input for the device, it should be okay to use system.
If you want to avoid using system, you can do something similar with fork and exec. This does not use the shell, so it is safer. But the code is more complex. I included a safer reusable "systemv" function.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
char *mkfs_ext4_prog = "/sbin/mkfs.ext4";
int systemv(const char *pathname, char *const argv[])
{
int wstatus;
pid_t pid;
pid = fork();
if (pid == -1) {
perror("fork failed");
exit(EXIT_FAILURE);
} else if (pid == 0) {
execv(pathname, argv);
exit(EXIT_FAILURE);
}
if (waitpid(pid, &wstatus, 0) == -1) {
perror("waitpid");
}
if (WIFEXITED(wstatus)) {
return WEXITSTATUS(wstatus);
}
if (WIFSIGNALED(wstatus)) {
fprintf(stderr, "%s killed by signal %d\n", mkfs_ext4_prog, WTERMSIG(wstatus));
}
exit(EXIT_FAILURE);
}
int mkfs_ext4(char *device)
{
char *const argv[] = { mkfs_ext4_prog, "--", device, NULL };
return systemv(mkfs_ext4_prog, argv);
}
int main(void)
{
int status;
char *device;
device = "/dev/sdc1";
status = mkfs_ext4(device);
exit(status);
}

Related

merging two files with write and read in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I would like to merge two files using open and file descriptor. Moreover I would like to separate the content of the first file with - before writing the the content of the second file.
I did the following :
void merge (char* fileName, char *fileName1) {
int fd = open(fileName, O_RDWR);
char c;
while (read(fd, c, 1) > 0) {//going at the end of the first file
}
char next[] = "\n";
char charc[] = "-";
write (fd, next, strlen(next));
for (int i = 0; i < 80; i++) {
if (write (fd, charc, strlen(charc)) == -1) {
perror("error : ");
}
}
write (fd, next, strlen(next));
int fd1 = open(fileName1, O_RDWR);
while(read(fd1, &c, 1) > 0) {
write(fd, &c, sizeof(c));
}
close(fd1);
close(fd);
}
Is there a better way to write this code ? Moreover I have a little problem even if it works it seems like I don't have the right to read the new file. For example if I do cat newFile I have a permission denied.
Is there a better way to write this code ?
You are not handling errors of all calls. All of syscalls open, write, read and close return -1 on error and set errno and may do that at any time. EINTR could be handled.
going at the end of the first file open has O_APPEND flag mode that is used for appending data.
Copying one character at a time is very not optimal. With glibc standard library you could use BUFSIZ bytes at a time that is chosen for fast I/O output. You could make a copy of a big chunk size at a time that is a power of 2, like 2048 or 4096.
There is little reason to use file descriptors here - prefer to use standard FILE * handling, which would make your code portable and also buffer the data for faster I/O.
If you wish to create the file use O_CREAT and add the third argument to open that is the mask of permissions of new file.
On linux there is splice(2) system call that can be used to append data on kernel side for maximum efficiency.

How to create a FILE in Desktop, using c [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
How,and what libs I need to create and manipulate a FILE in the Desktop? using only C, not C# or C++.
I'm using Codeblocks, I using allegro, what means I can´t use windows.h lib, The program need to work in windows.
In Windows Vista or higher, use SHGetKnownFolderPath to find he path for desktop. You have to use Unicode functions to get the file path, use _wfopen_s. You can write ANSI to the file, but it is recommended to write UTF16 or to convert text to UTF8.
#include <stdio.h>
#include <Windows.h>
#include <Shlobj.h>
int main()
{
wchar_t *desktop;
if(S_OK == SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &desktop))
{
wprintf(L"Desktop path: %s\n", desktop);
wchar_t filename[MAX_PATH];
swprintf_s(filename, MAX_PATH, L"%s\\%s", desktop, L"file.txt");
wprintf(L"Filename path: %s\n", filename);
FILE *fp;
_wfopen_s(&fp, filename, L"w");
if(fp)
{
fprintf(fp, "Hello world\n");
fclose(fp);
}
else
{
wprintf(L"can't create file\n");
}
CoTaskMemFree(desktop);
}
return 0;
}
In Windows XP use SHGetSpecialFolderPath (deprecated)
#include <stdio.h>
#include <Windows.h>
#include <Shlobj.h>
int main()
{
wchar_t desktop[MAX_PATH];
if(SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_DESKTOP | CSIDL_FLAG_CREATE, NULL, 0, desktop)))
{
wprintf(L"desktop: %s\n", desktop);
wchar_t path[MAX_PATH];
swprintf(path, L"%s\\%s", desktop, L"filename.txt");
HANDLE handle = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle != INVALID_HANDLE_VALUE)
{
DWORD temp;
const char *buf = "hello world";
WriteFile(handle, buf, strlen(buf), &temp, NULL);
CloseHandle(handle);
}
else
{
printf("can't create file\n");
}
}
return 0;
}
Given that you are on Windows, you'd want to look at CreateFile and its associated functions.
The lifecycle of a file is as follows: You can create it (or, if it exists, open it) using CreateFile, and once it is created/opened, you can use the resulting file handle to manipulate it with ReadFile, WriteFile, and potentially DeleteFile. Once you're done, you need to close the handle with CloseHandle.
1 If you are using Unix or Unix-like system, you can call
system("touch ~/Desktop/FILE");
in your code, and you need to #include <stdlib.h>.
This calls the command "touch ~/Desktop/FILE". If you want to handle (read/write) the file after this, you have to call fopen with correct mode. But the 2nd method is much better if you want to write something into the file.
2 You can also use
For Unix or Unix-like operating systems:
FILE *file = fopen("~/Desktop/FILE", "w+")
For Windows:
FILE *file = fopen("C:\\Users\\YOUR_USER_NAME\\Desktop\\FILE", "w+")
(*Assumes you are using the default user folder location.)
This creates the file, and then you can read/write to the file after this. Be sure to used the correct mode. Here is a reference for fopen and modes. Remember to #include <stdlib.h>.

Convert shell script to C code using wrapper [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to execute a shell script when loading a .php in a web-server, I've already been struggling with this for a while so I will ask for help.
What I've tried so far is to make a wrapper as explained in this post: Execute root commands via PHP
But I couldn't really get it to work making the wrapper execute a shell script, even when the script worked when being executed from the console with root privileges.
So the only solution I could found is to convert the shell code to a C code using "system ("") as using system(" ")
I don't really know if it's possible, what the shell script used to do is check the PID of the process running in the port 12321 and then kill it.
The shell script alone worked, so I am asking if anyone knows if it's possible to convert to C, here is the shell script I want to convert:
#!/bin/sh
pid=$(/bin/fuser -n tcp 12321 | /usr/bin/awk '{print $1}');
/bin/kill -9 $pid;
And here is the wrapper.c being used, that used to execute the code above called in my machine (testversion.sh), but I don't know why, isn't working.
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
setuid (0);
system ("/bin/bash /var/www/html/scrip/debugport/testversion.sh");
return 0;
}
As this doesn't seem to work, someone got a way of executing it all in the C code?
Try this. This code would only be able to kill a process owned by the same user unless run as root.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#define PORT_TO_LOOK_FOR "12321"
#define DO_NOT_KILL_BELOW 2 /* I am just putting 2 here, you can increase this */
int main(void) {
FILE *fp;
char buf[11] = {0};
pid_t pid;
/* Open the command for reading. */
fp = popen("lsof -t -i tcp:" PORT_TO_LOOK_FOR, "r");
if (fp == NULL) {
printf("Could not run lsof.\n");
exit(1);
}
else {
fgets(buf, sizeof(buf)-1, fp);
pclose(fp);
pid = (pid_t)atoi(buf);
if( pid < 1) {
printf("Either no one is listening on port "
PORT_TO_LOOK_FOR " or u don't have the "
"necessary permission.\n" );
exit(1);
}
else if( pid < DO_NOT_KILL_BELOW ) {
printf("The PID we got was not safe to kill.\n");
exit(1);
}
if( kill(pid, SIGKILL) != 0 ) {
perror("kill");
}
}
return 0;
}

C Processes Programming [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm taking an Operating Systems class for university and we have an assignment as follows:
Write a program that can be used to create a child process.
The child process should create a file called “Listx.txt” and ask the user for data to write to it. The parent process should read the data from the file and display it on the screen.
Modify the program to make the parent read the file and display the contents five times. It should pause for 1 second between each display.
Modify the program to make the parent read the file and display the contents over and over again until the user sends SIGSTOP. It should pause for 1 second between each display.
And this is the code I've come up with:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
int main()
{
int x;
int y = 0;
pid_t pid = fork();
if (pid==0)
{
printf("Hi, i am the child\n");
int fd;
fd = open("listx.txt", O_RDWR |O_CREAT |O_TRUNC);
printf ("enter Number");
scanf("%d\n",x);
char wd [100];
ssize_t nr;
wd[0]=x;
nr = write (fd, wd, sizeof (wd));
}
else
printf(" I am the parent, the child is %d\n",pid);
{
int fd;
fd = open ("listx.txt", O_RDONLY);
if (fd == -1)
{
printf("file not opened \n");
}
else
{
printf("file found \n");
}
char wd[100];
ssize_t nr;
nr = read (fd, wd, sizeof (wd));
if (nr == -1)
{
printf("file not read \n");
}
else
{
while (y < 5){
printf("The file has %s \n",wd);
sleep(1);
}
}
return 0;
The program compiles (through GCC) but I think I have the logic wrong.
May you kindly assist with helping me solve this?
This:
scanf("%d\n",x);
char wd [100];
ssize_t nr;
wd[0]=x;
is rather wrong, in more ways than one:
You must pas &x to scanf(), since it can't store the value unless given an address. Instead you pass the current value of x, causing undefined behavior.
You assign the value of x into a single character, which is going to drop lots of bits. This is probably not what you want to do.
You use file descriptors even after detecting that they are not valid.
Please figure out how to maximize the diagnostics (warnings and errors) from your compiler, and observe what it says. Many of these problems will generate warnings. For GCC, this manual page is informative. Basically, start out by adding -Wall -Wpedantic -Wextra to your compiler invocation.
exit the child (_exit(0))
wait in the parent until child has finished (waitpid(2) et.al.)
Apart from scanf problems I see printf(" I am the parent, the child is %d\n",pid); that I suspect that you wanted inside the curly brackets.
Moreover you need to ensure that the child wrote before starting reading so the first instruction in the parent should be waitpid(pid,&status,0); that waits for the child termination (and indirectly for the file being written). Note that the fact that the code of the child is on top doesn't mean that it will executed as first (I think this is what the exercise wants to highlight).
Another thing that you should always do as a good programmer is closing your file after writing.

Anonymous stream in c

Can I make an anonymous stream in c? I don't want to create a new file on the file system, just have a stream that one function can fwrite to while the other can fread from it. Not c++, c.
Maybe You're looking for pipes.
Forward Your STDOUT to the pipe.
Then the other application would read from the pipe.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#define RDR 0
#define WTR 1
char ** parseargs(char *string);
int main(void){
char mode = 'r';
char prog[50] = "/bin/ps --version";
char **argv;
int p[2];
pid_t pid;
FILE *readpipe;
int pipein, pipeout;
char buf;
/* create the pipe */
if(pipe(p) != 0){
fprintf(stderr, "error: could not open pipe\n");
}
pipein = p[RDR];
pipeout = p[WTR];
if((pid = fork()) == (pid_t) 0){
close(pipein);
dup2(pipeout, 1);
close(pipeout);
if(execv(argv[0], argv) == -1){
fprintf(stderr, "error: failed to execute %s\n", argv[0]);
}
_exit(1);
}
close(pipeout);
readpipe = fdopen(pipein, &mode);
while(!feof(readpipe)){
if(1 == fread(&buf, sizeof(char), 1, readpipe)){
fprintf(stdout, "%c", buf);
}
}
return 0;
}
Yes, tmpfile() is one way to do it. However, I believe tmpfile() is frowned upon these days due to security concerns.
So, you should use mkstemp in POSIX or tmpfile_s in Windows instead of tmpfile().
These will all still create files in the filesystem, though. They're temporary in that they "go away" when the program exits.
Another option, which doesn't create a physical file is mmap().
Oops, just found it... maybe. tmpfile() returns a tmeporary FILE *
Is that the right way to do it?
If you're on Unix (or a similar OS), you want to read Beej's Guide to Unix Interprocess Communication (it's a good read no matter what your OS is).
Check it out at Beej's Guides.
In a rapid glance there I noticed a few things you could probably use with more or less work (and with the optional creation of a file/resource):
Pipes
FIFOs
Message Queues
Shared Memory Segments
Memory Mapped Files
Unix Sockets

Resources