/*
2.Modify the 1st problem and see whether when creating a file with large holes (hundreds of MB or GB) does the OS allocate space on the HDD for the holes in the file, too, or not. For this you can use the commands stat and df. Find out what value does a read operation return when reading from such a zone.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
char buf1[]=”LAB “;
char buf2[]=”OS Linux”;
int main( void)
{
int fd;
if ((fd=creat(“file.gol”, 0666)) < 0) {
perror(“Creation error”);
exit (1);
}
if (write(fd, buf1, sizeof(buf1)) < 0) {
perror(“Writing error”);
exit(2);
}
if (lseek(fd, 4096, SEEK_SET) < 0) {
perror(“Positioning error”);
exit(3);
}
if (write(fd, buf2, sizeof(buf2)) < 0) {
perror(“Writing error”);
exit(2);
}
}
/*
4.Write a program that reads the characters located to offset 0, 20, 40, 60 … in an existing text file and appends them to the end of the file. Print out the size of the file before and after all append operations.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main ()
{
int f;
f=open(“test”,O_RDWR);
int flag_read=0;
int lungime_fisier=lseek(f,0,SEEK_END);
char b;
if (f>0)
{
do
{
lseek(f,flag_read,SEEK_SET);
read(f,&b,1);
printf(“\n%d: citim {%c}”,flag_read,b);
lseek(f,0,SEEK_END);
write(f,&b,1);
flag_read+=20;
}
while (flag_read<lungime_fisier);
printf(“\nlungimea fiserului inaite %d si dupa %d”,lungime_fisier,lseek(f,0,SEEK_END));
close(f);
}
return 0;
}
/*
5.Using lseek system call, find out if you can read from and write to any position in a file opened for reading and writing with O_APPEND. Write a program that when you launch N times in the background, writes the ID of the current process in a file. Neither of the programs can continue their execution until all the processes haven’t written their ID in the file. In the end all processes should print out the ID of the following process. Consider N as a known value.
*/
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc,char** argv)
{
int N;
int fd,pid;
int dimi,dima;
printf(“test\n”);
sscanf(argv[0],”%d”,&N);
printf(“N=%d\n”,N);
sscanf(argv[1],”%d”,&fd) ;
printf(“fd=%d”,fd);
pid=getpid();
write(fd,&pid,sizeof(int));
printf(“procesul cu pidul %d si-a scris propriul pid in fisier\n”,pid);
sscanf(argv[2],”%d”,&dimi);
printf(“dimi=%d\n”,dimi);
dima=lseek(fd,0,SEEK_END);
printf(“dima=%d\n”,dima);
while(((dima-dimi)/sizeof(int))<N)
{
sleep(1);
dima=lseek(fd,0,SEEK_END);
}
lseek(fd,dimi,SEEK_SET);
int i=0;
int pidNext;
int val;
while(i<N)
{
read(fd,&val,sizeof(int));
if(val==pid)
{
read(fd,&pidNext,sizeof(int));
lseek(fd,dima,SEEK_SET);
write(fd,&pidNext,sizeof(int));
printf(“procesul cu pidul %d a scris in fisier pidul procesului urm=%d\n”,pid,pidNext);
exit(1);
}
i++;
}
}
/*
6.Write a program that would allow the user to insert a string (read from the standard input) into a file from a certain position. The program call should have the following format: insert file offset string.
*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
main( int argc, char *argv[])
{
char buf[100],buf2[100];
char c;
int fd;
int i,j;
int poz,nr,new_poz;
poz = atoi(argv[1]);
j=0;
if (argc != 3)
{
printf(“nu-s bine argumentele\n”);
exit(0);
}
if ((fd=open(argv[2],O_RDWR)) == -1)
{
printf(“Eroare la deschidere fisier”);
exit(1);
}
scanf(“%c”,&c);
i=0;
while(c != ‘.’)
{
buf[i]=c;
scanf(“%c”,&c);
i++;
}
lseek(fd,poz,SEEK_SET);
if ((nr = read(fd,&buf2,sizeof(buf2))) == -1)
{
printf(“Eroare la citire”);
exit(2);
}
lseek(fd,poz,SEEK_SET);
if (write(fd,&buf,i) == -1)
{
printf(“Eroare la scriere”);
exit(3);
}
new_poz=poz+i;
lseek(fd,new_poz,SEEK_SET);
if (write(fd,&buf2,nr) == -1)
{
printf(“Eroare la scriere”);
exit(4);
}
}
/*
7.Consider the program below. Assuming that the file temp exists and that the program is launched in the background explain the result of the following commands:
ls -l temp; df /home; a.out &
$ ls -l temp; df /home; # după terminarea progr.
$ df /home
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main( void)
{
if (open(“temp”, O_RDWR) < 0)
{
perror(“open”);
exit(1);
}
if (unlink(“temp”) < 0)
{
perror(“unlink”);
exit(2);
}
printf(“Unlink done!\n”);
sleep(15);
printf(“END.\n”);
exit(0);
}
/*
8.Write a C program that deletes a directory with all its subfolders. The name of the directory should be read from the command line.
*/
void DeleteDirectory(char *dirName)
{
DIR* directory;
struct dirent *dirEntry;
struct stat inode;
char name[100];
directory = opendir(dirName);
if (directory == 0)
{
printf(“\n***”);
perror(“Error opening the directory.”);
exit(1);
}
while( (dirEntry=readdir(directory)) != 0)
{
sprintf(name, “%s/%s”, dirName, dirEntry->d_name);
lstat(name, &inode);
if(S_ISDIR(inode.st_mode))
{
if(strcmp(dirEntry->d_name, “.”) && strcmp(dirEntry->d_name, “..”) )
{
DeleteDirectory(name);
rmdir(name);
}
}
else if(S_ISREG(inode.st_mode) || S_ISLNK(inode.st_mode))
unlink(name);
else;
}
}
int main(int argc, char **argv)
{
if(argc != 2)
{
printf(“USAGE: %s <directory_name>”, argv[0]);
exit(0);
}
DeleteDirectory(argv[1]);
rmdir(argv[1]);
}
/*
9.Write a program that deletes every 5th byte from a file, but without using a temporary file or allocating a buffer in the memory. For adjusting the size of the file you may use the truncate function.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int arg,char** fis)
{
int fd;
int n;
char buf[5];
int ni=0;
fd=open(fis[1],O_RDWR);
if(fd==-1)
{
printf(“Fisierul nu exista”);
exit(2);
}
do
{
if (ni!=0) lseek(fd,ni,SEEK_CUR);
n=read(fd,buf,5);
if (ni!=0)lseek(fd,-ni,SEEK_CUR);
printf(“\n buf:=%s”,buf);
lseek(fd,-5,SEEK_CUR);
printf(“\n scris=%d” , write(fd,&buf,4));
ni++;
}
while(n>=5);
close(fd);
}
/*
10.Write a C program that finds a file in a file-tree starting from a given directory. The name of the file for which we are searching for, as well as the name of the starting directory should be read from the command line. Optionally, the name of the file can be specified as a pattern using the ‘*’ character.
*/
#include<sys/types.h>
#include<dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
void functie(char*dir, char *file)
{
struct dirent* entit;
DIR* director;
director=opendir(dir);
char temp[100];
struct stat statbuf;
printf(“Caut in: %s\n”,dir);
if (director!=0)
{
while ((entit=readdir(director))!=0)
{
strcpy(temp,”");
strcat(temp,dir);
strcat(temp,”/”);
strcat(temp,entit->d_name);
if ((strcmp(entit->d_name,”.”)!=0)&&(strcmp(entit->d_name,”..”)!=0))
functie(temp,file);
}
closedir(director);
}
else
{
lstat(dir,&statbuf);
if (S_ISREG(statbuf.st_mode) && strcmp(basename(dir),file) == 0)
{
int f1 = open(file,O_RDONLY);
int f2 = open(dir,O_RDONLY);
printf(“%d %d”, lseek(f1,0,SEEK_END), lseek(f2,0,SEEK_END));
if( lseek(f1,0,SEEK_END) == lseek(f2,0,SEEK_END) )
printf(“Am gast fisier: %s\n”, dir);
}
}
}
int main(int argc, char*argv[])
{
functie(argv[1], argv[2]);
return 0;
}
/*
11.Write a C program similar to the previous one, but this time try to find a string in the files.
*/
#include<sys/types.h>
#include<dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
void functie(char*dir, char *string)
{
struct dirent* entit;
DIR* director;
director=opendir(dir);
char temp[100];
struct stat statbuf;
printf(“Caut in: %s\n”,dir);
if (director!=0)
{
while ((entit=readdir(director))!=0)
{
strcpy(temp,”");
strcat(temp,dir);
strcat(temp,”/”);
strcat(temp,entit->d_name);
if ((strcmp(entit->d_name,”.”)!=0)&&(strcmp(entit->d_name,”..”)!=0))
functie(temp,string);
}
closedir(director);
}
else
{
lstat(dir,&statbuf);
if (S_ISREG(statbuf.st_mode) )
{
int f2 = open(dir,O_RDONLY);
int poz = 0;
int len = strlen(string);
char buf[512];
while(read(f2,buf,len) > 0)
{
if(strcmp(buf,string) == 0 )
{
printf(“Am gast in: %s\n”,dir);
break;
}
poz++;
lseek(f2,poz,SEEK_SET);
}
}
}
}
int main(int argc, char*argv[])
{
functie(argv[1], argv[2]);
return 0;
}
/*
12.Write a program having the name move, similar with the Linux command mv. The user should be able to call the program in any of the following ways:
move numeFisOld numeFisNew
move numeFis numeDir
move numeDirOld numeDirNew
*/
#include<sys/types.h>
#include<dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
int main(int argc, char*argv[])
{
execlp(“cp”,”cp”,”-rf”,argv[1],argv[2],0);
execlp(“rm”,”rm”,”-rf”,argv[1],0);
return 0;
}
/*
13.Write a program that would allow traversing a file-tree printing out the type, size and access rights for of the found files. The name of the starting directory should be read from the command line. Observation: be attentive to the symbolic links.
*/
#include<sys/types.h>
#include<dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
void functie(char*dir, char *file)
{
struct dirent* entit;
DIR* director;
director=opendir(dir);
char temp[100];
struct stat statbuf;
if (director!=0)
{
while ((entit=readdir(director))!=0)
{
strcpy(temp,”");
strcat(temp,dir);
strcat(temp,”/”);
strcat(temp,entit->d_name);
if ((strcmp(entit->d_name,”.”)!=0)&&(strcmp(entit->d_name,”..”)!=0))
{
printf(“%s is a directory\n”,entit->d_name);
functie(temp,file);
}
}
closedir(director);
}
else
{
lstat(dir,&statbuf);
if (S_ISREG(statbuf.st_mode))
{
printf(“%s is a regular file, the size of which is %d and has the rights: \n”, dir, statbuf.st_size);
}
else if (s_ISLNK(statbuf.st_mode))
{
printf(“%s is a symbolic link\n”, dir);
}
}
}
int main(int argc, char*argv[])
{
functie(argv[1], argv[2]);
return 0;
}
/*
14. A binary file fil.bin contains integers. Calculate the arithmetic mean of each group of numbers that are situated between two 0s in the file. Write these obtained values on distinct lines in the file means.txt. The beginning and the end of the file plays the role of a 0, except the case when the first and last element of the file is 0.
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int N;
int fisBin, n, nrsRead[1000];
void media(int N);
void generateNrs(int N);
FILE *fout;
int main()
{
if ((fisBin=creat(“fis.bin”, 0666)) < 0) {
perror(“Error creating destination file”);
exit(2);
}
N = rand()%1000;
generateNrs(N);
media(N);
}
void media(int N)
{
if ((fisBin=open(“fis.bin”, O_RDWR)) < 0) {
perror(“Error opening source file”);
exit(1);
}
printf(“Media %d”);
int i,n=0,nr = 0;
for (i=0; i<N; i++)
{
if ((n = read(fisBin, &nr, sizeof(int))) < 0)
{
perror(“Error reading file”);
exit(4);
}
else
{
nrsRead[i] = nr;
}
}
close(fisBin);
// calcul
if ((fout = fopen(“fout.txt”,”w”))<0)
{
perror(“Error opening source file”);
exit(1);
}
int sumap = 0, nr_citite = 0, med = 0;
for (i=0; i<N; i++)
{
if ((nrsRead[i] == 0) || (i==N-1))
{
med = sumap/nr_citite;
sumap = 0;
nr_citite = 0;
if ((n=fprintf(fout, “Media %d \n”, med)) < 0)
{
perror(“Error writing destination file”);
exit(4);
}
}
else
{
if ((n=fprintf(fout, ” %d “, nrsRead[i])) < 0)
{
perror(“Error writing destination file”);
exit(4);
}
sumap += nrsRead[i];
nr_citite++;
}
}
}
void generateNrs(int N)
{
if ((fisBin=open(“fis.bin”, O_RDWR)) < 0) {
perror(“Error opening source file”);
exit(1);
}
int i =0,nr;
for (i=0; i<N; i++)
{
nr = rand()%100;
if ((n=write(fisBin, &nr, sizeof(int))) < 0)
{
perror(“Error writing destination file”);
exit(4);
}
else printf(” %d “,nr);
}
printf(“N = %d\n”, N);
close(fisBin);
}
/*
3.Write a C program that writes the lines of a file into another file, but in the reverse order. The names of the files should be read as input parameters.
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
char **linii;
int nr_linii=0,i;
long lungime_fisier;
FILE *f;
if(argc!=2)
{
printf(“Sintax: %s <filename>\n”,argv[0]);
return 1;
}
if((f=fopen(argv[1],”r”))==NULL)
{
printf(“Error opening the file: <%s>\n”,argv[1]);
return 1;
}
fseek(f,0,SEEK_END);
lungime_fisier=ftell(f);
fseek(f,0,SEEK_SET);
linii=(char **)malloc((nr_linii+1)*sizeof(char *));
while(lungime_fisier>ftell(f))
{
linii[nr_linii]=(char *)malloc(1000 * sizeof(char));
fgets(linii[nr_linii],1000,f);
nr_linii++;
linii=(char **)realloc(linii,(nr_linii+1)*sizeof(char *));
}
for(i=nr_linii-1;i>=0;i–)
{
printf(“%s”,linii[i]);
}
fclose(f);
return 0;
}
/*15.A binary file fil.bin contains numbers and characters in the following way: 2 integers followed by a character from the set {+,-,*,/}. Write a C program that reads a group of numbers and the attached character and performs the operation on the two integers and then writes the result in a file res.txt in the form:
nr1 operator nr2 = result
The result line should be appended to the end of the file. The number of groups in the binary file should be specified in the command line as an input parameter.
*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
typedef struct operatie
{
float f1, f2;
char op;
}Op;
int main(int argc, char** argv)
{
int fd, fw;
Op s;
char c;
char buf[8] = “”;
char b[512] = “”;
int i = 0;
if (argc != 3)
{
printf(“UTILIZARE: %s limita1 limita2″, argv[0]);
exit(0);
}
if ((fd = open(“fis.bin”, O_RDONLY)) == -1)
{
perror(“Eroare la deschidere!\n”);
exit(1);
}
if (creat(“rez.txt”, 0666) < 0)
{
perror(“Eroare creare fisier!\n”);
exit(2);
}
if ((fw = open(“rez.txt”, O_WRONLY)) < 0)
{
perror(“Eroare deschidere fisier de iesire!\n”);
exit(3);
}
int nr = 1; //nr de grupuri
while (read(fd, &c, sizeof(char)) > 0)
{
if (c == ‘ ‘)
{
if (i == 0)
s.f1 = atof(buf);
else
s.f2 = atof(buf);
i++;
strcpy(buf, “”);
}
else
if (c == ‘+’ || c == ‘-’ || c == ‘*’ || c == ‘/’)
{
s.op = c;
if (nr >= atoi(argv[1]) && nr <= atoi(argv[2]))
{
//printf(“\ns.f1 = %f\ns.f2 = %f\ns.op = %c\n”, s.f1, s.f2, s.op);
float interm;
if (s.op == ‘+’)
interm = s.f1 + s.f2;
else
if (s.op == ‘-’)
interm = s.f1 – s.f2;
else
if (s.op == ‘*’)
interm = s.f1 * s.f2;
else
interm = s.f1/s.f2;
sprintf(b, “%s%f %c %f = %f\n”, &b, s.f1, s.op, s.f2, interm);
}
}
else
if (c == ‘\n’)
{
i = 0;
strcpy(buf, “”);
nr++;
}
else
sprintf(buf, “%s%c”, &buf, c);
}
if (write(fw, &b, sizeof(b)) < 0)
{
perror(“Eroare de scriere la iesire!\n”);
exit(4);
}
close(fd);
close(fw);
}