Author Topic: Pwn needs help in C  (Read 2727 times)

Offline Pwnator

  • *
  • Posts: 6676
  • Rep: 15
  • Awards BOTM Winner
    • View Profile
    • http://pwnator.tumblr.com
    • Awards
  • See profile for gamer tags: Yes
Pwn needs help in C
« on: August 31, 2011, 07:09:16 AM »
On my way to create a two-way chat program using FIFOs, but unfortunately I can't even get my test program to work. >.<


Code: [Select]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
/*A lot of excess headers because I'm supposed to add more functions, but that's for later*/

int main(void){
   char buffer[128];
   int fifofd;
   char fifoname[] = "chatfifo";
   int ret;


   ret = mkfifo(fifoname, S_IRUSR | S_IWUSR);


   if(ret<0){
      printf("'chatfifo' already exists.\nThis is the FIFO reader.\n");
      fifofd = open(fifoname, O_RDONLY | O_NONBLOCK);
      do {
         read(fifofd, buffer, sizeof(buffer));
         printf("Message retrieved> %s", buffer);
      } while (strcmp(buffer,"exit\n")!=0);
      close(fifofd);
      unlink(fifoname);
   }
   else{
      printf("'chatfifo' created.\nThis is the FIFO writer.\n");
      fifofd = open(fifoname, O_WRONLY | O_NONBLOCK);
      printf("Type in 'exit' to quit:\n");
      do {
         printf("Enter message to send> ");
         fgets(buffer, sizeof(buffer), stdin);
         write(fifofd, buffer, strlen(buffer)+1 );
      } while (strcmp(buffer,"exit\n")!=0);
      close(fifofd);
   }


   return 0;
}


The program should be able to run on two separate tabs/windows and should perform different tasks (one to write and the other to read). The do-while loop for the read() part just goes on in an infinite loop, which led me to a conclusion that read() returns a value of 0.


Now I have no idea where I went wrong - the 'if' block or the 'else' block. >.<
Clash Cubes 1 - Grey Matter (Runner-Up)
King of Karnage - Sideshow Freak (Runner-Up, Best Engineered)
Rust In Pieces - Paper Cut 3 (Grand Champion, Most Dangerous Bot)
Wheely Tag Tournament - Ion Thruster (Grand Champion, along with Ounces' DiSemboweLment)
UK vs USA - Dark Striker (Grand Champion)
Rust In Pieces 2 - Claymore (Runner-Up, Favourite Bot)
BBEANS 6 - Infection 4 (Runner-Up)
RA2 Team Championships - Serious Business, Skeksis (Runner-Up, along with Scrappy, S_M, and Badnik)
RA2 Team Championships 2 - The Other Stig (Runner-Up, along with Scrappy, S_M, Badnik, 090901, and R1885)
Replica Wars 3 - Abaddon (Runner-Up, Luckiest Bot)
BroBots - wheebot & yaybot (Runner-Up)
Robo Zone 2 - Dipper (4th place, Survival Champion, & Best Axle Bot)
ARBBC - The Covenant (3rd place, BW Rumble Winner, Most Feared BW)

Offline Serge

  • *
  • Posts: 1530
  • Rep: 13
    • View Profile
    • http://www.q3k.org/
    • Awards
Re: Pwn needs help in C
« Reply #1 on: August 31, 2011, 08:09:02 AM »
You need to disable the O_NONBLOCK flag on both the reader. Otherwise, read() won't block until it receives data, the loop will keep running, and printing invalid data (since read() didn't receive any data, and so, no valid data was written to the buffer).

Code: [Select]
q3k@luna ~ $ ./pwn
'chatfifo' created.
This is the FIFO writer.
Type in 'exit' to quit:
Enter message to send> ffds
Enter message to send> I like turtles.
Enter message to send>

Code: [Select]
q3k@luna ~ $ ./pwn
'chatfifo' already exists.
This is the FIFO reader.
Message retrieved> ffds
Message retrieved> I like turtles.

EDIT: Another option, if you want to keep the asynchronous (=non-blocking) reading on the reader, you can refrain from printing data to the client unless read() returns > 0, which would mean some bytes were actually read, This way, the reader can still run on a loop, and do some other  processing in the meantime (printing the time, blinking a cursor, whatever). However, this can be more CPU intensive, as a infinite loop like this (=a polled loop) is very CPU intensive.
A good compromise between the two (something asynchronous, but not so CPU intensive) is to use the select() syscall (or some OS equivalent, kpoll on Linux, something on Windows I forgot - they are usually even fatser than select(), which is standarized). This syscall allows you to specify a bunch of file descriptors (be it open files, fifos, or even network sockets), and will block until one or more of these descriptors can be read from or written to. Here's the fun part: you can also specify for how long it will block! This allows you to write code that will block, for example, for 0.1 seconds (waiting for the fifo to have somedata), and then return. If it returned the file descriptor, it means some data was available on it - then you can read() it. If it returns 0, it means the block time has expired, and no data was read from the fifo. After you either handle or not the descriptor, you can do whatever more processing you want, and then loop back to the select() call.

Of course, all of this is unnecessary if you can live with having a blocked loop :P.
home | twitter | yt | gmf de/compiler | component freedom | xmpp: q3k@q3k.org | email: q3k@q3k.org

Offline Pwnator

  • *
  • Posts: 6676
  • Rep: 15
  • Awards BOTM Winner
    • View Profile
    • http://pwnator.tumblr.com
    • Awards
  • See profile for gamer tags: Yes
Re: Pwn needs help in C
« Reply #2 on: August 31, 2011, 08:13:26 AM »
I disabled both O_NONBLOCKs and for some reason the program just stops at open(). The printf() that followed it didn't come out. D:
Clash Cubes 1 - Grey Matter (Runner-Up)
King of Karnage - Sideshow Freak (Runner-Up, Best Engineered)
Rust In Pieces - Paper Cut 3 (Grand Champion, Most Dangerous Bot)
Wheely Tag Tournament - Ion Thruster (Grand Champion, along with Ounces' DiSemboweLment)
UK vs USA - Dark Striker (Grand Champion)
Rust In Pieces 2 - Claymore (Runner-Up, Favourite Bot)
BBEANS 6 - Infection 4 (Runner-Up)
RA2 Team Championships - Serious Business, Skeksis (Runner-Up, along with Scrappy, S_M, and Badnik)
RA2 Team Championships 2 - The Other Stig (Runner-Up, along with Scrappy, S_M, Badnik, 090901, and R1885)
Replica Wars 3 - Abaddon (Runner-Up, Luckiest Bot)
BroBots - wheebot & yaybot (Runner-Up)
Robo Zone 2 - Dipper (4th place, Survival Champion, & Best Axle Bot)
ARBBC - The Covenant (3rd place, BW Rumble Winner, Most Feared BW)

Offline Serge

  • *
  • Posts: 1530
  • Rep: 13
    • View Profile
    • http://www.q3k.org/
    • Awards
Re: Pwn needs help in C
« Reply #3 on: August 31, 2011, 08:51:58 AM »
I disabled both O_NONBLOCKs and for some reason the program just stops at open(). The printf() that followed it didn't come out. D:

What OS are you using? Did you delete the fifo, and kill the old reader / writer processes? Because it's working fine here on Linux. If you're on Windows, maybe you should look into WinAPI equivalents?
home | twitter | yt | gmf de/compiler | component freedom | xmpp: q3k@q3k.org | email: q3k@q3k.org

Offline Pwnator

  • *
  • Posts: 6676
  • Rep: 15
  • Awards BOTM Winner
    • View Profile
    • http://pwnator.tumblr.com
    • Awards
  • See profile for gamer tags: Yes
Re: Pwn needs help in C
« Reply #4 on: August 31, 2011, 08:56:41 AM »
Another option, if you want to keep the asynchronous (=non-blocking) reading on the reader, you can refrain from printing data to the client unless read() returns > 0, which would mean some bytes were actually read, This way, the reader can still run on a loop, and do some other  processing in the meantime (printing the time, blinking a cursor, whatever). However, this can be more CPU intensive, as a infinite loop like this (=a polled loop) is very CPU intensive.
A good compromise between the two (something asynchronous, but not so CPU intensive) is to use the select() syscall (or some OS equivalent, kpoll on Linux, something on Windows I forgot - they are usually even fatser than select(), which is standarized). This syscall allows you to specify a bunch of file descriptors (be it open files, fifos, or even network sockets), and will block until one or more of these descriptors can be read from or written to. Here's the fun part: you can also specify for how long it will block! This allows you to write code that will block, for example, for 0.1 seconds (waiting for the fifo to have somedata), and then return. If it returned the file descriptor, it means some data was available on it - then you can read() it. If it returns 0, it means the block time has expired, and no data was read from the fifo. After you either handle or not the descriptor, you can do whatever more processing you want, and then loop back to the select() call.

Of course, all of this is unnecessary if you can live with having a blocked loop :P.

This, kids, is why I don't regret not taking BS CS in college. XD

All I did was remove both O_NONBLOCKs then this happened:



I'm compiling through BBS, and my university's computers are running CentOS 5 (HAHAHAHA SO OLD). And yeah, I removed the fifo before running it again.

Does CTRL+C count as killing the processes? That might be my problem.
Clash Cubes 1 - Grey Matter (Runner-Up)
King of Karnage - Sideshow Freak (Runner-Up, Best Engineered)
Rust In Pieces - Paper Cut 3 (Grand Champion, Most Dangerous Bot)
Wheely Tag Tournament - Ion Thruster (Grand Champion, along with Ounces' DiSemboweLment)
UK vs USA - Dark Striker (Grand Champion)
Rust In Pieces 2 - Claymore (Runner-Up, Favourite Bot)
BBEANS 6 - Infection 4 (Runner-Up)
RA2 Team Championships - Serious Business, Skeksis (Runner-Up, along with Scrappy, S_M, and Badnik)
RA2 Team Championships 2 - The Other Stig (Runner-Up, along with Scrappy, S_M, Badnik, 090901, and R1885)
Replica Wars 3 - Abaddon (Runner-Up, Luckiest Bot)
BroBots - wheebot & yaybot (Runner-Up)
Robo Zone 2 - Dipper (4th place, Survival Champion, & Best Axle Bot)
ARBBC - The Covenant (3rd place, BW Rumble Winner, Most Feared BW)

Offline Serge

  • *
  • Posts: 1530
  • Rep: 13
    • View Profile
    • http://www.q3k.org/
    • Awards
Re: Pwn needs help in C
« Reply #5 on: August 31, 2011, 09:01:26 AM »
I'm compiling through BBS, and my university's computers are running CentOS 5 (HAHAHAHA SO OLD).
Oh wow. It works fine on ArchLinux, but it does fail on CentOS (I just tested on my CentOS 5.5 box). I'll look into it.
home | twitter | yt | gmf de/compiler | component freedom | xmpp: q3k@q3k.org | email: q3k@q3k.org

Offline Serge

  • *
  • Posts: 1530
  • Rep: 13
    • View Profile
    • http://www.q3k.org/
    • Awards
Re: Pwn needs help in C
« Reply #6 on: August 31, 2011, 09:24:42 AM »
Acutally, it does work well when you disable O_NONBLOCK on both fthe reader and writer, but the writer will stay blocked at open() until the reader is ran, too.

Code: [Select]
[root@parallelogram ~]# uname -a
Linux parallelogram.global7hosting.com 2.6.18-238.19.1.el5 #1 SMP Fri Jul 15 07:31:24 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux
[root@parallelogram ~]# cat /etc/issue | head - n 1
CentOS release 5.6 (Final)
home | twitter | yt | gmf de/compiler | component freedom | xmpp: q3k@q3k.org | email: q3k@q3k.org

Offline Pwnator

  • *
  • Posts: 6676
  • Rep: 15
  • Awards BOTM Winner
    • View Profile
    • http://pwnator.tumblr.com
    • Awards
  • See profile for gamer tags: Yes
Re: Pwn needs help in C
« Reply #7 on: September 01, 2011, 04:41:19 AM »
WHOA. Did not see that coming. O_O

Just tested it on my buddy's Ubuntu and it also worked fine. No idea why this was an exception, though.
Clash Cubes 1 - Grey Matter (Runner-Up)
King of Karnage - Sideshow Freak (Runner-Up, Best Engineered)
Rust In Pieces - Paper Cut 3 (Grand Champion, Most Dangerous Bot)
Wheely Tag Tournament - Ion Thruster (Grand Champion, along with Ounces' DiSemboweLment)
UK vs USA - Dark Striker (Grand Champion)
Rust In Pieces 2 - Claymore (Runner-Up, Favourite Bot)
BBEANS 6 - Infection 4 (Runner-Up)
RA2 Team Championships - Serious Business, Skeksis (Runner-Up, along with Scrappy, S_M, and Badnik)
RA2 Team Championships 2 - The Other Stig (Runner-Up, along with Scrappy, S_M, Badnik, 090901, and R1885)
Replica Wars 3 - Abaddon (Runner-Up, Luckiest Bot)
BroBots - wheebot & yaybot (Runner-Up)
Robo Zone 2 - Dipper (4th place, Survival Champion, & Best Axle Bot)
ARBBC - The Covenant (3rd place, BW Rumble Winner, Most Feared BW)