Is there a way I can rewrite the following code which reproduce the functionality of the grep command in linux, in less lines of code? Or is there something I can make to save some memory or yo make the code even more efficient?
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <error.h>
#include "ourhdr.h"
#define size 1024
int main(int argc, char **argv)
{
char fis[100],car[10],buff[size];
FILE *file;
if(argc!=3)
{
printf("Not all parameters were given <./a.out> <char> <numefisier>\n");
}
else
{
file=fopen(argv[2],"r");
if (file==NULL)
{
err_ret("Fisierul sursa nu exista %s", argv[2]);
exit(0);
}
strcpy(fis,argv[2]);
strcpy(car,argv[1]);
while((!feof(file)))
{
while(fgets(buff,size,file)!=NULL)
{
if(strstr(buff,car))
printf("%s \n",buff);
}
}
fclose(file);
}
return 0;
}
Related
I am trying to use 'FIFOs' and 'popen()' function for communication between multiple processes. Also, the first process is multithreaded for reading and writing operations.
Following is the C code for the processes:
P1 process (Q1.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
void* reader()
{
char string[64];
int rfd = open("FIFO",O_RDONLY);
while(1)
{
read(rfd,string,sizeof(string));
sleep(10);
printf("%s\n",string);
}
}
void* writer()
{
char string[64];
FILE *wfd = popen("./Q1_1","w");
int fd = fileno(wfd);
while(1)
{
scanf("%s",string);
write(fd,string,sizeof(string));
}
pclose(wfd);
}
int main()
{
if(mkfifo("FIFO",0666)==-1)
{
if(errno!=EEXIST)
{
return 1;
}
}
pthread_t r_thread,s_thread;
pthread_create(&r_thread,NULL,reader,NULL);
pthread_create(&s_thread,NULL,writer,NULL);
pthread_join(r_thread,NULL);
pthread_join(s_thread,NULL);
return 0;
}
P2 Process (Q1_1.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
int main()
{
FILE *fd = popen("./Q1_2","w");
char string[64];
int ffd = fileno(fd);
printf("P2Check");
while(1)
{
scanf("%s",string);
write(ffd,string,sizeof(string));
}
return 0;
}
P3 Process (Q1_2.c)
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
int main()
{
char string[64];
if(mkfifo("FIFO",0666)==-1)
{
if(errno!=EEXIST)
{
return 1;
}
}
int wfd = open("FIFO",O_WRONLY);
printf("P3Check");
while(1)
{
scanf("%s",string);
write(wfd,string,sizeof(string));
}
}
However, after executing process P1 and providing input, there is no output as if the process is stuck. I suspect there is some issue with the multithreading but not sure.
The following code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
int
main(int argc, char **argv)
{
char *p;
int shm_fd;
int error;
size_t len;
if ((shm_fd = shm_open("/somename", O_CREAT | O_RDWR, 0666)) < 0) {
perror("shm_open");
exit(1);
}
error = close(shm_fd);
if (error < 0) {
perror("close");
}
return 0;
}
Works fine on fedora22 x86_64, freebsd 10.2 x86_64. But it fails on OSX 10.10 with
close: Invalid argument
What is wrong with the call on OSX?
I have a problem i don't know how to solve in my code. I have to compress with gzip several arguments received form the command-line.
But i have to introduce in the command line the route and not the file. The sample i have prepared is working well but i'm indicating the name of the file and this is not correct.
Can you help me how to indicate the route and not the file? in the execlp. The route is argv[] but i don't know exactly how to build the sentence.
The code is:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int p,pid[p];
int fills;
int ret=0;
char msg[100];
int status;
char filename[30];
if (argc>1)
fills=atoi(argv[p]);
if (argc==1)
{
printf("Error");
exit(1);
}
// Creem N parĂ metres
for(p=1; p<argc; p++)
{
pid[p] = fork();
if (pid[p]<0)
error("Error");
if (pid[p]==0)
{
memset(filename,0,sizeof(filename));
snprintf(filename,30,"ex1a.c");
ret=execlp("gzip", "gzip", "-9", "-f", filename, NULL);
if (ret < 0)
{
exit(EXIT_FAILURE);
}
printf("Process %d created process %d compressed file %s \n",getppid(),getpid(),argv[p]);
exit(p);
}
else
wait(status);
}
exit(EXIT_SUCCESS);
}
I am looking for a peace of code to check if the argument I pass to my program is a directory or not. So far I found this:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct stat buf;
stat(argv[1],&buf);
exit(0);
}
But it does not really help me.
Use:
if(S_ISDIR(buf.st_mode))
printf(" Its a directoy\n");
else
printf("Its a file\n");
after stat(argv[1],&buf); call
I wrote a simple program to test lsetxattr() and lgetxattr() functions.
I just wanted to add an extended property to this file, and get the value again.
But I can't get the result as expected.
So what's the right way to use these two methods?
Thanks!
#define _GNU_SOURCE
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <time.h>
#include <unistd.h>
int main()
{
char *path = "/tmp/abc.txt";
FILE *file = fopen(path, "w");
int id = 101;
if (lsetxattr(path, "user.id", &id, sizeof(int), 0) < 0)
printf("lsetxattr wrong\n");
int result;
if (lgetxattr(path, "user.id", &result, sizeof(int)) != sizeof(int)) {
printf("lgetxattr wrong\n");
}
printf("%d\n", result);
return 0;
}
This is likely because your /tmp mount does not support extended attributes. Looking at the man page:
ENOTSUP
Extended attributes are not supported by the file system, or are
disabled, errno is set to ENOTSUP.
You can verify this by changing the path to be outside of that mount, such as in the current directory (assuming it's outside of that mount of course):
char *path = "abc.txt";
Assuming your other mounts do support extended attributes of course (this is more likely). If you have to do it on /tmp, then you'll have to look at some manuals to figure out how to enable it on /tmp (tmpfs).
Looks like both lsetxattr() and lgetxatter() return -1 by default:
#include <errno.h>
#include <sys/xattr.h>
ssize_t
lgetxattr (const char *__path, const char *__name,
void *__value, size_t __size)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (lgetxattr)
#include <stub-tag.h>
I found this on glibc's source code: lgetxattr.c and lsetxattr.c