Welcome to iraf.net Tuesday, March 19 2024 @ 06:43 AM GMT


 Forum Index > Help Desk > Systems New Topic Post Reply
 com_write()
   
Jason Quinn
 11/18/2015 08:54PM (Read 1321 times)  
+++++
Active Member

Status: offline


Registered: 04/07/2006
Posts: 175
I'm still playing around the the CDL code. I found some interesting issues in the private function com_write() in comm.c which I thought I'd share because it helps to "think aloud" so-to-speak to make sure my own changes are valid. This function is kind of at the heart of CDL's handling of the IIS protocol. Here is the X11IRAF2.0BETA version:

[code=c]
/* COM_WRITE -- Asynchronous write of data to the server. Write exactly
* nbytes bytes from the buffer to the server.
*/


#ifdef ANSI_FUNC

static int
com_write (
int fd, /* connection file descriptor */
char *buf, /* buffer to write */
int nbytes /* number of bytes to write */
)
#else

static int
com_write (fd, buf, nbytes)
int fd; /* connection file descriptor */
char *buf; /* buffer to write */
int nbytes; /* number of bytes to write */
#endif
{
int n = 0, total = 0, maxbytes = nbytes;
char *ip = (char *)buf;

for (total=0; total

 
Profile Email
 Quote
Jason Quinn
 11/18/2015 08:57PM  
+++++
Active Member

Status: offline


Registered: 04/07/2006
Posts: 175
Trying again because my previous posting was mangled for some reason.

I'm still playing around the the CDL code. I found some interesting issues in the private function com_write() in comm.c which I thought I'd share because it helps to "think aloud" so-to-speak to make sure my own changes are valid. This function is kind of at the heart of CDL's handling of the IIS protocol. Here is the X11IRAF2.0BETA version:

[code=c]
/* COM_WRITE -- Asynchronous write of data to the server. Write exactly
* nbytes bytes from the buffer to the server.
*/


#ifdef ANSI_FUNC

static int
com_write (
int fd, /* connection file descriptor */
char *buf, /* buffer to write */
int nbytes /* number of bytes to write */
)
#else

static int
com_write (fd, buf, nbytes)
int fd; /* connection file descriptor */
char *buf; /* buffer to write */
int nbytes; /* number of bytes to write */
#endif
{
int n = 0, total = 0, maxbytes = nbytes;
char *ip = (char *)buf;

for (total=0; total

 
Profile Email
 Quote
Jason Quinn
 11/18/2015 09:02PM  
+++++
Active Member

Status: offline


Registered: 04/07/2006
Posts: 175
Ugh.. it seems the c code module cannot handle less than symbols or even the HTML entiteis without choking the parser.

Oh well.

 
Profile Email
 Quote
fitz
 11/18/2015 09:05PM  
AAAAA
Admin

Status: offline


Registered: 09/30/2005
Posts: 4040
The code bracket is just the word "code" in square brackets, and then closed with "/code" in brackets, you don't need to specify the language. You can also use the 'Preview' button to ensure your post is formatted as you intend.



 
Profile Email
 Quote
Jason Quinn
 11/18/2015 10:21PM  
+++++
Active Member

Status: offline


Registered: 04/07/2006
Posts: 175
Quote by: fitz

The code bracket is just the word "code" in square brackets, and then closed with "/code" in brackets, you don't need to specify the language. You can also use the 'Preview' button to ensure your post is formatted as you intend.



The posts shows fine in preview. It only gets butchered after submission. I was using the code brackets correctly. I will try again not specifying the language as c and using the default PHP to see if I can workaround the parsing bug.

===========================

I'm still playing around the the CDL code. I found some interesting issues in the private function com_write() in comm.c which I thought I'd share because it helps to "think aloud" so-to-speak to make sure my own changes are valid. This function is kind of at the heart of CDL's handling of the IIS protocol. Here is the X11IRAF2.0BETA version:

PHP Formatted Code

/* COM_WRITE -- Asynchronous write of data to the server.  Write exactly
 * nbytes bytes from the buffer to the server.
 */



#ifdef ANSI_FUNC

static int
com_write (
    int fd,                             /* connection file descriptor   */
    char *buf,                          /* buffer to write              */
    int nbytes                          /* number of bytes to write     */
)
#else

static int
com_write (fd, buf, nbytes)
int     fd;                             /* connection file descriptor   */
char    *buf;                           /* buffer to write              */
int     nbytes;                         /* number of bytes to write     */
#endif
{
        int n = 0, total = 0, maxbytes = nbytes;
        char *ip = (char *)buf;

        for (total=0; total < nbytes; total += n, ip += n) {
            n = nbytes - total;
            if (maxbytes)
                n = min (maxbytes, n);
            if ((n = write (fd, ip, n)) <= 0)
                return (ERR);
        }
        return (OK);
}



This code attempts to write nbytes to the file descriptor given by fd. Two things to notice:

Minor thing first, the "if (maxbytes)" section is unneeded. In the for-loop, maxbytes will always be positive, so the if-condition will always evaluate to true. Then inside the if-block, the expression "n = min (maxbytes, n)" will never change the value of n because n is always less than or equal to maxbytes. The entire if-block therefore does nothing except perhaps slow things down.

The more serious issue is with the way the write() call is made. The code works by iteratively by looping on calls to write() until all the data is written. Most of the time, write() writes big chunks --- perhaps even writing all the data; however it doesn't have to write everything. It may happen that write() was able to write nothing even when no error occurred (for example, if it just so happened that a signal was caught at just the right time). In this case, the loop should just try again until write() actually can write but that doesn't happen in the function. Instead, it incorrectly returns with ERR. The error check should be less than zero instead of less than or equal to zero. As it is, the code will occasionally error falsely.

A fixed version of (the main body of) the code would look like

PHP Formatted Code

{
        int n = 0, total = 0;
        char *ip = (char *)buf;

        for (total=0; total < nbytes; total += n, ip += n) {
            n = nbytes - total;
            if ((n = write (fd, ip, n)) < 0)
                return (ERR);
        }
        return (OK);
}


Cheers,
Jason


 
Profile Email
 Quote
Jason Quinn
 11/18/2015 11:08PM  
+++++
Active Member

Status: offline


Registered: 04/07/2006
Posts: 175
Even better would just be

PHP Formatted Code

{
        int n = 0, total = 0;
        char *ip = (char *)buf;

        for (total=0; total < nbytes; total += n, ip += n) {
            if ((n = write (fd, ip, nbytes - total)) < 0)
                return (ERR);
        }
        return (OK);
}


so that there's only one semantic interpretation of n instead of two ("number of bytes desired to write" and "number of bytes just written").

Jason

 
Profile Email
 Quote
fitz
 11/20/2015 05:24PM  
AAAAA
Admin

Status: offline


Registered: 09/30/2005
Posts: 4040
Thanks, I agree your last version is much cleaner/clearer and will make the change. Not sure I remember the thinking behind the original code, I've written similar procedures elsewhere and it looks nothing like that 8-)

 
Profile Email
 Quote
   
Content generated in: 0.38 seconds
New Topic Post Reply

Normal Topic Normal Topic
Sticky Topic Sticky Topic
Locked Topic Locked Topic
New Post New Post
Sticky Topic W/ New Post Sticky Topic W/ New Post
Locked Topic W/ New Post Locked Topic W/ New Post
View Anonymous Posts 
Anonymous users can post 
Filtered HTML Allowed 
Censored Content 
dog allergies remedies cialis 20 mg chilblain remedies


Privacy Policy
Terms of Use

User Functions

Login