/* Runs the 'file' command on the given file, and returns the output * (a verbose description of the file type) */ static char * get_file_type_desc( const char *filename ) { static char *cmd_output = NULL; FILE *cmd; double t0; int len, c, i = 0; char *cmd_line; /* Allocate output buffer */ RESIZE(cmd_output, strlen( filename ) + 1024, char); /* Construct command line */ len = strlen( FILE_COMMAND ) + strlen( filename ) - 1; cmd_line = NEW_ARRAY(char, len); sprintf( cmd_line, FILE_COMMAND, filename ); /* Open command stream */ cmd = popen( cmd_line, "r" ); xfree( cmd_line ); if (cmd == NULL) { strcpy( cmd_output, _("Could not execute 'file' command") ); return cmd_output; } /* Read loop */ t0 = xgettime( ); while (!feof( cmd )) { /* Read command's stdout */ c = fgetc( cmd ); if (c != EOF) cmd_output[i++] = c; /* Check for timeout condition */ if ((xgettime( ) - t0) > 5.0) { fclose( cmd ); /* Is this allowed? */ strcpy( cmd_output, _("('file' command timed out)") ); return cmd_output; } /* Keep the GUI responsive */ gui_update( ); } pclose( cmd ); cmd_output[i] = '\0'; len = strlen( filename ); if (!strncmp( filename, cmd_output, len )) { /* Remove prepended "filename: " from output */ return &cmd_output[len + 2]; } return cmd_output; }
/* This checks if the widget associated with the given adjustment is * currently busy redrawing/reconfiguring itself, or is in steady state * (this is used when animating widgets to avoid changing the adjustment * too often, otherwise the widget can't keep up and things slow down) */ boolean gui_adjustment_widget_busy( GtkAdjustment *adj ) { static const double threshold = (1.0 / 18.0); double t_prev; double t_now; double *tp; /* ---- HACK ALERT ---- * This doesn't actually check GTK+ internals-- I'm not sure which * ones are relevant here. This just checks the amount of time that * has passed since the last time the function was called with the * same adjustment and returned FALSE, and if it's below a certain * threshold, the object is considered "busy" (returning TRUE) */ t_now = xgettime( ); tp = gtk_object_get_data( GTK_OBJECT(adj), "t_prev" ); if (tp == NULL) { tp = NEW(double); *tp = t_now; gtk_object_set_data_full( GTK_OBJECT(adj), "t_prev", tp, _xfree ); return FALSE; }