Without using remove() function How to delete a file in C program - c

I am trying to delete a file in c program. Assume that the file is located in current directory of source file. I have searched a lot but didn't get any solution. Everyone is suggesting to use remove() function.
Here is my source code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
int delete_status;
char del[50];
printf("Enter a file name to delete it: ");
gets(del);
delete_status = remove(del);
if(delete_status!=0) {
printf("File can not be deleted!\nFile does not exist in current directory\n");
}
else printf("File %s has been deleted successfully!\n", del);
return 0;
}
Is there any way to remove file without using remove() function. I want to code manually without using any other stl built in function.

You can replace remove() with unlink() (for files) and rmdir() (for directories).

You can check this answer. You should try to read a system programming book where you can learn about uses like INTERNAL_SYSCALL.
You can skim through the functions referred in the posts like unlink() etc.
EDIT: actually somehow you will end up using a system-call at some level. You probably trying to achieve the operation of deleting a file from different abstraction level.(remove() system call will also use INTERNAL_SYSCALL which nothing but a system call).
Now from low level deleting a file doesn't mean we are erasing something. We are just considering the space as free space(free pool of memory) and then any metadata related to that file is also freed. To achieve that you need to implement a filesystem that allocates memory,deletes it..using device level instructions.

Call unlink for files, rmdir for directories. You could easily check which a file is using stat and then call the correct function.
struct stat sb;
if (!stat(filename, &sb))
{
if (S_ISDIR(sb.st_mode))
rmdir(filename);
else
unlink(filename);
}
Include <sys/stat.h> for stat and S_ISDIR, <unistd.h> for rmdir and unlink.
Oh, and per your comment:
All of you didn't understand my needs and requirement. I know that it is posible to delete a file using standard library function like remove(), unlink(), rm() etc. But I want to code manually without using any built in function.
Have fun reproducing unlink's source code.

I think what you need to know is unlink() function. For deleting files, remove() internally calls unlink() itself. Check the man page for details.
However, first I suggest you to change the gets() with fgets(). Also, int main() should be int main(void).

One can use fork and exec to run the rm command over shell.
sample code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
int status;
pid_t pid = fork();
if(-1 == pid){
printf("fork() failed");
exit(EXIT_FAILURE);
}else if(pid == 0){
execl("/bin/sh", "sh", "-c", "rm /tmp/sandeep_reve.txt", (char *) NULL);
}else{
printf("Fork with id %ld\n",(long)pid);
waitpid(pid,&status,0);
}
return 0;
}

Use system():
PART I:(Delete file)
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
int delete_status;
char path[100],order[]="del ";//del for delete file, if change del to rd is delete folder(**Code at part 2)
printf("Enter a path of file to delete it: ");
gets(path);
strcat(order,path);//Order
fp = fopen(path,"r");
if(fp != NULL){//Check file whether or not exist
fclose(fp);
system(order);//Del file
printf("Delete successfully");
}else{
perror("ERROR");
fclose(fp);
}
return 0;
}
For example, you want to delete 1.txt.Then, you may put the c program in the same file and then intput 1.txt or enter whole path of the file.(e.g C:\User\desktop\1.txt)
PART II :(Delete folder)
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
int delete_status,i = 1;
char path[100],order[] = "rd ";//del -> rd
printf("Enter a path of file to delete it: ");
gets(path);
strcat(order,path);
system(order);
return 0;
}

Related

usage of tmpfile() in C

I don't understand why my script below seems to work without creating any files.
script.c:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]){
printf("P_tmpdir is '%s'\n", P_tmpdir);
FILE *tmp = tmpfile();
if(tmp == NULL){
printf("Unable to create temp file");
exit(1);
}
else{
printf("Temporary file is created\n");
}
for(int i = 0; string[i] != '\0'){
fputc(string[i], tmp);
}
rewind(tmp);
while(!feof(tmp)){
putchar(fgetc(tmp));
}
sleep(3);
return(0);
}
The P_tmpdir variable returns me the "/tmp" directory although in the sleeping time no new file is created in it... can you help me or explain me plz ?
Quoting cppreference.com (emphasis mine):
On some implementations (e.g. Linux), this function actually creates, opens, and immediately deletes the file from the file system: as long as an open file descriptor to a deleted file is held by a program, the file exists, but since it was deleted, its name does not appear in any directory, so that no other process can open it.
The file does not have to be "visible" in the file system tree, as long as a process has a handle on it, the file continues to exist.
If you want a file that's visible in the file system tree you should use mkstemp.

Linux/ Open directory as a file

I've been reading Brian Kernighan and Dennis Ritchie - The C Programming Language and chapter 8.6 is about directory listing under UNIX OS. They say that everything and even directory is a file. This means that I should be able to open directory as a file? I've tried it using stdio functions and it didn't work. Now, I'm trying it with UNIX system functions. Of course, I'm not using UNIX, I'm using Ubuntu linux. Here is my code:
#include <syscall.h>
#include <fcntl.h>
int main(int argn, char* argv[]) {
int fd;
if (argn!=1) fd=open(argv[1],O_RDONLY,0);
else fd=open(".",O_RDONLY,0);
if (fd==-1) return -1;
char buf[1024];
int n;
while ((n=read(fd,buf,1024))>0)
write(1,buf,n);
close (fd);
return 0;
}
This writes nothing even when argn is 1 (no parameters) and I'm trying to read current directory.
Any ideas/explanations? :)
Files are also called regular files to distinguish them from special files.
Directory or not a regular file. The most common special file is the directory. The layout of a directory file is defined by the filesystem used.
So use opendir to open diretory.
Nachiket's answer is correct (as indeed is sujin) but they don't clear up the mystery as to why open works and not read. Out of curiosity I made some changes to the given code to find out exactly what was going on.
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char* argv[]) {
int fd = -1;
if (argc!=1) fd=open(argv[1],O_RDONLY,0);
else fd=open(".",O_RDONLY,0);
if (fd < 0){
perror("file open");
printf("error on open = %d", errno);
return -1;
}
printf("file descriptor is %d\n", fd);
char buf[1024];
int n;
if ((n=read(fd,buf,1024))>0){
write(1,buf,n);
}
else {
printf("n = %d\n", n);
if (n < 0) {
printf("read failure %d\n", errno);
perror("cannot read");
}
}
close (fd);
return 0;
}
The result of compiling and running this:
file descriptor is 3
n = -1
read failure 21
cannot read: Is a directory
That settles it, though I'd have expected open to fail, since the correct system function for opening directories is opendir().
Though everything in unix is a file (directory also) but still filetype is concept is present in unix and applicable to all files.
there are file types like regular file,directory etc and certain operations and functions are allowed/present for every file type.
In your case readdir is applicable for reading contents of directory.
If you want to see the files in a directory you have to use the opendir and readdir functions.
K&R were correct for the original UNIX. I remember doing it back when UNIX file systems had a 14 character length limit for filenames. The opendir(), readdir(), ... stuff happened about the time that longer file names became common (around 1990?)

open a windows file directory for reading/writing in c

I'm trying to write the contents of a windows directory to a file using c. For example, if I had a directory of jpegs (i.e. a directory that contains multiple jpegs) and wanted to convert them to a .raw file, I have something like this:
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
typedef uint8_t BYTE;
#define BLOCK 512*sizeof(BYTE);
int main(void)
{
FILE * fd = fopen("C:\\jpegs", "r");
if (fd == NULL) {
fprintf(stderr, "Error opening device file.\n");
return EXIT_FAILURE;
}
int block = BLOCK;
FILE * fn = fopen("new.raw", "w+");
void * buff = malloc(block);
while(feof(fd) == 0) {
fread(buff,block,1,fd);
fwrite(buff,block,1,fn);
}
free(buff);
fclose(fd);
fclose(fn);
return 0;
}
The problem is I don't think windows directories are terminated with EOF. Does anyone have any ideas about how to solve this?
On Unix systems, although you can open a directory for reading, you can't really read from it unless you use the opendir(), readdir(), closedir() family of calls. You can't write to a directory on Unix; even superuser (root) can't do that. (The main reason for opening a directory, more usually with open() than fopen(), is so that you can use chdir() followed by fchdir() to get back to where you started, or use the various *at() functions, such as openat(), to reference the directory.)
On Windows, you'd at minimum need to use "rb" mode, but frankly, I'd not expect you to be able to do much with it. There are probably analogues to the Unix opendir() functions in the Windows API, and you should use those instead.

File I/O management in C

My first post :), am starting out with C language as basic learning step into programming arena. I am using following code which reads string from text file, makes directory with that string name and opens a file for writing in that created directory. But am not able to create a file inside directory made, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <string.h>
int main()
{
char file_name[25], cwd[100];
FILE *fp, *op;
fp = fopen("myfile.txt", "r");
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
fgets(file_name, 25, fp);
_mkdir(file_name);
if (_getcwd(cwd,sizeof(cwd)) != 0)
{
fprintf(stdout, "Your dir name: %s\\%s\n", cwd,file_name);
op = fopen("cwd\\file_name\\mynewfile.txt","w");
fclose(op);
}
fclose(fp);
return 0;
}
What you need is to store the file name (with the path) in a c-string before opening. What you are opening is cwd\file_name\mynewfile.txt. I doubt that your directory is named cwd.
A sample could could be:
char file_path[150];
sprintf(file_path, "%s\\%s\\mynewfile.txt", cwd, file_name);
op = fopen(file_path,"w");
use
#include <sys/stat.h>
#include <sys/types.h>
instead of
#include <direct.h>
and modify
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
I see you are using the return values. That is a good start for a beginner. You can refine your error messages by including "errno.h". Instead of printing your own error messages call
printf("%s", strerror(errno));
You get more precise error messages that way.
op = fopen("cwd\\file_name\\mynewfile.txt","w”);
You’re actually passing the string literals “cwd” and “file_name” as part of the path of the file, when I think you actually mean to put the contents of the variables with those names in there. You will probably have to piece together a string for the path. Try looking into strcat()
http://www.cplusplus.com/reference/cstring/strcat/

Trying to read in the files of a directory and write it to a list

I'm trying to create 5000 junk files, write them to a file and delete them. But this code only is writing a portion of the files to the file. ls -l | grep ^- | wc -l says I have 1598 files remaining in the directory that is supposed to be emptied with unlink();. If I remove close(fd) I get a seg fault if I do any more than 1000 files. Any suggestions?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
main (int argv, char *args[]){
if(argv<3){
printf("Please run with proper command line arguements.\n");
return;
}
int numFiles = atoi(args[1]);
char *fileName = args[2];
char *fileList[numFiles];
int x, ret,fd;
char buff[50];
for(x=0;x<numFiles;x++){
ret = sprintf(buff,"./stuff/%s-%d.junk",fileName, x);
fd = creat(buff);
close(fd);
}
DIR *odir = opendir("./stuff");
struct dirent *rdir = NULL;
FILE *fp;
fp = fopen("./files.list", "w");
x=0;
while(rdir = readdir(odir)){
char* name = rdir->d_name;
ret = sprintf(buff,"./stuff/%s-%d.junk",fileName, x);
if(strcmp(name,"..")!=0){
if(strcmp(name,".")!=0){
fprintf(fp,"%s %d\n",name,x);
x++;
}
}
unlink(buff);
}
close(fp);
closedir(odir);
}
Thanks!
Note: Use of creat(), opendir(), readdir() and unlink() were required for the assignment. And as for error checking, your right of course but I'm under time constraints and the TA really, really doesn't care... But thank you all!
Here you're using fopen:
FILE *fp;
fp = fopen("./files.list", "w");
But then you're using close instead of fclose to close it:
close(fp);
I'm not at all sure this is what's causing the problem you're seeing, but it's definitely wrong anyway. You probably just want unlink(rdir->d_name) instead of unlink(buff). You embedded the number into the file name when you created it -- you don't need to do it again when you're reading in the name of the file you created.
You're removing things from the directory while calling readdir; I think that's supposed to work OK, but you might want to consider avoiding it.
More to the point: as you iterate over the directory with readdir you're potentially removing different files from the ones readdir is listing. (Because what you pass to unlink is buff which you've filled in from the steadily-incrementing x rather than from anything returned by readdir.) So, here's a toy example to show why that's problematic. Suppose the directory contains files 1,2,3,4 and readdir lists them in the order 4,3,2,1.
readdir tells you about file 4. You delete file 1.
readdir tells you about file 3. You delete file 2.
readdir would have told you about file 2, but it's gone so it doesn't.
readdir would have told you about file 1, but it's gone so it doesn't.
You end up with files 3 and 4 still in the directory.

Resources