How to read long value sent by Arduino in C
char b[1];  // read expects an array, so we give it a 1-byte array


No, it expects a pointer to a destination to store the data. You don't need a 1-entry array - you can simplify your code with:

char b;
...
int n = read(fd, &amp;b, 1);  // read a char at a time
...
buf[i] = b;
... etc ...



  Currently it works fine, but I strongly believe it is not the correct way to do it (or rather not the optimized way to do it).


C has the function strtoul() which is far more efficient that sscanf.

uint32_t val = strtoul(buf, NULL, 10);


The 10 is the base to convert from, so you could convert hexadecimal (base 16), octal (base 8), etc using it.


  Q1: Am i reading the \r\n wrongly from the println (I saw in Arduino documentation that println prints \r\n)? What resulted in C 'cutting off' the message when it detected a \r from Arduino even though I specifically set to kill it only when \n is received?


You're defining the variable until to contain \n, yet passing the variable newLine to your function. Maybe that has something to do with it?


  Q2: Instead of printing a string to me and converting it back to integer in C, is there a way for Arduino to send me a long value directly instead? eg 501050105 or 51515. how should I rewrite the serial print or method? And how do i capture that integer correctly in C? If i'm not wrong if a raw integer is print out from Arduino, it converts it into ASCII code. I'm still very new to C and Arduino and hope some guidelines to be given so I can improve on the current coding.


You can send a 32-bit value using just 4 bytes. However it's not reliable without implementing a whole protocol around those 4 bytes which, for just 4 bytes, is a bit of a waste. Simplest just to stick to ASCII encoding your data.