示例#1
0
const char* sge_dstring_append_time(dstring *buffer, time_t time, bool as_xml)
{
   struct tm *tm;
#ifdef HAS_LOCALTIME_R
   struct tm tm_buffer;
#endif
          
   DENTER(DSTRING_LAYER, "sge_dstring_append_time");

#ifdef HAS_LOCALTIME_R
   tm = (struct tm *)localtime_r(&time, &tm_buffer);
#else   
   tm = localtime(&i);
#endif       

   if (as_xml) {
      sge_dstring_sprintf_append(buffer, "%04d-%02d-%02dT%02d:%02d:%02d",
              1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
              tm->tm_hour, tm->tm_min, tm->tm_sec);
   } else {
      sge_dstring_sprintf_append(buffer, "%02d/%02d/%04d %02d:%02d:%02d",
              tm->tm_mon + 1, tm->tm_mday, 1900 + tm->tm_year,
              tm->tm_hour, tm->tm_min, tm->tm_sec);
   }

   DRETURN(buffer->s);
}
示例#2
0
void sge_spoolmsg_append(dstring *ds, const char comment_char, const char *version)
{
   int i = 0;

   sge_dstring_sprintf_append(ds, "%c Version: %s\n", comment_char, version);
   while(spoolmsg_message[i]) {
      sge_dstring_sprintf_append(ds, "%c %s\n", comment_char, spoolmsg_message[i]);
      i++;
   }

   return;
}
示例#3
0
/****** uti/monitor/sge_monitor_output() ***************************************
*  NAME
*     sge_monitor_output() -- outputs the result into the message file
*
*  SYNOPSIS
*     void sge_monitor_output(monitoring_t *monitor) 
*
*  FUNCTION
*     This function computes the output line from the gathered statistics.
*     The output is only generated, when the the output flag in the
*     monitoring structure is set.
*
*     The monitoring line is printed to the message file in the profiling
*     class and it made available for the qping -f output. For the qping
*     output, it stores the the generation time, though that qping can
*     show, when the message was generated.
*
*     If an extension is set, it calls the apropriate output function for
*     it.
*
*  INPUTS
*     monitoring_t *monitor - the monitoring info
*
*  NOTES
*     MT-NOTE: sge_monitor_output() is MT safe 
*
*******************************************************************************/
void sge_monitor_output(monitoring_t *monitor) 
{
   DENTER(GDI_LAYER, "sge_monitor_output");

   if ((monitor != NULL) && (monitor->output == true)) {
      struct timeval after;
      double time;

      gettimeofday(&after, NULL); 
      time = after.tv_usec - monitor->now.tv_usec;
      time = after.tv_sec - monitor->now.tv_sec + (time/1000000);

      sge_dstring_clear(monitor->work_line);
  
      sge_dstring_sprintf_append(monitor->work_line, MSG_UTI_MONITOR_DEFLINE_SF, 
                                 monitor->thread_name, monitor->message_in_count/time); 
      
      if (monitor->ext_type != NONE_EXT) {
         sge_dstring_append(monitor->work_line, " (");
         monitor->ext_output(monitor->work_line, monitor->ext_data, time);
         sge_dstring_append(monitor->work_line, ")");
      };
      
      sge_dstring_sprintf_append(monitor->work_line, MSG_UTI_MONITOR_DEFLINE_FFFFF,  
                                 monitor->message_out_count/time,
                                 monitor->message_in_count ? (time - monitor->idle)/monitor->message_in_count: 0,
                                 monitor->idle/time*100, monitor->wait/time*100, time);           
    
      /* only log into the message file, if the user wants it */
      if (monitor->log_monitor_mes) {
         sge_log(LOG_PROF, sge_dstring_get_string(monitor->work_line),__FILE__,SGE_FUNC,__LINE__); 
      }
     
      if (monitor->pos != -1) {
         dstring *tmp = NULL;

         sge_mutex_lock("sge_monitor_init", SGE_FUNC, __LINE__, &(Output[monitor->pos].Output_Mutex));
         tmp = Output[monitor->pos].output;
         Output[monitor->pos].output = monitor->work_line;
         Output[monitor->pos].update_time = after.tv_sec;         
         sge_mutex_unlock("sge_monitor_init", SGE_FUNC, __LINE__, &(Output[monitor->pos].Output_Mutex));

         monitor->work_line = tmp;
       }

      sge_monitor_reset(monitor);
   }
   
   DRETURN_VOID;
}
示例#4
0
/****** uti/sge_log/sge_do_log() ***********************************************
*  NAME
*     sge_do_log() -- Write message to log file 
*
*  SYNOPSIS
*     static void sge_do_log(int aLevel, const char *aMessage, const char 
*
*  FUNCTION
*     ??? 
*
*  INPUTS
*     int aLevel           - log level
*     const char *aMessage - log message
*
*  RESULT
*     void - none
*
*  NOTES
*     MT-NOTE: sge_do_log() is MT safe.
*
*******************************************************************************/
static void sge_do_log(u_long32 me, const char* progname, const char* unqualified_hostname,
                       int aLevel, const char *aMessage)
{
   int fd;

   if (me == QMASTER || me == EXECD || me == SCHEDD || me == SHADOWD) {
      if ((fd = SGE_OPEN3(log_state_get_log_file(), O_WRONLY | O_APPEND | O_CREAT, 0666)) >= 0) {
         char msg2log[4*MAX_STRING_SIZE];
         dstring msg;
         int len;

         sge_dstring_init(&msg, msg2log, sizeof(msg2log));

         append_time((time_t)sge_get_gmt(), &msg, false);

         sge_dstring_sprintf_append(&msg, "|%6.6s|%s|%c|%s\n",
                 progname,
                 unqualified_hostname,
                 aLevel,
                 aMessage);

         len = strlen(msg2log);
         if (write(fd, msg2log, len) != len) {
            /* we are in error logging here - the only chance to log this problem
             * might be to write it to stderr
             */
            fprintf(stderr, "can't log to file %s: %s\n", log_state_get_log_file(), sge_strerror(errno, &msg));
         }
         close(fd);
      }
   }

   return;
} /* sge_do_log() */
示例#5
0
/****** uti/sge_log/sge_do_log() ***********************************************
*  NAME
*     sge_do_log() -- Write message to log file 
*
*  SYNOPSIS
*     static void sge_do_log(int aLevel, const char *aMessage, const char 
*
*  FUNCTION
*     ??? 
*
*  INPUTS
*     int aLevel           - log level
*     const char *aMessage - log message
*
*  RESULT
*     void - none
*
*  NOTES
*     MT-NOTE: sge_do_log() is MT safe.
*
*******************************************************************************/
static void sge_do_log(u_long32 me, const char* progname, const char* unqualified_hostname,
                       int aLevel, const char *aMessage) 
{
   int fd;

   if (me == QMASTER || me == EXECD || me == SCHEDD || me == SHADOWD) {
      if ((fd = SGE_OPEN3(log_state_get_log_file(), O_WRONLY | O_APPEND | O_CREAT, 0666)) >= 0) {
         char msg2log[4*MAX_STRING_SIZE];
         dstring msg;
         
         sge_dstring_init(&msg, msg2log, sizeof(msg2log));

         append_time((time_t)sge_get_gmt(), &msg, false); 

         sge_dstring_sprintf_append(&msg, "|%6.6s|%s|%c|%s\n",
                 progname,
                 unqualified_hostname,
                 aLevel,
                 aMessage);

         write(fd, msg2log, strlen(msg2log));
         close(fd);
      }
   }   

   return;
} /* sge_do_log() */
示例#6
0
static void ext_tet_output(dstring *message, void *monitoring_extension, double time)
{
   m_tet_t *tet_ext = (m_tet_t*) monitoring_extension;
  
   sge_dstring_sprintf_append(message, MSG_UTI_MONITOR_TETEXT_FF,
            ((double)tet_ext->event_count) / tet_ext->count,
             tet_ext->exec_count / time
           );
}
示例#7
0
/****** uti/monitor/ext_lis_output() *******************************************
*  NAME
*     ext_lis_output() -- generates a string from the listener extension 
*
*  SYNOPSIS
*     static void 
*     ext_lis_output(char *message, int size, void 
*                    *monitoring_extension, double time) 
*
*  FUNCTION
*     generates a string from the extension and returns it.
*
*  INPUTS
*     char *message              - initilized string buffer
*     int size                   - buffer size
*     void *monitoring_extension - the extension structure
*     double time                - length of the mesurement interval
*
*  NOTES
*     MT-NOTE: ext_lis_output() is MT safe 
*******************************************************************************/
static void ext_lis_output(dstring *message, void *monitoring_extension, double time)
{
   m_lis_t *gdi_ext = (m_lis_t*) monitoring_extension;

   sge_dstring_sprintf_append(message, MSG_UTI_MONITOR_LISEXT_FFFF,
            gdi_ext->inc_gdi/time,
            gdi_ext->inc_ack/time,
            gdi_ext->inc_ece/time,
            gdi_ext->inc_rep/time);
}
示例#8
0
/****** uti/monitor/ext_gdi_output() *******************************************
*  NAME
*     ext_gdi_output() -- generates a string from the GDI extension
*
*  SYNOPSIS
*     static void ext_gdi_output(char *message, int size, void 
*     *monitoring_extension, double time) 
*
*  FUNCTION
*     generates a string from the extension and returns it.
*
*  INPUTS
*     char *message              - initilized string buffer
*     int size                   - buffer size
*     void *monitoring_extension - the extension structure
*     double time                - length of the mesurement interval
*
*  NOTES
*     MT-NOTE: ext_gdi_output() is MT safe 
*******************************************************************************/
static void ext_gdi_output(dstring *message, void *monitoring_extension, double time)
{
   m_gdi_t *gdi_ext = (m_gdi_t*) monitoring_extension;

   sge_dstring_sprintf_append(message, MSG_UTI_MONITOR_GDIEXT_FFFFFFFFFFFFI,
            gdi_ext->eload_count/time, gdi_ext->ejob_count/time, 
            gdi_ext->econf_count/time, gdi_ext->eproc_count/time,
            gdi_ext->eack_count/time, 
            gdi_ext->gdi_add_count/time, gdi_ext->gdi_get_count/time,
            gdi_ext->gdi_mod_count/time, gdi_ext->gdi_del_count/time,
            gdi_ext->gdi_cp_count/time, gdi_ext->gdi_trig_count/time, 
            gdi_ext->gdi_perm_count/time,
            sge_u32c(gdi_ext->queue_length));
}
示例#9
0
/****** uti/monitor/ext_edt_output() *******************************************
*  NAME
*     ext_edt_output() -- generates a string from the GDI extension
*
*  SYNOPSIS
*     static void ext_edt_output(char *message, int size, void 
*     *monitoring_extension, double time) 
*
*  FUNCTION
*     generates a string from the extension and returns it.
*
*  INPUTS
*     char *message              - initilized string buffer
*     int size                   - buffer size
*     void *monitoring_extension - the extension structure
*     double time                - length of the mesurement interval
*
*  NOTES
*     MT-NOTE: ext_edt_output() is MT safe 
*
*******************************************************************************/
static void ext_edt_output(dstring *message, void *monitoring_extension, double time)
{
   m_edt_t *edt_ext = (m_edt_t*) monitoring_extension;
   
   sge_dstring_sprintf_append(message, MSG_UTI_MONITOR_EDTEXT_FFFFFFFF,
            ((double)edt_ext->client_count) / edt_ext->count,
            edt_ext->mod_client_count / time,
            edt_ext->ack_count / time,
            ((double)edt_ext->blocked_client_count) / edt_ext->count,
            ((double)edt_ext->busy_client_count) / edt_ext->count,
            
            edt_ext->new_event_count / time,
            edt_ext->added_event_count / time,
            edt_ext->skip_event_count / time);
}
示例#10
0
/****** sgeobj/str/str_list_append_to_dstring() *******************************
*  NAME
*     str_list_append_to_dstring() -- append strings to dstring 
*
*  SYNOPSIS
*     const char * 
*     str_list_append_to_dstring(const lList *this_list, 
*                                dstring *string, 
*                                const char delimiter) 
*
*  FUNCTION
*     Append the strings contained in "this_list" to the dstring 
*     "string". Separate them by the character contained in 
*     "delimiter". 
*     If "this_list" is NULL or conaines no elements, "NONE" will
*     be added to the dstring.
*
*  INPUTS
*     const lList *this_list - ST_Type list 
*     dstring *string        - dynamic string 
*     const char delimiter   - delimiter  
*
*  RESULT
*     const char * - pointer to the given "string"-buffer 
*
*  SEE ALSO
*     sgeobj/str/str_list_parse_from_string()
*******************************************************************************/
const char *
str_list_append_to_dstring(const lList *this_list, dstring *string,
                           const char delimiter)
{
   const char *ret = NULL;

   DENTER(STR_LAYER, "str_list_append_to_dstring");
   if (string != NULL) {
      lListElem *elem = NULL;
      bool printed = false;

      for_each(elem, this_list) {
         sge_dstring_append(string, lGetString(elem, ST_name));
         if (lNext(elem) != NULL) {
            sge_dstring_sprintf_append(string, "%c", delimiter);
         }
         printed = true;
      }
示例#11
0
/****** sge_binding/binding_print_to_string() **********************************
*  NAME
*     binding_print_to_string() -- Prints the content of a binding list to a string
*
*  SYNOPSIS
*     bool binding_print_to_string(const lListElem *this_elem, dstring *string)
*
*  FUNCTION
*     Prints the binding type and binding strategy of a binding list element 
*     into a string.
*
*  INPUTS
*     const lListElem* this_elem - Binding list element
*
*  OUTPUTS
*     const dstring *string      - Output string which must be initialized.
*
*  RESULT
*     bool - true in all cases
*
*  NOTES
*     MT-NOTE: is_starting_point() is MT safe
*
*******************************************************************************/
bool
binding_print_to_string(const lListElem *this_elem, dstring *string) {
   bool ret = true;

   DENTER(BINDING_LAYER, "binding_print_to_string");
   if (this_elem != NULL && string != NULL) {
      const char *const strategy = lGetString(this_elem, BN_strategy);
      binding_type_t type = (binding_type_t)lGetUlong(this_elem, BN_type);

      switch (type) {
         case BINDING_TYPE_SET:
            sge_dstring_append(string, "set ");
            break;
         case BINDING_TYPE_PE:
            sge_dstring_append(string, "pe ");
            break;
         case BINDING_TYPE_ENV:
            sge_dstring_append(string, "env ");
            break;
         case BINDING_TYPE_NONE:
            sge_dstring_append(string, "NONE");
      }

      if (strcmp(strategy, "linear_automatic") == 0) {
         u_long32 n = sge_u32c(lGetUlong(this_elem, BN_parameter_n));
         if (BIND_INFINITY == n)
            sge_dstring_sprintf_append(string, "linear:slots");
         else
            sge_dstring_sprintf_append(string, "linear:"sge_U32CFormat, n);
      } else if (strcmp(strategy, "linear") == 0) {
        sge_dstring_sprintf_append(string, "%s:"sge_U32CFormat":"sge_U32CFormat","sge_U32CFormat,
               "linear", sge_u32c(lGetUlong(this_elem, BN_parameter_n)),
               sge_u32c(lGetUlong(this_elem, BN_parameter_socket_offset)),
               sge_u32c(lGetUlong(this_elem, BN_parameter_core_offset)));
      } else if (strcmp(strategy, "striding_automatic") == 0) {
         sge_dstring_sprintf_append(string, "%s:"sge_U32CFormat":"sge_U32CFormat,
            "striding", sge_u32c(lGetUlong(this_elem, BN_parameter_n)),
            sge_u32c(lGetUlong(this_elem, BN_parameter_striding_step_size)));
      } else if (strcmp(strategy, "striding") == 0) {
         sge_dstring_sprintf_append(string, "%s:"sge_U32CFormat":"sge_U32CFormat":"sge_U32CFormat","sge_U32CFormat,
            "striding", sge_u32c(lGetUlong(this_elem, BN_parameter_n)),
            sge_u32c(lGetUlong(this_elem, BN_parameter_striding_step_size)),
            sge_u32c(lGetUlong(this_elem, BN_parameter_socket_offset)),
            sge_u32c(lGetUlong(this_elem, BN_parameter_core_offset)));
      } else if (strcmp(strategy, "explicit") == 0) {
         sge_dstring_sprintf_append(string, "%s", lGetString(this_elem, BN_parameter_explicit));
      }
   }
   DRETURN(ret);
}
示例#12
0
/****** category/sge_build_job_cs_category() ***********************************
*  NAME
*     sge_build_job_cs_category() -- generates the category string for the sc
*
*  SYNOPSIS
*     const char* sge_build_job_cs_category(dstring *category_str, lListElem 
*     *job, lListElem *cat_obj) 
*
*  FUNCTION
*     ??? 
*
*  INPUTS
*     dstring *category_str - storage forthe c string
*     lListElem *job        - job for which to create a category
*     lListElem *cat_obj    - regular category for the job.
*
*  RESULT
*     const char* - 
*
*  EXAMPLE
*     ??? 
*
*  NOTES
*     MT-NOTE: sge_build_job_cs_category() is MT safe 
*
*******************************************************************************/
const char* 
sge_build_job_cs_category(dstring *category_str, lListElem *job, lListElem *cat_obj, bool did_project) 
{
   const char *p;

   DENTER(TOP_LAYER, "sge_build_job_cs_category");

   /* 
    *  deadline
    */
   sge_dstring_sprintf_append(category_str, "-dl "sge_u32, lGetUlong(job, JB_deadline));
   /*
    * priority
    */
   sge_dstring_sprintf_append(category_str, "-p "sge_u32, lGetUlong(job, JB_priority));
   sge_dstring_sprintf_append(category_str, "-ot "sge_u32, lGetUlong(job, JB_override_tickets));
   sge_dstring_sprintf_append(category_str, "-js "sge_u32, lGetUlong(job, JB_jobshare));
   sge_dstring_sprintf_append(category_str, "-u %s", lGetString(job, JB_owner));

   /*
    * ticket assignment can depend on a jobs project.
    * If the project was not added to the resource categories
    * it gets added directly to the cs category string 
    */
   if ((p=lGetString(job, JB_project)) && !did_project)
      sge_dstring_sprintf_append(category_str, " -P %s", p);

   /*
    * id for the resource category
    * I use teh address of the resource category as a hash value for its string.
    */
   sge_dstring_sprintf_append(category_str, " %x", cat_obj);

   DEXIT;
   return sge_dstring_get_string(category_str);
}
示例#13
0
/****** uti/monitor/ext_sch_output() *******************************************
*  NAME
*     ext_sch_output() -- generates a string from the scheduler extension
*
*  SYNOPSIS
*     static void 
*     ext_sch_output(char *message, int size, void 
*                    *monitoring_extension, double time) 
*
*  FUNCTION
*     generates a string from the extension and returns it.
*
*  INPUTS
*     char *message              - initilized string buffer
*     int size                   - buffer size
*     void *monitoring_extension - the extension structure
*     double time                - length of the mesurement interval
*
*  NOTES
*     MT-NOTE: ext_gdi_output() is MT safe 
*******************************************************************************/
static void ext_sch_output(dstring *message, void *monitoring_extension, double time)
{
   sge_dstring_sprintf_append(message, "");
}
示例#14
0
/****** uti/monitor/sge_monitor_status() ***************************************
*  NAME
*     sge_monitor_status() -- generates the status for qping / commlib
*
*  SYNOPSIS
*     u_long32 sge_monitor_status(char **info_message, u_long32 monitor_time) 
*
*  FUNCTION
*     This method creats the health monitoring output and returns the monitoring
*     info to the commlib. 
*
*  INPUTS
*     char **info_message   - info_message pointer, has to point to a NULL string
*     u_long32 monitor_time - the configured monitoring interval
*
*  RESULT
*     u_long32 - 0 : everything is okay
*                1 : warning
*                2 : error
*                3 : init problems
*
*  NOTES
*     MT-NOTE: sge_monitor_status() is MT safe 
*
*******************************************************************************/
u_long32 sge_monitor_status(char **info_message, u_long32 monitor_time)
{
   u_long32 ret = 0;
   char date[40];
   dstring ddate;
   
   DENTER(GDI_LAYER, "sge_monitor_status");

   if (info_message == NULL) {
      DEXIT;
      return 3;
   }

   sge_dstring_init(&ddate, date, sizeof(date));
   
   sge_mutex_lock("sge_monitor_status", SGE_FUNC, __LINE__, &global_mutex);

   sge_dstring_clear(&Info_Line);
   
   {/* this is the qping info section, it checks if each thread is still alive */
      int i;
      int error_count = 0;
      struct timeval now;
      double time;
      char   state = 'R';
      gettimeofday(&now,NULL);
      
      for (i = 0; i < MAX_OUTPUT_LINES; i++) {
         sge_mutex_lock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex));
         if (Output[i].name != NULL) {
            time = now.tv_usec - Output[i].last_wait_time.tv_usec;
            time = now.tv_sec - Output[i].last_wait_time.tv_sec + (time /1000000);

            
            if (Output[i].warning_timeout !=  NO_WARNING) {
               if (Output[i].warning_timeout < time) {
                  if (Output[i].error_timeout < time) {
                     state = 'E';
                  }
                  else {
                     state = 'W';
                  }
                  error_count++;
               }
            } 
            sge_dstring_sprintf_append(&Info_Line, MSG_UTI_MONITOR_INFO_SCF, Output[i].name, state, time);
         }
         sge_mutex_unlock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex));
      }

      if (error_count == 0) {
         sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_OK);
      }
      else if (error_count == 1) {
         ret = 1;
         sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_WARNING);
      }
      else {
         ret = 2;
         sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_ERROR);
      }
      sge_dstring_append(&Info_Line, "\n");
   }

#if defined(LINUX) || defined(AIX43) || defined(AIX51) || defined(IRIX) || defined(SOLARIS) || defined(HP11)
   if (mallinfo_func_pointer != NULL) {
      struct mallinfo mallinfo_data = mallinfo_func_pointer();

      sge_dstring_sprintf_append(&Info_Line, MSG_UTI_MONITOR_SCHEXT_UUUUUUUUUU,
                                 mallinfo_data.arena,
                                 mallinfo_data.ordblks,
                                 mallinfo_data.smblks,
                                 mallinfo_data.hblks,
                                 mallinfo_data.hblkhd,
                                 mallinfo_data.usmblks,
                                 mallinfo_data.fsmblks,
                                 mallinfo_data.uordblks,
                                 mallinfo_data.fordblks,
                                 mallinfo_data.keepcost);
      sge_dstring_append(&Info_Line, "\n");
   }
#endif
 

   if (monitor_time != 0) { /* generates the output monitoring output data */
      int i;
      sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_COLON); 
      sge_dstring_append(&Info_Line, "\n");

      for (i = 0; i < MAX_OUTPUT_LINES; i++) {
         sge_mutex_lock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex));
         if (Output[i].name != NULL) {
            append_time(Output[i].update_time, &Info_Line, false);
            sge_dstring_append(&Info_Line, " | ");
            sge_dstring_append_dstring(&Info_Line, Output[i].output);
            sge_dstring_append(&Info_Line,"\n");
         }
         sge_mutex_unlock("sge_monitor_status", SGE_FUNC, __LINE__, &(Output[i].Output_Mutex));
      }
   }
   else {
      sge_dstring_append(&Info_Line, MSG_UTI_MONITOR_DISABLED);
      sge_dstring_append(&Info_Line, "\n");
   }

   *info_message = strdup(sge_dstring_get_string(&Info_Line));
  
   sge_mutex_unlock("sge_monitor_status", SGE_FUNC, __LINE__, &global_mutex);
   DEXIT;
   return ret;
}
static bool 
check_all(dstring *sb)
{
   bool ret = true;
   int i;

   /* sge_dstring_append */
   printf("\nchecking sge_dstring_append\n");
   sge_dstring_append(NULL, NULL);

   sge_dstring_append(sb, NULL);
   check_dstring(sb);

   sge_dstring_append(sb, "blah");
   check_dstring(sb);

   sge_dstring_clear(sb);
   sge_dstring_append(sb, "too long string to fit into a static string buffer");
   check_dstring(sb);

   sge_dstring_clear(sb);
   sge_dstring_append(sb, 
                      "long string that requires multiple chunks ....... ");
   check_dstring(sb);
   for (i = 0; i < 20; i++) {
      sge_dstring_append(sb, 
                         "long string that requires multiple chunks ....... ");
   }
   check_dstring(sb);

   /* sge_dstring_append_dstring */
   printf("\nchecking sge_dstring_append_dstring\n");
   sge_dstring_clear(sb);
   sge_dstring_append_dstring(NULL, NULL);
   {
      dstring second = DSTRING_INIT;
      sge_dstring_append(&second, "dstring");
      sge_dstring_append_dstring(NULL, &second);
      sge_dstring_append_dstring(sb, NULL);
      sge_dstring_append_dstring(sb, &second);
      check_dstring(sb);
   
      sge_dstring_free(&second);
   }

   /* sge_dstring_append_char */
   printf("\nchecking sge_dstring_append_char\n");
   sge_dstring_clear(sb);
   sge_dstring_append_char(NULL, 'a');
   sge_dstring_append_char(sb, '\0');
   check_dstring(sb);
   sge_dstring_append_char(sb, 'a');
   check_dstring(sb);
   sge_dstring_append_char(sb, 'b');
   check_dstring(sb);

   /* sge_dstring_sprintf */
   printf("\nchecking sge_dstring_sprintf\n");
   sge_dstring_sprintf(NULL, "test %s", "string");
   sge_dstring_sprintf(sb, NULL);
   sge_dstring_sprintf(sb, "test %s", "string");
   check_dstring(sb);
  
#if 0
   /* does not build on irix */
   /* sge_dstring_vsprintf */
   printf("\nchecking sge_dstring_vsprintf\n");
   {
      const char *args[] = { "string", NULL };
      sge_dstring_clear(sb);
      sge_dstring_vsprintf(NULL, "test %s", args);
      sge_dstring_vsprintf(sb, NULL, args);
      sge_dstring_vsprintf(sb, "test %s", args);
      check_dstring(sb);
   }
#endif
   
   /* sge_dstring_sprintf_append */
   printf("\nchecking sge_dstring_sprintf_append\n");
   sge_dstring_clear(sb);
   sge_dstring_sprintf_append(NULL, "test %s", "string");
   sge_dstring_sprintf_append(sb, NULL);
   sge_dstring_sprintf_append(sb, "test %s", "string");
   sge_dstring_sprintf_append(sb, " appended test %s", "string");
   check_dstring(sb);
   
   /* sge_dstring_clear */
   printf("\nchecking sge_dstring_clear\n");
   sge_dstring_clear(NULL);
   sge_dstring_clear(sb);
   check_dstring(sb);
   
   /* sge_dstring_free */
   printf("\nchecking sge_dstring_free\n");
   sge_dstring_free(NULL);
   sge_dstring_free(sb);
   check_dstring(sb);
   
   /* sge_dstring_get_string */
   printf("\nchecking sge_dstring_get_string\n");
   sge_dstring_clear(sb);
   sge_dstring_append(sb, "test string");
   { 
      const char *result;

      result = sge_dstring_get_string(NULL);
      printf("sge_dstring_get_string(NULL) = %s\n", 
             result == NULL ? "NULL" : result);
      result = sge_dstring_get_string(sb);
      printf("sge_dstring_get_string(sb) = %s\n", 
             result == NULL ? "NULL" : result);
   }
   
   /* sge_dstring_copy_string */
   printf("\nchecking sge_dstring_copy_string\n");
   sge_dstring_copy_string(NULL, NULL);
   sge_dstring_copy_string(sb, NULL);
   sge_dstring_copy_string(NULL, "new test string");
   sge_dstring_copy_string(sb, "new test string");
   check_dstring(sb);
   
   /* sge_dstring_copy_dstring 
    * check only NULL pointer behaviour, it just calls sge_dstring_copy_string
    */
   printf("\nchecking sge_dstring_copy_dstring\n");
   sge_dstring_copy_dstring(NULL, NULL);
   sge_dstring_copy_dstring(sb, NULL);
   check_dstring(sb);
   
   /* sge_dstring_strlen */
   printf("\nchecking sge_dstring_strlen\n");
   {
      int len;
      sge_dstring_copy_string(sb, "test string");
      len = sge_dstring_strlen(NULL);
      printf("sge_dstring_strlen(NULL) = %d\n", len);
      len = sge_dstring_strlen(sb);
      printf("sge_dstring_strlen(sb) = %d\n", len);
   }
   
   /* sge_dstring_remaining */
   printf("\nchecking sge_dstring_remaining\n");
   {
      int len;
      sge_dstring_copy_string(sb, "test string");
      len = sge_dstring_remaining(NULL);
      printf("sge_dstring_remaining(NULL) = %d\n", len);
      len = sge_dstring_remaining(sb);
      printf("sge_dstring_remaining(sb) = %d\n", len);
   }

   return ret;
}