0

For some reason if I do a second open, it compiles but when I try to run it, it does nothing like it's locked. It's missing a lot of other functions, because it's a work in progress for a school project. If I remove one of the open(), the program runs just fine.

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUFFER_SIZE 100

#define INPUT "/tmp/father"

int main(int argc, char **argv)
{

    int fds;

    int fd;

    char mode[BUFFER_SIZE];

    char buffer[BUFFER_SIZE];

    unlink(INPUT);

    mkfifo(INPUT, S_IRUSR | S_IWUSR);

    if(argc != 2)
    {
        fputs("Argumentos invalidos\n", stderr);

        exit(EXIT_FAILURE);
    }

    fd = open(argv[1], O_WRONLY);

    if(fd == -1)
    {
        fprintf(stderr, "\nCan't open pipe\n");

        exit(EXIT_FAILURE);
    }

    fds = open(INPUT, O_RDONLY);

    if(fds == -1)
    {
        fprintf(stderr, "\nCan't open pipe\n");

        exit(EXIT_FAILURE);
    }

    while(1)
    {
        fgets(buffer,BUFFER_SIZE,stdin);

        sscanf(buffer,"%s", mode);      

        write(fd,buffer,strlen(buffer));
    }
}
harpun
  • 4,022
  • 1
  • 36
  • 40
Yommere
  • 3
  • 1
  • 1
    Check the return value from `unlink()` and `mkfifo()`. Also, read this: http://stackoverflow.com/questions/8507810/why-does-my-program-hang-when-opening-a-mkfifo-ed-pipe and this: http://stackoverflow.com/questions/580013/how-do-i-perform-a-non-blocking-fopen-on-a-named-pipe-mkfifo?rq=1 – Andrew Henle Dec 04 '15 at 17:55
  • Are you trying to open the same file twice? That may not be possible especially since you've got a write-handle open. You need to close() the handle to the file first. – V Maharajh Dec 04 '15 at 18:01
  • On my other program I'm doing " int father = open("/tmp/father", O_WRONLY); " both /tmp/father and argv[1] are named pipes – Yommere Dec 04 '15 at 18:04
  • You said it does nothing like it's locked, but how far does it get? The `fgets(buffer, BUFFER_SIZE, stdin);` will block until a line has been read from standard input. The `write(fd, buffer, strlen(buffer));` will block if there is no room left in the FIFO. – Ian Abbott Dec 04 '15 at 18:27
  • Hopefully, your other program doesn't unlink and create "/tmp/father" as well! – Ian Abbott Dec 04 '15 at 18:28
  • It doesn't unlink and create father ! It unlinks and create "/tmp/par-shell-in" – Yommere Dec 04 '15 at 18:30
  • Look up the `perror` function. It prints out error messages, which are likely to be very helpful to you. – nategoose Dec 04 '15 at 20:20
  • the posted code manipulates the file system before checking the argc for a correct number of command line parameters. Strongly suggest checking the parameters first and if the count is correct, then manipulate the file system. – user3629249 Dec 05 '15 at 18:17
  • when calling system functions, especially those that access items that are not under the programs control, like opening a file or creating a fifo node, always check the returned value to assure the operation was successful. When an error indication is returned from a system function, immediately call `perror()` to write to stderr with the enclosed text And the associated system error message. – user3629249 Dec 05 '15 at 18:21
  • when checking the command line parameter count (argc), if the count is not correct, then call printf() with a `USAGE` statement and call `exit( EXIT_FAILURE );` – user3629249 Dec 05 '15 at 18:26
  • a write to a pipe will block until the read end is open'd – user3629249 Dec 05 '15 at 18:36

1 Answers1

0

Are you sure there's a problem? You are reading from stdin (the fgets at the bottom), and writing to the pipe. What you're missing is something reading from the pipe. So if in another terminal you type:

$ cat /tmp/father

then anything you type into your prog will appear there.

So, in one terminal I do:

$ ./test /tmp/father
line one
line two

And in the second terminal:

$ cat /tmp/father

and I see:

line one
line two

No?

P.S. You are doing sscanf to read from buffer and write to mode, then writing out the buffer string. Not that it matters, but you're not using mode.

gilez
  • 669
  • 3
  • 6
  • if(strcmp(mode,"stats") == 0) { read(fds,buff,BUFFER_SIZE); printf("%s\n",buff); } – Yommere Dec 04 '15 at 18:14
  • The argv[1] is /tmp/par-shell-in , created in another program. That other program creates the par-shell-in then redirects the stdin to that pipe. If it reads stats from that pipe (sent by the code above), writes to /tmp/father a string I need. – Yommere Dec 04 '15 at 18:19
  • 1
    So I'm confused about what you're attempting. You write to the file specified in `argv[1]`, which is descriptor `fd`. You read characters from `stdin`, and write them to `fd`. Descriptor `fds` is the read side of your pipe, which you don't do anything with. If you specify `argv[1]` as /tmp/father, then you're writing to the write side of the pipe (but nothing is reading it -- thus the `cat` works).... – gilez Dec 04 '15 at 20:06