Go Premium for a chance to win a PS4. Enter to Win


Can Anyone Explain This Program line by line if you have patience .....

Posted on 2004-08-04
Medium Priority
Last Modified: 2010-04-15
Hi Guys

 This Code IS from Richard Stevens Book......

/* include readline */
#include        "unp.h"

static ssize_t
my_read(int fd, char *ptr)
        static int      read_cnt = 0;
        static char     *read_ptr;
        static char     read_buf[MAXLINE];

        if (read_cnt <= 0) {
                if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
                        if (errno == EINTR)
                                goto again;
                } else if (read_cnt == 0)
                read_ptr = read_buf;

        *ptr = *read_ptr++;

readline(int fd, void *vptr, size_t maxlen)
        int             n, rc;
        char    c, *ptr;

        ptr = vptr;
        for (n = 1; n < maxlen; n++) {
                if ( (rc = my_read(fd, &c)) == 1) {
                        *ptr++ = c;
                        if (c == '\n')
                                break;  /* newline is stored, like fgets() */
                } else if (rc == 0) {
                        if (n == 1)
                                return(0);      /* EOF, no data read */
                                break;          /* EOF, some data was read */
                } else
                        return(-1);             /* error, errno set by read() */

        *ptr = 0;       /* null terminate like fgets() */
/* end readline */

Readline(int fd, void *ptr, size_t maxlen)
        ssize_t         n;

        if ( (n = readline(fd, ptr, maxlen)) < 0)
                err_sys("readline error");

help me


Question by:amankhan

Author Comment

ID: 11719109
Whats the main usage of static variables in that program....

LVL 22

Expert Comment

ID: 11719234
Two, er THREE  probs:

(1)  I don't see ANY static vars in the code.

(2)  I don't see a program.

(2)  Sure sounds like homework.....

LVL 55

Expert Comment

by:Jaime Olivares
ID: 11719956
When you invoke a function, any local variable (function local) is created on the fly, if this function is invoked many times, then this can make your program slower.
A static variable is like a global variable (never is destroyed until program ends) but in a local scope (the function, in this case)

So static variables can be used for 2 main purposes:
1.- To remember the previous value of the variable when function was invoked
2.- To avoid the variables to be created and destroyed every time the function is invoked

I think in your sample code static variables are used for both purposes:
- read_cnt will remember last value, so it keep count of last value the previous time my_read was invoked
- read_buf will be not created again and again when my_read is invoked, gaining some performance
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 23

Accepted Solution

brettmjohnson earned 2000 total points
ID: 11720512
It might be easier to read this program from the bottom up:

Readline() is little more than a very thin wrapper over readline(), adding
error reporting.  There is not much more to say about it.

readline() reads a line of text from the file opened on the file descriptor 'fd'
into the memory specified by 'ptr'.  At most 'maxlen' bytes will be read into
the buffer.  A 'line' is defined as a sequence of bytes terminated by the
ASCII NEWLINE character ('\n') or reaching 'maxlen' in length.  If the on-disk
line is physically longer than 'maxlen' then it will be read in 'maxlen'-sized chunks
on each subsequent call to readline().  The newline character, if found, is returned
in the buffer, so the caller knows if it read a full or partial line.  The returned
buffer of bytes is always terminated with a NUL byte ('\0').  readline returns the
number of bytes read into the buffer (not including the NUL terminator).

To assemble the line, readline() reads one byte at a time from the file by
calling my_read().  If it gets a byte back from my_read(), readline() places
that byte into its supplied buffer, then checks it to see if it was a newline,
allowing it to finish.  If no data was read, it returns 0 bytes read, indicating
an End-Of-File (EOF) condition.  As a comment in the code mentions, readline()
is behaving much like the system library function fgets(), so you can read
the documentation for fgets() for more details.

my_read() does 'buffered' file input from the file opened on descriptor 'fd'.
The function my_read() is declared static, so it is not visible outside of the C file
in which is is implemented (it's 'scope' is limited to the file).

Although my_read() one byte at a time from the files contents, for efficiency it
reads the file in larger chunks and caches the data in a internal buffer 'read_buf[]'.
Although not mentioned in the code snippet supplied, the sizeof read_buf[]
is probably a multiple of the disk block size (512, 1024, or 4096 bytes,
depending on OS and filesystem).  my_read() will read a buffer full of data from
the file, the return the buffer contents one byte at a time for each successive
call to my_read().  When the bytes in the read_buff[] are exhausted, my_read()
reads another chunk of the file in to its cache.

Note that between calls to my_read(), it needs to remember the cache of data it
has read in from the file, the next byte in that cache to return, and the number
of bytes left in the cache.  This information is stored in the variables, read_buf[],
read_ptr, and read_cnt, respectively.  However if these variables were local variables
to the my_read() function as follows, their values would not persist across successive
calls to my_read(), since the storage space for local variables is allocated from the stack
at function entry time:

static ssize_t
my_read(int fd, char *ptr)
       int      read_cnt = 0;
       char     *read_ptr;
       char     read_buf[MAXLINE];

To correct that problem, we could move the variables outside the scope of the
function, making them global.  This forces their storage to be allocated at compile
time, rather than function entry time, so their values persist.

int      read_cnt = 0;
char  *read_ptr;
char    read_buf[MAXLINE];

static ssize_t
my_read(int fd, char *ptr)

Unfortunately, although making the variables global allows their values to
persist between calls to my_read(), it also exposes the private workings of
my_read() to the outside world.  We could make the variables static, but
their placement still exposes the inner workings of my_read() to all the
other functions in the C file (only slightly better than exposing to the whole

static int      read_cnt = 0;
static char  *read_ptr;
static char    read_buf[MAXLINE];

static ssize_t
my_read(int fd, char *ptr)

Using the 'static' keyword with a variable declared within the scope of a function
allows the function create storage that is allocated at compile time and is persistent
across calls like a global variable, but its 'scope' (ability to reference by name) is
limited to the confines of the function:

static ssize_t
my_read(int fd, char *ptr)
       static int      read_cnt = 0;
       static char  *read_ptr;
       static char    read_buf[MAXLINE];

BTW.  Use of a static buffer in this particular way is not particularly good
programming practice.  The function is not 're-entrant'.  Consider the case
where you want to read lines from two separate files (perhaps you are
comparing the two files).  Since my_read() only has a single buffer of
cached data, it doesn't know from which file the data was read.  So even
if you call my_read(fd2, ...), if there was cached bytes previously read from
fd1, my_read() will cheerfully return them.

A better choice is to attach the cached read buffer to each file descriptor
rather than using a single static buffer.  That is exactly what the FILE structure
in stdio.h does.


Expert Comment

ID: 11723199
read_cnt need not be a static variable.
read_buf is a local array, where the data read is getting stored. It's address will be given to pointer ptr, which will be used by the called function.
If read_buf is not a static variable, then once the function returns, the address stored in ptr will become invalid! To avoid this danger, read_buf is declared as static array.
The static pointer read_ptr is not at all needed. The address of read_buf can be directly assigned to ptr.

LVL 23

Expert Comment

ID: 11723267

You did not read the code carefully.  read_cnt and read_ptr MUST be static in this
implementation since they maintain the current read position and number of valid
bytes remaining within read_buf[] between calls to my_read().  See my explanation above.
Note that my_read() returns a single char read from the input stream, albeit in an
awkward manner compared to fgetc().


Expert Comment

ID: 11723317
I think that is correct.
I didn't read the code properly!:-(
Anyway, thanks for pointing out the mistake...


Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
Suggested Courses

971 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question