StanM
StanM

Reputation: 869

Tee - mimicking program only writes the initial input to file, ignoring all sequential inputs

So I have a mytee program (with much much less functionality). Trying to learn how to work with pipes / children / etc

(1) I do pipe
(2) Create the file(s)
(3) fork
(4) the parent does scanf to get the text
(5) sends the text to the pipe
(6) child receives it and writes it to files

-> #4 should be a loop until the user writes '.'
-> #6 should continue writing new lines, but somewhere there is a breakdown.

Some of the things that I think it might be:
1. Something is wrong with my permissions (but O_APPEND is there, and not sure what else I would need)
2. there may be a problem in parent do while loop, where it should send the msg to the pipe (fd[1])
3. #6 where I strongly think my problem lies. After the initial write it doesn, continue writing. I am not sure if I need to somehow keep track of the size of bytes already written, but if that was the case I would expect the last message to be there not the first.

I'm pretty much at a loss right now

I run it using

   ./mytee test1

Code:

ret = pipe (fd);
  if (ret == -1)
  {
    perror ("pipe");
    return 1;
  }
  for (i=0;i<argc-1;i++) {
     if ((filefd[i] = open(argv[i+1], O_CREAT|O_TRUNC|O_WRONLY|O_APPEND, 0644)) < 0) {
                perror(argv[i]);        /* open failed */
                return 1;
     }
  }
  pid = fork();
  if (pid==0)     /* child */
  {
   int read_data;
   do {
     read_data = read(fd[0], buffer, sizeof(buffer));
     for(i=0;i<argc;i++) {
       write(filefd[i], buffer, read_data);
     }

   } while (read_data > 1);
  for (i=0; i<argc; i++)
    close(filefd[i]);
  return 0;
  }
  else {          /* parent */
    char msg[20];
    do{
      scanf("%s",msg);
      write(fd[1],msg,sizeof(msg));
    }while (strcmp(msg,".")!=0);
    while ((pid = wait(&status)) != -1)
       fprintf(stderr, "process %d exits with %d\n", pid, WEXITSTATUS(status));
    return 0;
  }

Adding Output:

$ ./a.out test1
qwe
asd
zxc
.
^C

It doesn't exit properly. I think the child is stuck in the loop And the contents of test1:

qwe

Upvotes: 0

Views: 105

Answers (2)

Mark Plotnick
Mark Plotnick

Reputation: 10271

Working through this with the OP, reportedly the problem was unconditionally writing all 20 bytes of msg instead of just the NUL-terminated string contained within it. Suggested minimal fix: change

scanf("%s",msg);
write(fd[1],msg,sizeof(msg));

to

scanf("%19s",msg);
write(fd[1],msg,strlen(msg));

Upvotes: 1

paddy
paddy

Reputation: 63481

I see a couple of issues, which could potentially cause that behaviour.

Firstly, your loop condition doesn't look right. Currently it will terminate if a single byte is read. Change it to this:

while (read_data > 0);

The other issue I see is that you're writing to more files than you opened. Make sure you loop to argc-1, not argc:

for (i=0; i<argc-1; i++)

Upvotes: 0

Related Questions