grep exec on a File Content in C - c

I am trying to apply the grep on file content using excel. But, it is not working. I am stuck on it. I don't know how to get the content of the file in the exec call.
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main() {
int link[2];
pid_t pid;
char foo[4096];
if (pipe(link)==-1)
die("pipe");
if ((pid = fork()) == -1)
die("fork");
if(pid == 0) {
const char *input = "output1.txt";
int fd = open(input, O_RDONLY);
dup2(fd, 0);
execl("grep", "grep" ,"com", NULL);
close(fd);
exit(1);
} else {
}
return 0;
}
The output1.txt is shown below:
c1.txt
c1.txt~
commands1
commands1~
commandSample1.txt
commandSample1.txt~
commandSample2.txt
foo.txt
output1.txt
output2.txt
text.txt
text.txt~
Suggestions would be great.

The first argument for execl must be a full path. Or you can use execlp instead.

Related

Named pipe (FIFO) halts execution when read and write are called

Trying to create a process ring using named pipes for an assignment, and whenever I call read/write to those files it pauses the execution at that point. I've tried everything I could find for hours now, and have no idea why this is happening.
More context: Process ring with named pipes, passing a token between n processes, from a process i to i+1 in each loop.
Any help would be very much appreciated, and thank you for taking the time!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#define MAX 50
int main(int argc, char** argv) {
// File descriptors for pipes i and i+1 and token
int fd1, fd2, token = 0;
pid_t pid;
// Pipes path array
char* fifos[2][MAX] = { "pipe1to2" , "pipe2to1" }
...
// Create pipes
for(int i =0 ; i < 2 ; i++){
char* fileToCreate = fifos[i];
if ((mkfifo(fileToCreate,S_IRWXU)) != 0) {
if(errno == 17){ // If a file with the same name exists, this overwrites it
unlink(fileToCreate);
mkfifo(fileToCreate,S_IRWXU);
}else{
printf("Unable to create a fifo; errno=%d\n",errno);
exit(1);
}
}
}
while(true){
char* file = fifos[itr];
fd1 = open(file,O_WRONLY);
if(fd1 == -1){
printf("Open error\n");
return 1;
}
if(write(fd1,token,sizeof(int)) == -1){
printf("Write error");
return 2;
}
close(fd1);
...
}
}

How to communicate from children process(exec) with parent through pipe()?

I have these two files and i call exec.c from main.c using exec(). As far as I understand exec.c should inherit the pipe but it says there is no link pipe in exec.c. What is the problem here?
main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define die(e) \
do \
{ \
fprintf(stderr, "%s\n", e); \
exit(EXIT_FAILURE); \
} while (0);
int main(int argc, char *argv[])
{
int link[2];
pid_t pid;
char foo[4096];
if (pipe(link) == -1)
die("pipe");
if ((pid = fork()) == -1)
die("fork");
if (pid == 0)
{
dup2(link[1], STDOUT_FILENO);
close(link[0]);
close(link[1]);
execvp("./exec", argv);
die("execl");
}
else
{
close(link[1]);
int nbytes = read(link[0], foo, sizeof(foo));
printf("Output: (%.*s)\n", nbytes, foo);
wait(NULL);
}
return 0;
}
exec.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
int main(int argc, char *argv[])
{
char a;
a='A';
write(link[1],&a,sizeof(a));
return 0;
}
I am just practicing and want to output the data that is save from pipe()
What I am doing wrong, can you help me to debug?
TIA!
In the main.c program you connect the pipe through standard output of the child process.
That means the child process passes information to the parent process through its normal standard output.
From this follows that the exec.c program could be as simple as this:
#include <stdio.h>
int main(void)
{
printf("A");
}
More specifically, your exec.c Source file doesn't have any idea of the pipe, and definitely not about the variable link, and will simply fail to build.

C named pipe does not work with multiprocess

I would like to create a named pipe in the parent process and after write a string to it in the child process and finally read this string in the parent process. When run the program I dont get back the prompt like still waiting for end of child process. Why the child process not finished?
Current output:
Expected output:
(picture created without multiprocesses)
My source code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
int main() {
int pipefd[2];
pid_t cpid;
char szoveg[32];
int fd, ret;
char buf[32];
buf[0]=0;
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(-1);
}
if (cpid == 0) {
printf("%d: Child process\n",getpid());
strcpy(buf,"Some text \0");
printf("%d:write to fifo: %s:%ld\n",getpid(),buf,strlen(buf));
write(fd,buf,strlen(buf));
exit(0);
} else {
printf("%d: Parent process\n",getpid());
ret=mkfifo("FifoName",00666);
if (ret == -1) {
perror("mkfifo()");
exit(-1);
}
fd=open("FifoName",O_RDWR);
if (fd == -1) {
perror("open() error!");
exit(-1);
}
wait(NULL);
ret=read(fd,buf,32);
printf("%d:read() Read %d bytes: %s\n",getpid(),ret,buf);
close(fd);
unlink("FifoName");
exit(0);
}
}
William Pursell right. The problem was the missing fd=open("FifoName",O_RDWR); line from child process.

how to use execlp() with redirected output

i tried to write c program in Unix environment that using execlp function.
the command is:
execlp("tsort","tsort","text.txt",">","1.txt",(char *)NULL);
syserr("execlp");
i am always gets the same error.
the error is:
tsort: extra operand `>'
what did i do wrong?
'>' is not a parameter, it is normally interpreted by a shell. If you want to achieve the same effect in C code, you have to do the same thing the shell normally does:
open a file (1.txt) for writing
fork() a new process
[in child] replace the stdout of the new process with the file's descriptor using dup2()
[in child] exec the command
Simplified example code for POSIX:
#define _POSIX_C_SOURCE 200101L
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int outfd = open("1.txt", O_CREAT|O_WRONLY|O_TRUNC, 0644);
if (!outfd)
{
perror("open");
return EXIT_FAILURE;
}
pid_t pid = fork();
if (pid < 0)
{
close(outfd);
perror("fork");
return EXIT_FAILURE;
}
if (pid)
{
// child code
dup2(outfd, 1); // replace stdout
close(outfd);
// just a "useless cat" for simplicity:
execlp("cat", "cat", "redir.c", 0);
}
else
{
// parent code
close(outfd);
int status;
waitpid(pid, &status, 0);
if (WIFEXITED(status)) return WEXITSTATUS(status);
else return EXIT_FAILURE;
}
}
As per the comment: If you don't mind replacing your process with the called program, you don't even need to fork and the program becomes very short:
#define _POSIX_C_SOURCE 200101L
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int outfd = open("1.txt", O_CREAT|O_WRONLY|O_TRUNC, 0644);
if (!outfd)
{
perror("open");
return EXIT_FAILURE;
}
dup2(outfd, 1); // replace stdout
close(outfd);
execlp("cat", "cat", "redir.c", 0);
}
This of course is not what an interactive shell does.

how to end redirected execlp in c

I try to redirect the exec function input, output result with pipe. This code works fine, however I can't exit the execlp function below, which always require new input, however I just want run it one time. How can stop it after first input.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)
int main(int argc, char *argv[])
{
int chi_pipe[2], par_pipe[2];
if (pipe(chi_pipe) == -1 || pipe(par_pipe) == -1)
ERR_EXIT("pipe error");
pid_t pid;
pid = fork();
if (pid == -1)
ERR_EXIT("fork error");
if (pid == 0)
{
close(chi_pipe[0]); // I don't read in channel 1
close(par_pipe[1]); // I don't write in channel 2
close(STDIN_FILENO);
dup(par_pipe[0]);
execlp("tr", "tr", "/a-z/", "/A-Z/", NULL);
close(chi_pipe[1]);
close(par_pipe[0]);
_exit(0);
}
close(par_pipe[0]);
close(chi_pipe[1]);
write(par_pipe[1], "haha\n", 5);
char buf[3024] = {0};
read(chi_pipe[0], buf, 1024*3);
printf("buf=%s", buf);
printf("\n");
close(par_pipe[1]);
close(chi_pipe[0]);
return 0;
}
I think you want this.
move the close up so the read can know that it won't get any more.
write(par_pipe[1], "haha\n", 5);
close(par_pipe[1]);
you seem to missing a dup for stdout in the child segment too,

Resources