Changeset 1213 for trunk/packages


Ignore:
Timestamp:
Nov 12, 2008, 4:10:22 PM (16 years ago)
Author:
gah
Message:

fixed pymol input race condition

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/vizservers/pymolproxy/pymolproxy.c

    r1211 r1213  
    104104
    105105        format = TCL_VARARGS_START(char *, arg1, args);
     106        fprintf(flog, "pymolproxy: ");
    106107        vfprintf(flog, format, args);
    107108        fprintf(flog, "\n");
     
    271272}
    272273
    273 void
     274static void
    274275dyBufferSetLength(DyBuffer *buffer, int length)
    275276{
     
    309310    int left = size;
    310311
    311     trace("bwrite: want to write %d bytes\n", size);
     312    trace("bwrite: want to write %d bytes.", size);
    312313    while(1) {
    313314        result = write(sock,buffer+total,left);
     
    322323            break;
    323324    }
    324     trace("bwrite: wrote %d bytes\n", total);
    325     return(total);
     325    trace("bwrite: wrote %d bytes.", total);
     326    return total;
    326327}
    327328
     
    340341       
    341342        if ((result < 0) && (errno != EAGAIN) && (errno != EINTR)) {
    342             trace("pymolproxy: Error reading sock(%d), %d/%s\n",
    343                   sock, errno,strerror(errno));
     343            trace("Error reading sock(%d), %d/%s.", sock, errno,
     344                  strerror(errno));
    344345            break;
    345346        }
     
    420421}
    421422
     423INLINE static void
     424clear_error(PymolProxy *proxyPtr)
     425{
     426    proxyPtr->error = 0;
     427    proxyPtr->status = TCL_OK;
     428}
     429
    422430static int
    423431getline(int sock, char *buffer, int size, int timeout)
     
    452460            continue; /* try again, if interrupted/blocking */
    453461
    454         if (status <= 0)
     462        if (status <= 0) {
     463            trace("getline: status=%d, errno=%d", status, errno);
    455464            break;
    456                        
     465        }
    457466        if (buffer[pos] == '\n') {
    458467            pos++;
     
    463472
    464473    buffer[pos]=0;
    465 
    466     return(pos);
    467 }
    468 
    469 static int
    470 waitForString(PymolProxy *pymol, char *string, char *buffer, int length)
     474    return pos;
     475}
     476
     477static int
     478Expect(PymolProxy *proxyPtr, char *match, char *buffer, int length)
    471479{
    472480    int sock;
     481    char c;
     482    size_t mlen;
    473483
    474484    assert(buffer != NULL);
    475     if (pymol->status != TCL_OK)
    476         return pymol->status;
    477 
    478     sock = pymol->p_stdout;
    479     trace("want to match (%s)\n", string);
    480     while(1) {
    481         if (getline(sock,buffer,length, IO_TIMEOUT) == 0) {
    482             pymol->error = 2;
    483             pymol->status = TCL_ERROR;
     485    if (proxyPtr->status != TCL_OK)
     486        return proxyPtr->status;
     487
     488    sock = proxyPtr->p_stdout;
     489    trace("Expect(%s)", match);
     490    c = match[0];
     491    mlen = strlen(match);
     492    for (;;) {
     493        if (getline(sock, buffer, length, IO_TIMEOUT) == 0) {
     494            proxyPtr->error = 2;
     495            proxyPtr->status = TCL_ERROR;
    484496            break;
    485497        }
    486498        trace("stdout-u>read(%s)", buffer);
    487         if (strncmp(buffer, string, strlen(string)) == 0) {
    488             trace("stdout-e> %s",buffer);
    489             pymol->error = 0;
    490             pymol->status = TCL_OK;
     499        if ((c == buffer[0]) && (strncmp(buffer, match, mlen) == 0)) {
     500            trace("stdout-e> %s", buffer);
     501            clear_error(proxyPtr);
    491502            break;
    492503        }
    493504    }
    494505
    495     return pymol->status;
    496 }
    497 
    498 INLINE static int
    499 clear_error(PymolProxy *pymol)
    500 {
    501     pymol->error = 0;
    502     pymol->status = TCL_OK;
    503     return pymol->status;
    504 }
    505 
    506 static int
    507 send_expect(PymolProxy *pymol, char *expect, char *cmd)
    508 {
    509     if (pymol->error) {
    510         return(TCL_ERROR);
    511     }
    512     trace("to-pymol>(%s)", cmd);
    513     write(pymol->p_stdin, cmd, strlen(cmd));
    514     if (waitForString(pymol, expect, cmd, 800)) {
    515         trace("pymolproxy: Timeout reading data [%s]\n",cmd);
    516         pymol->error = 1;
    517         pymol->status = TCL_ERROR;
    518         return pymol->status;
    519     }
    520     return( pymol->status );
    521 }
    522 
    523 static int
    524 sendf(PymolProxy *pymol, char *format, ...)
     506    return proxyPtr->status;
     507}
     508
     509static int
     510Send(PymolProxy *proxyPtr, char *format, ...)
    525511{
    526512    va_list ap;
    527     char buffer[800];
    528 
    529     if (pymol->error)
    530         return(TCL_ERROR);
    531 
     513    char iobuffer[BUFSIZ];
     514
     515    if (proxyPtr->error) {
     516        return TCL_ERROR;
     517    }
    532518    va_start(ap, format);
    533     vsnprintf(buffer, 800, format, ap);
     519    vsnprintf(iobuffer, 800, format, ap);
    534520    va_end(ap);
    535     trace("to-pymol>(%s)", buffer);
    536     write(pymol->p_stdin, buffer, strlen(buffer));
    537 
    538     if (waitForString(pymol, "PyMOL>", buffer, 800)) {
    539         trace("pymolproxy: Timeout reading data [%s]\n",buffer);
    540         pymol->error = 1;
    541         pymol->status = TCL_ERROR;
    542         return pymol->status;
    543     }
    544 
    545     return( pymol->status );
    546 }
    547 
    548 static int
    549 BallNStickCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    550 {
     521
     522    trace("to-pymol>(%s)", iobuffer);
     523
     524    /* Write the command out to the server. */
     525    write(proxyPtr->p_stdin, iobuffer, strlen(iobuffer));
     526
     527    /* Now wait for the "PyMOL>" prompt. */
     528    if (Expect(proxyPtr, "PyMOL>", iobuffer, BUFSIZ)) {
     529        trace("timeout reading data (iobuffer=%s)", iobuffer);
     530        proxyPtr->error = 1;
     531        proxyPtr->status = TCL_ERROR;
     532        return proxyPtr->status;
     533    }
     534    return  proxyPtr->status;
     535}
     536
     537static int
     538BallNStickCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     539              const char *argv[])
     540{
     541    float radius, transparency;
    551542    int ghost = 0, defer = 0, push = 0, arg;
    552543    const char *model = "all";
    553     PymolProxy *pymol = (PymolProxy *) cdata;
    554 
    555     clear_error(pymol);
     544    PymolProxy *proxyPtr = clientData;
     545
     546    clear_error(proxyPtr);
    556547
    557548    for(arg = 1; arg < argc; arg++) {
     
    572563    }
    573564
    574     pymol->invalidate_cache = 1;
    575     pymol->need_update = !defer || push;
    576     pymol->immediate_update |= push;
    577 
    578     sendf(pymol, "hide everything,%s\n",model);
    579     sendf(pymol, "set stick_color,white,%s\n",model);
    580        
    581     if (ghost)
    582         sendf(pymol, "set stick_radius,0.1,%s\n",model);
    583     else
    584         sendf(pymol, "set stick_radius,0.14,%s\n",model);
    585 
    586     sendf(pymol, "set sphere_scale=0.25,%s\n", model);
    587 
     565    proxyPtr->invalidate_cache = 1;
     566    proxyPtr->need_update = !defer || push;
     567    proxyPtr->immediate_update |= push;
     568
     569    Send(proxyPtr, "hide everything,%s\n",model);
     570    Send(proxyPtr, "set stick_color,white,%s\n",model);
    588571    if (ghost) {
    589         sendf(pymol, "set sphere_transparency,0.75,%s\n", model);
    590         sendf(pymol, "set stick_transparency,0.75,%s\n", model);
    591     }
    592     else {
    593         sendf(pymol, "set sphere_transparency,0,%s\n", model);
    594         sendf(pymol, "set stick_transparency,0,%s\n", model);
    595     }
    596 
    597     sendf(pymol, "show sticks,%s\n",model);
    598     sendf(pymol, "show spheres,%s\n",model);
    599 
    600     if (pymol->labels)
    601         sendf(pymol, "show labels,%s\n", model);
    602 
    603     return( pymol->status );
    604 }
    605 
    606 static int
    607 SpheresCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     572        radius = 0.1f;
     573        transparency = 0.75f;
     574    } else {
     575        radius = 0.14f;
     576        transparency = 0.0f;
     577    }
     578    Send(proxyPtr, "set stick_radius,%g,%s\n", radius, model);
     579    Send(proxyPtr, "set sphere_scale=0.25,%s\n", model);
     580    Send(proxyPtr, "set sphere_transparency,%g,%s\n", transparency, model);
     581    Send(proxyPtr, "set stick_transparency,%g,%s\n", transparency, model);
     582    Send(proxyPtr, "show sticks,%s\n",model);
     583    Send(proxyPtr, "show spheres,%s\n",model);
     584
     585    if (proxyPtr->labels)
     586        Send(proxyPtr, "show labels,%s\n", model);
     587
     588    return proxyPtr->status;
     589}
     590
     591static int
     592SpheresCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     593           const char *argv[])
    608594{
    609595    int defer = 0, ghost = 0, push = 0, arg;
    610596    const char *model = "all";
    611     PymolProxy *pymol = (PymolProxy *) cdata;
    612 
    613     clear_error(pymol);
     597    PymolProxy *proxyPtr = clientData;
     598
     599    clear_error(proxyPtr);
    614600
    615601    for(arg = 1; arg < argc; arg++) {
     
    630616    }
    631617
    632     pymol->invalidate_cache = 1;
    633     pymol->need_update = !defer || push;
    634     pymol->immediate_update |= push;
    635 
    636     sendf(pymol, "hide everything, %s\n", model);
    637     sendf(pymol, "set sphere_scale,0.41,%s\n", model);
    638     //sendf(pymol, "set sphere_quality,2,%s\n", model);
    639     sendf(pymol, "set ambient,.2,%s\n", model);
     618    proxyPtr->invalidate_cache = 1;
     619    proxyPtr->need_update = !defer || push;
     620    proxyPtr->immediate_update |= push;
     621
     622    Send(proxyPtr, "hide everything, %s\n", model);
     623    Send(proxyPtr, "set sphere_scale,0.41,%s\n", model);
     624    //Send(proxyPtr, "set sphere_quality,2,%s\n", model);
     625    Send(proxyPtr, "set ambient,.2,%s\n", model);
    640626
    641627    if (ghost)
    642         sendf(pymol, "set sphere_transparency,.75,%s\n", model);
     628        Send(proxyPtr, "set sphere_transparency,.75,%s\n", model);
    643629    else
    644         sendf(pymol, "set sphere_transparency,0,%s\n", model);
    645 
    646     sendf(pymol, "show spheres,%s\n", model);
    647 
    648     if (pymol->labels)
    649         sendf(pymol, "show labels,%s\n", model);
    650 
    651     return pymol->status;
    652 }
    653 
    654 static int
    655 LinesCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     630        Send(proxyPtr, "set sphere_transparency,0,%s\n", model);
     631
     632    Send(proxyPtr, "show spheres,%s\n", model);
     633
     634    if (proxyPtr->labels)
     635        Send(proxyPtr, "show labels,%s\n", model);
     636
     637    return proxyPtr->status;
     638}
     639
     640static int
     641LinesCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     642         const char *argv[])
    656643{
    657644    int ghost = 0, defer = 0, push = 0, arg;
    658645    const char *model = "all";
    659     PymolProxy *pymol = (PymolProxy *) cdata;
    660 
    661     clear_error(pymol);
     646    PymolProxy *proxyPtr = clientData;
     647    float lineWidth;
     648
     649    clear_error(proxyPtr);
    662650
    663651    for(arg = 1; arg < argc; arg++) {
     
    678666    }
    679667
    680     pymol->invalidate_cache = 1;
    681     pymol->need_update = !defer || push;
    682     pymol->immediate_update |= push;
    683 
    684     sendf(pymol, "hide everything,%s\n",model);
    685 
    686     if (ghost)
    687         sendf(pymol, "set line_width,.25,%s\n",model);
    688     else
    689         sendf(pymol, "set line_width,1,%s\n",model);
    690 
    691     sendf(pymol, "show lines,%s\n",model);
    692 
    693     if (pymol->labels)
    694         sendf(pymol, "show labels,%s\n",model);
    695 
    696     return pymol->status;
    697 }
    698 
    699 static int
    700 DisableCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    701 {
    702     PymolProxy *pymol = (PymolProxy *) cdata;
     668    proxyPtr->invalidate_cache = 1;
     669    proxyPtr->need_update = !defer || push;
     670    proxyPtr->immediate_update |= push;
     671
     672    Send(proxyPtr, "hide everything,%s\n",model);
     673
     674    lineWidth = (ghost) ? 0.25f : 1.0f;
     675    Send(proxyPtr, "set line_width,%g,%s\n", lineWidth, model);
     676    Send(proxyPtr, "show lines,%s\n",model);
     677    if (proxyPtr->labels)
     678        Send(proxyPtr, "show labels,%s\n",model);
     679
     680    return proxyPtr->status;
     681}
     682
     683static int
     684DisableCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     685           const char *argv[])
     686{
     687    PymolProxy *proxyPtr = clientData;
    703688    const char *model = "all";
    704689    int arg, defer = 0, push = 0;
    705690
    706     clear_error(pymol);
     691    clear_error(proxyPtr);
    707692
    708693    for(arg = 1; arg < argc; arg++) {
     
    717702    }
    718703
    719     pymol->need_update = !defer || push;
    720     pymol->immediate_update |= push;
    721     pymol->invalidate_cache = 1;
    722 
    723     sendf( pymol, "disable %s\n", model);
    724 
    725     return pymol->status;
    726 }
    727 
    728 static int
    729 EnableCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    730 {
    731     PymolProxy *pymol = (PymolProxy *) cdata;
     704    proxyPtr->need_update = !defer || push;
     705    proxyPtr->immediate_update |= push;
     706    proxyPtr->invalidate_cache = 1;
     707
     708    Send( proxyPtr, "disable %s\n", model);
     709
     710    return proxyPtr->status;
     711}
     712
     713static int
     714EnableCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     715          const char *argv[])
     716{
     717    PymolProxy *proxyPtr = clientData;
    732718    const char *model = "all";
    733719    int arg, defer = 0, push = 0;
    734720
    735     clear_error(pymol);
     721    clear_error(proxyPtr);
    736722
    737723    for(arg = 1; arg < argc; arg++) {
     
    746732    }
    747733
    748     pymol->need_update = !defer || push;
    749     pymol->immediate_update |= push;
    750     pymol->invalidate_cache = 1;
    751 
    752     sendf( pymol, "enable %s\n", model);
    753 
    754     return pymol->status;
    755 }
    756 
    757 static int
    758 VMouseCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    759 {
    760     PymolProxy *pymol = (PymolProxy *) cdata;
     734    proxyPtr->need_update = !defer || push;
     735    proxyPtr->immediate_update |= push;
     736    proxyPtr->invalidate_cache = 1;
     737
     738    Send( proxyPtr, "enable %s\n", model);
     739
     740    return proxyPtr->status;
     741}
     742
     743static int
     744VMouseCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     745          const char *argv[])
     746{
     747    PymolProxy *proxyPtr = clientData;
    761748    int arg, defer = 0, push = 0, varg = 1;
    762749    int arg1 = 0, arg2 = 0, arg3 = 0, arg4 = 0, arg5 = 0;
    763750
    764     clear_error(pymol);
     751    clear_error(proxyPtr);
    765752
    766753    for(arg = 1; arg < argc; arg++) {
     
    791778    }
    792779
    793     pymol->need_update = !defer || push;
    794     pymol->immediate_update |= push;
    795     pymol->invalidate_cache = 1;
    796 
    797     sendf(pymol, "vmouse %d,%d,%d,%d,%d\n", arg1,arg2,arg3,arg4,arg5);
    798 
    799     return pymol->status;
    800 }
    801 
    802 static int
    803 RawCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    804 {
    805     PymolProxy *pymol = (PymolProxy *) cdata;
     780    proxyPtr->need_update = !defer || push;
     781    proxyPtr->immediate_update |= push;
     782    proxyPtr->invalidate_cache = 1;
     783
     784    Send(proxyPtr, "vmouse %d,%d,%d,%d,%d\n", arg1, arg2, arg3,
     785                    arg4, arg5);
     786
     787    return proxyPtr->status;
     788}
     789
     790static int
     791RawCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[])
     792{
     793    PymolProxy *proxyPtr = clientData;
    806794    DyBuffer buffer;
    807795    int arg, defer = 0, push = 0;
    808796    const char *cmd;
    809     clear_error(pymol);
     797    clear_error(proxyPtr);
    810798
    811799    dyBufferInit(&buffer);
     
    822810    }
    823811
    824     pymol->need_update = !defer || push;
    825     pymol->immediate_update |= push;
    826     pymol->invalidate_cache = 1;
    827 
    828     sendf(pymol,"%s\n", cmd);
     812    proxyPtr->need_update = !defer || push;
     813    proxyPtr->immediate_update |= push;
     814    proxyPtr->invalidate_cache = 1;
     815
     816    Send(proxyPtr,"%s\n", cmd);
    829817    dyBufferFree(&buffer);
    830818
    831     return pymol->status;
    832 }
    833 
    834 static int
    835 LabelCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    836 {
    837     PymolProxy *pymol = (PymolProxy *) cdata;
     819    return proxyPtr->status;
     820}
     821
     822static int
     823LabelCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     824         const char *argv[])
     825{
     826    PymolProxy *proxyPtr = clientData;
    838827    int state = 1;
    839828    int arg, push = 0, defer = 0;
    840829
    841     clear_error(pymol);
     830    clear_error(proxyPtr);
    842831
    843832    for(arg = 1; arg < argc; arg++) {
     
    851840            state = 0;
    852841        else if (strcmp(argv[arg],"toggle") == 0 )
    853             state =  !pymol->labels;
    854     }
    855 
    856     pymol->need_update = !defer || push;
    857     pymol->immediate_update |= push;
    858     pymol->invalidate_cache = 1;
     842            state =  !proxyPtr->labels;
     843    }
     844
     845    proxyPtr->need_update = !defer || push;
     846    proxyPtr->immediate_update |= push;
     847    proxyPtr->invalidate_cache = 1;
    859848
    860849    if (state) {
    861         sendf(pymol, "set label_color,white,all\n");
    862         sendf(pymol, "set label_size,14,all\n");
    863         sendf(pymol, "label all,\"%%s%%s\" %% (ID,name)\n");
     850        Send(proxyPtr, "set label_color,white,all\n");
     851        Send(proxyPtr, "set label_size,14,all\n");
     852        Send(proxyPtr, "label all,\"%%s%%s\" %% (ID,name)\n");
    864853    }
    865854    else
    866         sendf(pymol, "label all\n");
    867 
    868     pymol->labels = state;
    869 
    870     return pymol->status;
    871 }
    872 
    873 static int
    874 FrameCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    875 {
    876     PymolProxy *pymol = (PymolProxy *) cdata;
     855        Send(proxyPtr, "label all\n");
     856
     857    proxyPtr->labels = state;
     858
     859    return proxyPtr->status;
     860}
     861
     862static int
     863FrameCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     864         const char *argv[])
     865{
     866    PymolProxy *proxyPtr = clientData;
    877867    int frame = 0;
    878868    int arg, push = 0, defer = 0;
    879869
    880     clear_error(pymol);
     870    clear_error(proxyPtr);
    881871
    882872    for(arg = 1; arg < argc; arg++) {
     
    889879    }
    890880               
    891     pymol->need_update = !defer || push;
    892     pymol->immediate_update |= push;
    893 
    894     pymol->frame = frame;
    895 
    896     sendf(pymol,"frame %d\n", frame);
     881    proxyPtr->need_update = !defer || push;
     882    proxyPtr->immediate_update |= push;
     883
     884    proxyPtr->frame = frame;
     885
     886    Send(proxyPtr,"frame %d\n", frame);
    897887       
    898     return pymol->status;
    899 }
    900 
    901 static int
    902 ResetCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    903 {
    904     PymolProxy *pymol = (PymolProxy *) cdata;
     888    return proxyPtr->status;
     889}
     890
     891static int
     892ResetCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     893         const char *argv[])
     894{
     895    PymolProxy *proxyPtr = clientData;
    905896    int arg, push = 0, defer = 0;
    906897
    907     clear_error(pymol);
     898    clear_error(proxyPtr);
    908899
    909900    for(arg = 1; arg < argc; arg++) {
     
    914905    }
    915906               
    916     pymol->need_update = !defer || push;
    917     pymol->immediate_update |= push;
    918     pymol->invalidate_cache = 1;
     907    proxyPtr->need_update = !defer || push;
     908    proxyPtr->immediate_update |= push;
     909    proxyPtr->invalidate_cache = 1;
    919910       
    920     sendf(pymol, "reset\n");
    921     sendf(pymol, "zoom buffer=2\n");
    922 
    923     return pymol->status;
    924 }
    925 
    926 static int
    927 RockCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    928 {
    929     PymolProxy *pymol = (PymolProxy *) cdata;
     911    Send(proxyPtr, "reset\n");
     912    Send(proxyPtr, "zoom buffer=2\n");
     913
     914    return proxyPtr->status;
     915}
     916
     917static int
     918RockCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     919        const char *argv[])
     920{
     921    PymolProxy *proxyPtr = clientData;
    930922    float y = 0.0;
    931923    int arg, push = 0, defer = 0;
    932924
    933     clear_error(pymol);
     925    clear_error(proxyPtr);
    934926
    935927    for(arg = 1; arg < argc; arg++) {
     
    942934    }
    943935               
    944     pymol->need_update = !defer || push;
    945     pymol->immediate_update |= push;
    946 
    947     sendf(pymol,"turn y, %f\n", y - pymol->rock_offset);
    948 
    949     pymol->rock_offset = y;
    950 
    951     return pymol->status;
    952 }
    953 
    954 static int
    955 ViewportCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    956 {
    957     PymolProxy *pymol = (PymolProxy *) cdata;
     936    proxyPtr->need_update = !defer || push;
     937    proxyPtr->immediate_update |= push;
     938
     939    Send(proxyPtr,"turn y, %f\n", y - proxyPtr->rock_offset);
     940
     941    proxyPtr->rock_offset = y;
     942
     943    return proxyPtr->status;
     944}
     945
     946static int
     947ViewportCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     948            const char *argv[])
     949{
     950    PymolProxy *proxyPtr = clientData;
    958951    int width = 640, height = 480;
    959952    int defer = 0, push = 0, arg, varg = 1;
    960953
    961     clear_error(pymol);
     954    clear_error(proxyPtr);
    962955
    963956    for(arg = 1; arg < argc; arg++) {
     
    977970    }
    978971
    979     pymol->need_update = !defer || push;
    980     pymol->immediate_update |= push;
    981     pymol->invalidate_cache = 1;
    982 
    983     sendf(pymol, "viewport %d,%d\n", width, height);
     972    proxyPtr->need_update = !defer || push;
     973    proxyPtr->immediate_update |= push;
     974    proxyPtr->invalidate_cache = 1;
     975
     976    Send(proxyPtr, "viewport %d,%d\n", width, height);
    984977
    985978    //usleep(205000); // .2s delay for pymol to update its geometry *HACK ALERT*
    986979       
    987     return pymol->status;
    988 }
    989 
    990 static int
    991 LoadPDB2Cmd(ClientData cdata, Tcl_Interp *interp, int argc,
    992               const char *argv[])
     980    return proxyPtr->status;
     981}
     982
     983static int
     984LoadPDBCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     985           const char *argv[])
    993986{
    994987    const char *pdbdata, *name;
    995     PymolProxy *pymol = (PymolProxy *) cdata;
     988    PymolProxy *proxyPtr = clientData;
    996989    int state = 1;
    997990    int arg, defer = 0, push = 0, varg = 1;
    998991   
    999     if (pymol == NULL)
    1000         return(TCL_ERROR);
    1001     clear_error(pymol);
     992    if (proxyPtr == NULL)
     993        return TCL_ERROR;
     994    clear_error(proxyPtr);
    1002995    pdbdata = name = NULL;      /* Suppress compiler warning. */
    1003996    for(arg = 1; arg < argc; arg++) {
     
    10181011    }
    10191012   
    1020     pymol->need_update = !defer || push;
    1021     pymol->immediate_update |= push;
     1013    proxyPtr->need_update = !defer || push;
     1014    proxyPtr->immediate_update |= push;
    10221015
    10231016    {
     
    10281021        sprintf(fileName, "/tmp/pymol%d.pdb", getpid());
    10291022        f = fopen(fileName, "w");
    1030         trace("pymolproxy: open file %s as %x\n", fileName, f);
    10311023        if (f == NULL) {
    1032             trace("pymolproxy: failed to open %s %d\n", fileName, errno);
     1024            trace("can't open `%s': %s", fileName, strerror(errno));
    10331025            perror("pymolproxy");
    10341026        }
     
    10361028        nWritten = fwrite(pdbdata, sizeof(char), nBytes, f);
    10371029        if (nBytes != nWritten) {
    1038             trace("pymolproxy: short write %d wanted %d bytes\n", nWritten,
    1039                   nBytes);
     1030            trace("short write %d wanted %d bytes", nWritten, nBytes);
    10401031            perror("pymolproxy");
    10411032        }
    10421033        fclose(f);
    1043         sendf(pymol, "load %s, %s, %d\n", fileName, name, state);
    1044     }
    1045     sendf(pymol, "zoom buffer=2\n");
    1046     return(pymol->status);
    1047 }
    1048 
    1049 static int
    1050 LoadPDBCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    1051 {
    1052     const char *pdbdata, *name;
    1053     PymolProxy *pymol = (PymolProxy *) cdata;
    1054     int state = 1;
    1055     int arg, defer = 0, push = 0, varg = 1;
    1056 
    1057     clear_error(pymol);
    1058 
    1059     pdbdata = name = NULL;      /* Suppress compiler warning. */
    1060     for(arg = 1; arg < argc; arg++) {
    1061         if ( strcmp(argv[arg],"-defer") == 0 )
    1062             defer = 1;
    1063         else if (strcmp(argv[arg],"-push") == 0)
    1064             push = 1;
    1065         else if (varg == 1) {
    1066             pdbdata = argv[arg];
    1067             varg++;
    1068         }
    1069         else if (varg == 2) {
    1070             name = argv[arg];
    1071             varg++;
    1072         }
    1073         else if (varg == 3) {
    1074             state = atoi( argv[arg] );
    1075             varg++;
    1076         }
    1077     }
    1078 
    1079     pymol->need_update = !defer || push;
    1080     pymol->immediate_update |= push;
    1081 
    1082     {
    1083         int count;
    1084         const char *p;
    1085         char *q, *newdata;
    1086 
    1087         count = 0;
    1088         for (p = pdbdata; *p != '\0'; p++) {
    1089             if (*p == '\n') {
    1090                 count++;
    1091             }
    1092             count++;
    1093         }
    1094        
    1095         q = newdata = malloc(count + 100);
    1096         strcpy(newdata, "cmd.read_pdbstr(\"\"\"\\\n");
    1097         q = newdata + strlen(newdata);
    1098         for (p = pdbdata; *p != '\0'; p++, q++) {
    1099             if (*p == '\n') {
    1100                 *q++ = '\\';
    1101             }
    1102             *q = *p;
    1103         }
    1104         sprintf(q, "\\\n\"\"\",\"%s\",%d)\n", name, state);
    1105         {
    1106             char expect[800];
    1107 
    1108             sprintf(expect, "PyMOL>\"\"\",\"%s\",%d)\n", name, state);
    1109             send_expect(pymol, expect, newdata);
    1110         }
    1111         free(newdata);
    1112     }
    1113     sendf(pymol, "zoom buffer=2\n");
    1114 
    1115     return pymol->status;
    1116 }
    1117 
    1118 
    1119 static int
    1120 RotateCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     1034        Send(proxyPtr, "load %s, %s, %d\n", fileName, name, state);
     1035    }
     1036    Send(proxyPtr, "zoom buffer=2\n");
     1037    return proxyPtr->status;
     1038}
     1039
     1040static int
     1041RotateCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     1042          const char *argv[])
    11211043{
    11221044    double turnx = 0.0;
    11231045    double turny = 0.0;
    11241046    double turnz = 0.0;
    1125     PymolProxy *pymol = (PymolProxy *) cdata;
     1047    PymolProxy *proxyPtr = clientData;
    11261048    int defer = 0, push = 0, arg, varg = 1;
    11271049
    1128     clear_error(pymol);
     1050    clear_error(proxyPtr);
    11291051
    11301052    for(arg = 1; arg < argc; arg++) {
     
    11441066        }
    11451067    }
    1146     pymol->need_update = !defer || push;
    1147     pymol->immediate_update  |= push;
    1148     pymol->invalidate_cache = 1;
     1068    proxyPtr->need_update = !defer || push;
     1069    proxyPtr->immediate_update  |= push;
     1070    proxyPtr->invalidate_cache = 1;
    11491071
    11501072    if (turnx != 0.0)
    1151         sendf(pymol,"turn x, %f\n", turnx);
     1073        Send(proxyPtr,"turn x, %f\n", turnx);
    11521074       
    11531075    if (turny != 0.0)
    1154         sendf(pymol,"turn y, %f\n", turny);
     1076        Send(proxyPtr,"turn y, %f\n", turny);
    11551077       
    11561078    if (turnz != 0.0)
    1157         sendf(pymol,"turn z, %f\n", turnz);
    1158 
    1159     return pymol->status;
    1160 }
    1161 
    1162 static int
    1163 ZoomCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     1079        Send(proxyPtr,"turn z, %f\n", turnz);
     1080
     1081    return proxyPtr->status;
     1082}
     1083
     1084static int
     1085ZoomCmd(ClientData clientData, Tcl_Interp *interp, int argc,
     1086        const char *argv[])
    11641087{
    11651088    double factor = 0.0;
    11661089    double zmove = 0.0;
    1167     PymolProxy *pymol = (PymolProxy *) cdata;
     1090    PymolProxy *proxyPtr = clientData;
    11681091    int defer = 0, push = 0, arg, varg = 1;
    11691092
    1170     clear_error(pymol);
     1093    clear_error(proxyPtr);
    11711094
    11721095    for(arg = 1; arg < argc; arg++) {
     
    11821105    zmove = factor * -75;
    11831106 
    1184     pymol->need_update = !defer || push;
    1185     pymol->immediate_update  |= push;
    1186     pymol->invalidate_cache = 1;
     1107    proxyPtr->need_update = !defer || push;
     1108    proxyPtr->immediate_update  |= push;
     1109    proxyPtr->invalidate_cache = 1;
    11871110
    11881111    if (zmove != 0.0)
    1189         sendf(pymol,"move z, %f\n", factor);
    1190 
    1191     return pymol->status;
    1192 }
    1193 
    1194 static int
    1195 PNGCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     1112        Send(proxyPtr,"move z, %f\n", factor);
     1113
     1114    return proxyPtr->status;
     1115}
     1116
     1117static int
     1118PNGCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[])
    11961119{
    11971120    char buffer[800];
    11981121    unsigned int nBytes=0;
    11991122    float samples = 10.0;
    1200     PymolProxy *pymol = (PymolProxy *) cdata;
    1201 
    1202     clear_error(pymol);
    1203 
    1204     if (pymol->invalidate_cache)
    1205         pymol->cacheid++;
    1206 
    1207     pymol->need_update = 0;
    1208     pymol->immediate_update = 0;
    1209     pymol->invalidate_cache = 0;
    1210 
    1211     sendf(pymol,"png -\n");
    1212 
    1213     waitForString(pymol, "image follows: ", buffer, 800);
     1123    PymolProxy *proxyPtr = clientData;
     1124
     1125    clear_error(proxyPtr);
     1126
     1127    if (proxyPtr->invalidate_cache)
     1128        proxyPtr->cacheid++;
     1129
     1130    proxyPtr->need_update = 0;
     1131    proxyPtr->immediate_update = 0;
     1132    proxyPtr->invalidate_cache = 0;
     1133
     1134    Send(proxyPtr,"png -\n");
     1135
     1136    Expect(proxyPtr, "image follows: ", buffer, 800);
    12141137
    12151138    sscanf(buffer, "image follows: %d\n", &nBytes);
     
    12171140    write(3, &samples, sizeof(samples));
    12181141 
    1219     dyBufferSetLength(&pymol->image, nBytes);
    1220 
    1221     bread(pymol->p_stdout, pymol->image.data, pymol->image.used);
    1222 
    1223     waitForString(pymol, " ScenePNG", buffer,800);
    1224 
    1225     if ((nBytes > 0) && (pymol->image.used == nBytes)) {
     1142    dyBufferSetLength(&proxyPtr->image, nBytes);
     1143
     1144    bread(proxyPtr->p_stdout, proxyPtr->image.data, proxyPtr->image.used);
     1145
     1146    Expect(proxyPtr, " ScenePNG", buffer,800);
     1147
     1148    if ((nBytes > 0) && (proxyPtr->image.used == nBytes)) {
    12261149        sprintf(buffer, "nv>image %d %d %d %d\n",
    1227                 nBytes, pymol->cacheid, pymol->frame, pymol->rock_offset);
     1150                nBytes, proxyPtr->cacheid, proxyPtr->frame, proxyPtr->rock_offset);
    12281151        trace("to-molvis> %s", buffer);
    1229         write(pymol->c_stdin, buffer, strlen(buffer));
    1230         bwrite(pymol->c_stdin, pymol->image.data, nBytes);
     1152        write(proxyPtr->c_stdin, buffer, strlen(buffer));
     1153        bwrite(proxyPtr->c_stdin, proxyPtr->image.data, nBytes);
    12311154        stats.nFrames++;
    12321155        stats.nBytes += nBytes;
    12331156    }
    1234     return pymol->status;
    1235 }
    1236 
    1237 static int
    1238 BMPCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     1157    return proxyPtr->status;
     1158}
     1159
     1160static int
     1161BMPCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[])
    12391162{
    12401163    char buffer[800];
    12411164    unsigned int nBytes=0;
    12421165    float samples = 10.0;
    1243     PymolProxy *pymol = (PymolProxy *) cdata;
    1244 
    1245     clear_error(pymol);
    1246 
    1247     if (pymol->invalidate_cache)
    1248         pymol->cacheid++;
    1249 
    1250     pymol->need_update = 0;
    1251     pymol->immediate_update = 0;
    1252     pymol->invalidate_cache = 0;
    1253 
    1254     sendf(pymol,"bmp -\n");
    1255 
    1256     waitForString(pymol, "image follows: ", buffer, 800);
     1166    PymolProxy *proxyPtr = clientData;
     1167
     1168    clear_error(proxyPtr);
     1169
     1170    if (proxyPtr->invalidate_cache)
     1171        proxyPtr->cacheid++;
     1172
     1173    proxyPtr->need_update = 0;
     1174    proxyPtr->immediate_update = 0;
     1175    proxyPtr->invalidate_cache = 0;
     1176
     1177    Send(proxyPtr,"bmp -\n");
     1178
     1179    Expect(proxyPtr, "image follows: ", buffer, 800);
    12571180
    12581181    sscanf(buffer, "image follows: %d\n", &nBytes);
    12591182    write(3,&samples,sizeof(samples));
    12601183
    1261     dyBufferSetLength(&pymol->image, nBytes);
    1262 
    1263     bread(pymol->p_stdout, pymol->image.data, pymol->image.used);
    1264 
    1265     if ((nBytes > 0) && (pymol->image.used == nBytes)) {
     1184    dyBufferSetLength(&proxyPtr->image, nBytes);
     1185
     1186    bread(proxyPtr->p_stdout, proxyPtr->image.data, proxyPtr->image.used);
     1187
     1188    if ((nBytes > 0) && (proxyPtr->image.used == nBytes)) {
    12661189        sprintf(buffer, "nv>image %d %d %d %d\n",
    1267                 nBytes, pymol->cacheid, pymol->frame, pymol->rock_offset);
    1268         write(pymol->c_stdin, buffer, strlen(buffer));
    1269         trace("to-molvis buffer=%s\n", buffer);
    1270         bwrite(pymol->c_stdin, pymol->image.data, nBytes);
     1190                nBytes, proxyPtr->cacheid, proxyPtr->frame, proxyPtr->rock_offset);
     1191        write(proxyPtr->c_stdin, buffer, strlen(buffer));
     1192        trace("to-molvis buffer=%s", buffer);
     1193        bwrite(proxyPtr->c_stdin, proxyPtr->image.data, nBytes);
    12711194        stats.nFrames++;
    12721195        stats.nBytes += nBytes;
    12731196    }
    1274     return pymol->status;
     1197    return proxyPtr->status;
    12751198}
    12761199       
     
    12871210    struct pollfd ufd[3];
    12881211    int pid;
    1289     PymolProxy pymol;
     1212    PymolProxy proxy;
    12901213    struct timeval now, end;
    12911214    int timeout;
     
    12951218
    12961219    if (pipe(pairIn) == -1)
    1297         return(-1);
     1220        return -1;
    12981221
    12991222    if (pipe(pairOut) == -1) {
    13001223        close(pairIn[0]);
    13011224        close(pairIn[1]);
    1302         return(-1);
     1225        return -1;
    13031226    }
    13041227
     
    13081231        close(pairOut[0]);
    13091232        close(pairOut[1]);
    1310         return(-1);
     1233        return -1;
    13111234    }
    13121235
     
    13171240    if (pid < 0) {
    13181241        fprintf(stderr, "can't fork process: %s\n", strerror(errno));
    1319         return(-3);
     1242        return -3;
    13201243    }
    13211244    if (pid == 0) {
     
    13401263       
    13411264        execvp(argv[0], argv);
    1342         trace("pymolproxy: Failed to start pyMol %s\n", argv[0]);
     1265        trace("Failed to start pymol `%s'", argv[0]);
    13431266        exit(-1);
    13441267    }
     
    13521275    signal(SIGPIPE, SIG_IGN); // ignore SIGPIPE (ie if nanoscale terminates)
    13531276
    1354     pymol.p_stdin = pairIn[1];
    1355     pymol.p_stdout = pairOut[0];
    1356     pymol.p_stderr = pairErr[0];
    1357     pymol.c_stdin  = c_in;
    1358     pymol.c_stdout = c_out;
    1359     pymol.labels = 0;
    1360     pymol.need_update = 0;
    1361     pymol.can_update = 1;
    1362     pymol.immediate_update = 0;
    1363     pymol.sync = 0;
    1364     pymol.frame = 1;
    1365     pymol.rock_offset = 0;
    1366     pymol.cacheid = 0;
    1367     pymol.invalidate_cache = 0;
    1368 
    1369     ufd[0].fd = pymol.c_stdout;
     1277    proxy.p_stdin = pairIn[1];
     1278    proxy.p_stdout = pairOut[0];
     1279    proxy.p_stderr = pairErr[0];
     1280    proxy.c_stdin  = c_in;
     1281    proxy.c_stdout = c_out;
     1282    proxy.labels = 0;
     1283    proxy.need_update = 0;
     1284    proxy.can_update = 1;
     1285    proxy.immediate_update = 0;
     1286    proxy.sync = 0;
     1287    proxy.frame = 1;
     1288    proxy.rock_offset = 0;
     1289    proxy.cacheid = 0;
     1290    proxy.invalidate_cache = 0;
     1291
     1292    ufd[0].fd = proxy.c_stdout;
    13701293    ufd[0].events = POLLIN | POLLHUP; /* ensure catching EOF */
    1371     ufd[1].fd = pymol.p_stdout;
     1294    ufd[1].fd = proxy.p_stdout;
    13721295    ufd[1].events = POLLIN | POLLHUP;
    1373     ufd[2].fd = pymol.p_stderr;
     1296    ufd[2].fd = proxy.p_stderr;
    13741297    ufd[2].events = POLLIN | POLLHUP;
    13751298
    1376     flags = fcntl(pymol.p_stdout, F_GETFL);
    1377     fcntl(pymol.p_stdout, F_SETFL, flags|O_NONBLOCK);
     1299    flags = fcntl(proxy.p_stdout, F_GETFL);
     1300    fcntl(proxy.p_stdout, F_SETFL, flags|O_NONBLOCK);
    13781301
    13791302    interp = Tcl_CreateInterp();
     
    13811304
    13821305    Tcl_DStringInit(&cmdbuffer);
    1383     dyBufferInit(&pymol.image);
     1306    dyBufferInit(&proxy.image);
    13841307    dyBufferInit(&dybuffer);
    13851308    dyBufferInit(&dybuffer2);
    13861309
    1387     Tcl_CreateCommand(interp, "bmp",     BMPCmd,        &pymol, NULL);
    1388     Tcl_CreateCommand(interp, "png",     PNGCmd,        &pymol, NULL);
    1389     Tcl_CreateCommand(interp, "screen",  ViewportCmd,   &pymol, NULL);
    1390     Tcl_CreateCommand(interp, "viewport",ViewportCmd,   &pymol, NULL);
    1391     Tcl_CreateCommand(interp, "rotate",  RotateCmd,     &pymol, NULL);
    1392     Tcl_CreateCommand(interp, "zoom",    ZoomCmd,       &pymol, NULL);
    1393     Tcl_CreateCommand(interp, "loadpdb.old", LoadPDBCmd,    &pymol, NULL);
    1394     Tcl_CreateCommand(interp, "loadpdb", LoadPDB2Cmd,  &pymol, NULL);
    1395     Tcl_CreateCommand(interp, "ballnstick",BallNStickCmd, &pymol, NULL);
    1396     Tcl_CreateCommand(interp, "spheres", SpheresCmd,    &pymol, NULL);
    1397     Tcl_CreateCommand(interp, "lines",   LinesCmd,      &pymol, NULL);
    1398     Tcl_CreateCommand(interp, "raw",     RawCmd,        &pymol, NULL);
    1399     Tcl_CreateCommand(interp, "label",   LabelCmd,      &pymol, NULL);
    1400     Tcl_CreateCommand(interp, "reset",   ResetCmd,      &pymol, NULL);
    1401     Tcl_CreateCommand(interp, "rock",    RockCmd,       &pymol, NULL);
    1402     Tcl_CreateCommand(interp, "frame",   FrameCmd,      &pymol, NULL);
    1403     Tcl_CreateCommand(interp, "vmouse",  VMouseCmd,     &pymol, NULL);
    1404     Tcl_CreateCommand(interp, "disable", DisableCmd,    &pymol, NULL);
    1405     Tcl_CreateCommand(interp, "enable",  EnableCmd,     &pymol, NULL);
     1310    Tcl_CreateCommand(interp, "bmp",     BMPCmd,        &proxy, NULL);
     1311    Tcl_CreateCommand(interp, "png",     PNGCmd,        &proxy, NULL);
     1312    Tcl_CreateCommand(interp, "screen",  ViewportCmd,   &proxy, NULL);
     1313    Tcl_CreateCommand(interp, "viewport",ViewportCmd,   &proxy, NULL);
     1314    Tcl_CreateCommand(interp, "rotate",  RotateCmd,     &proxy, NULL);
     1315    Tcl_CreateCommand(interp, "zoom",    ZoomCmd,       &proxy, NULL);
     1316    Tcl_CreateCommand(interp, "loadpdb", LoadPDBCmd,    &proxy, NULL);
     1317    Tcl_CreateCommand(interp, "ballnstick",BallNStickCmd, &proxy, NULL);
     1318    Tcl_CreateCommand(interp, "spheres", SpheresCmd,    &proxy, NULL);
     1319    Tcl_CreateCommand(interp, "lines",   LinesCmd,      &proxy, NULL);
     1320    Tcl_CreateCommand(interp, "raw",     RawCmd,        &proxy, NULL);
     1321    Tcl_CreateCommand(interp, "label",   LabelCmd,      &proxy, NULL);
     1322    Tcl_CreateCommand(interp, "reset",   ResetCmd,      &proxy, NULL);
     1323    Tcl_CreateCommand(interp, "rock",    RockCmd,       &proxy, NULL);
     1324    Tcl_CreateCommand(interp, "frame",   FrameCmd,      &proxy, NULL);
     1325    Tcl_CreateCommand(interp, "vmouse",  VMouseCmd,     &proxy, NULL);
     1326    Tcl_CreateCommand(interp, "disable", DisableCmd,    &proxy, NULL);
     1327    Tcl_CreateCommand(interp, "enable",  EnableCmd,     &proxy, NULL);
    14061328
    14071329    // Main Proxy Loop
     
    14131335    stats.start = end;
    14141336    while(1) {
    1415         char ch;
    1416        
    14171337        gettimeofday(&now,NULL);
    14181338       
    1419         if ( (!pymol.need_update) )
     1339        if ( (!proxy.need_update) )
    14201340            timeout = -1;
    14211341        else if ((now.tv_sec > end.tv_sec) || ( (now.tv_sec == end.tv_sec) && (now.tv_usec >= end.tv_usec)) )
     
    14311351        }
    14321352       
    1433         if (!pymol.immediate_update)
     1353        status = 0;
     1354        errno = 0;
     1355        if (!proxy.immediate_update) {
    14341356            status = poll(ufd, 3, timeout);
    1435         else
    1436             status = 0;
    1437        
     1357            trace("result of poll = %d: %s", status, strerror(errno));
     1358        }
    14381359        if ( status < 0 ) {
    1439             trace("pymolproxy: POLL ERROR: status = %d, errno = %d, %s \n", status,errno,strerror(errno));
     1360            trace("POLL ERROR: status = %d: %s", status, strerror(errno));
    14401361        } else if (status > 0) {
     1362
    14411363            gettimeofday(&now,NULL);
    1442            
    1443             if (ufd[0].revents) { /* Client Stdout Connection: command input */
    1444                 if (read(ufd[0].fd,&ch,1) <= 0) {
     1364            if (ufd[0].revents & POLLIN) {
     1365                /* Client Stdout Connection: command input */
     1366                ssize_t nRead;
     1367                char ch;
     1368
     1369                nRead = read(ufd[0].fd, &ch, 1);
     1370                if (nRead <= 0) {
     1371                    trace("unexpected read error from client (stdout): %s",
     1372                          strerror(errno));
    14451373                    if (errno != EINTR) {
    1446                         trace("pymolproxy: lost client connection (%d).\n", errno);
     1374                        trace("lost client connection: %s", strerror(errno));
    14471375                        break;
    14481376                    }
     
    14501378                    Tcl_DStringAppend(&cmdbuffer, &ch, 1);
    14511379                   
    1452                     if (ch == '\n' && Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer))) {
     1380                    if (ch == '\n' &&
     1381                        Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer))) {
    14531382                        int result;
    14541383
    14551384                        result = ExecuteCommand(interp, &cmdbuffer);
    1456                         if (timeout == 0) status = 0; // send update
     1385                        if (timeout == 0) {
     1386                            status = 0; // send update
     1387                        }
    14571388                    }
    14581389                }
     1390            } else if (ufd[0].revents & POLLHUP) {
     1391                trace("received hangup on stdout from client.");
     1392                break;
    14591393            }
    14601394
    1461             if (ufd[1].revents ) { /* pyMol Stdout Connection: pymol (unexpected) output */
    1462                 if (read(ufd[1].fd, &ch, 1) <= 0) {
    1463                     if (errno != EINTR) {
    1464                         trace("pymolproxy: lost connection (stdout) to pymol server\n");
    1465                         break;
     1395            if (ufd[1].revents & POLLIN) {
     1396                ssize_t nRead;
     1397                char ch;
     1398
     1399                /* This is supposed to suck up all the extra output from the
     1400                 * pymol server output after we've matched the command
     1401                 * prompt.  */
     1402
     1403                /* pyMol Stdout Connection: pymol (unexpected) output */
     1404                nRead = read(ufd[1].fd, &ch, 1);
     1405                if (nRead <= 0) {
     1406                    /* It's possible to have already drained the channel in
     1407                     * response to a client command (handled above). Skip
     1408                     * it if we're blocking. */
     1409                    if ((errno == EAGAIN) || (errno == EINTR)) {
     1410                        trace("try again to read (stdout) to pymol server.");
     1411                        goto nextchannel;
    14661412                    }
     1413                    trace("lost connection (stdout) from pymol server.");
     1414                    break;
    14671415                } else {
    14681416                    dyBufferAppend(&dybuffer, &ch, 1);
     
    14751423                    }
    14761424                }
     1425            } else if (ufd[1].revents & POLLHUP) {
     1426                trace("received hangup on stdout to pymol server.");
     1427                break;
    14771428            }
    1478            
    1479             if (ufd[2].revents) { /* pyMol Stderr Connection: pymol standard error output */
    1480                 if (read(ufd[2].fd, &ch, 1) <= 0) {
     1429        nextchannel:
     1430            if (ufd[2].revents & POLLIN) {
     1431                ssize_t nRead;
     1432                char ch;
     1433
     1434                /* pyMol Stderr Connection: pymol standard error output */
     1435
     1436                nRead = read(ufd[2].fd, &ch, 1);
     1437                if (nRead <= 0) {
     1438                    trace("unexpected read error from server (stderr): %s",
     1439                          strerror(errno));
    14811440                    if (errno != EINTR) {
    1482                         trace("pymolproxy: lost connection (stderr) to pymol server\n");
     1441                        trace("lost connection (stderr) to pymol server.");
    14831442                        break;
    14841443                    }
    14851444                } else {
    14861445                    dyBufferAppend(&dybuffer2, &ch, 1);
    1487                    
    14881446                    if (ch == '\n') {
    14891447                        ch = 0;
     
    14931451                    }
    14941452                }
     1453            } else if (ufd[2].revents & POLLHUP) {
     1454                trace("received hangup on stderr from pymol server.");
     1455                break;
    14951456            }
    14961457        }
     
    14991460            gettimeofday(&now,NULL);
    15001461           
    1501             if (pymol.need_update && pymol.can_update)
     1462            if (proxy.need_update && proxy.can_update)
    15021463                Tcl_Eval(interp, "bmp -\n");
    15031464           
     
    15161477    status = waitpid(pid, &result, WNOHANG);
    15171478    if (status == -1) {
    1518         trace("pymolproxy: error waiting on pymol server to exit (%d)\n", errno);
     1479        trace("error waiting on pymol server to exit: %s", strerror(errno));
    15191480    } else if (status == 0) {
    1520         trace("pymolproxy: attempting to SIGTERM pymol server\n");
     1481        trace("attempting to signal (SIGTERM) pymol server.");
    15211482        kill(-pid, SIGTERM); // kill process group
    15221483        alarm(5);
     
    15251486       
    15261487        while ((status == -1) && (errno == EINTR)) {
    1527             trace("pymolproxy: Attempting to SIGKILL process.\n");
     1488            trace("Attempting to signal (SIGKILL) pymol server.");
    15281489            kill(-pid, SIGKILL); // kill process group
    15291490            alarm(10);
     
    15331494    }
    15341495   
    1535     trace("pymolproxy: pymol server process ended (%d)\n", result);
     1496    trace("pymol server process ended (result=%d)", result);
    15361497   
    1537     dyBufferFree(&pymol.image);
     1498    dyBufferFree(&proxy.image);
    15381499   
    15391500    Tcl_DeleteInterp(interp);
Note: See TracChangeset for help on using the changeset viewer.