bl/spawn.c
author ali <ali@juiblex.co.uk>
Mon Jan 30 23:32:47 2012 +0000 (2012-01-30)
changeset 11 4a80c6053a66
parent 9 6a13fe0fc19e
permissions -rw-r--r--
Use Unicode output on MS-Windows consoles
     1 #include <stdlib.h>
     2 #include <stdio.h>
     3 #ifndef WIN32
     4 #include <sys/wait.h>
     5 #endif
     6 #include <bl/bl.h>
     7 
     8 #define SPAWN_BUFSIZE	128
     9 
    10 gboolean spawn_sync(const char *working_directory,char **argv,
    11   char **standard_output,int *exit_status,GError **error)
    12 {
    13 /* Don't use g_spawn_sync on WIN32 for now to avoid needing the helper */
    14 #ifndef WIN32
    15     char *standard_error=NULL;
    16     gboolean retval;
    17     GSpawnFlags flags=G_SPAWN_SEARCH_PATH;
    18     if (!standard_output)
    19 	flags=G_SPAWN_STDOUT_TO_DEV_NULL;
    20     retval=g_spawn_sync(working_directory,argv,NULL,flags,NULL,NULL,
    21       standard_output,&standard_error,exit_status,error);
    22     if (standard_error)
    23 	g_printerr("%s",standard_error);
    24     g_free(standard_error);
    25     if (retval && exit_status)
    26 	*exit_status=WEXITSTATUS(*exit_status);
    27     return retval;
    28 #else
    29     FILE *fp;
    30     int i,r;
    31     size_t n,len;
    32     char *current_dir;
    33     GString *command_line,*string;
    34     if (working_directory)
    35     {
    36 	current_dir=g_get_current_dir();
    37 	if (g_chdir(working_directory)<0)
    38 	{
    39 	    g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
    40 	      "%s: %s",working_directory,g_strerror(errno));
    41 	    g_free(current_dir);
    42 	    return FALSE;
    43 	}
    44     }
    45     else
    46 	current_dir=NULL;
    47     command_line=g_string_new(NULL);
    48     for(i=0;argv[i];i++)
    49     {
    50 	if (i)
    51 	    g_string_append_c(command_line,' ');
    52 	g_string_append(command_line,argv[i]);
    53     }
    54     fp=popen(command_line->str,"r");
    55     g_string_free(command_line,TRUE);
    56     if (current_dir)
    57     {
    58 	if (g_chdir(current_dir)<0)
    59 	    g_error("Failed to restore current directory: %s",
    60 	      g_strerror(errno));
    61 	g_free(current_dir);
    62     }
    63     if (!fp)
    64     {
    65 	g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
    66 	  "%s: %s",command_line->str,g_strerror(errno));
    67 	return FALSE;
    68     }
    69     string=g_string_new(NULL);
    70     do
    71     {
    72 	len=string->len;
    73 	g_string_set_size(string,len+SPAWN_BUFSIZE);
    74 	n=fread(string->str+len,1,SPAWN_BUFSIZE,fp);
    75 	if (n<0)
    76 	{
    77 	    g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
    78 	      "Error reading from bookloupe: %s",g_strerror(errno));
    79 	    (void)pclose(fp);
    80 	    g_string_free(string,TRUE);
    81 	    return FALSE;
    82 	}
    83 	g_string_set_size(string,len+n);
    84     } while(n);
    85     r=pclose(fp);
    86     if (r<0)
    87     {
    88 	g_set_error(error,G_FILE_ERROR,g_file_error_from_errno(errno),
    89 	  "Error reading from bookloupe: %s",g_strerror(errno));
    90 	g_string_free(string,TRUE);
    91 	return FALSE;
    92     }
    93     else
    94     {
    95 	if (exit_status)
    96 	    *exit_status=r;
    97 	if (standard_output)
    98 	    *standard_output=g_string_free(string,FALSE);
    99 	else
   100 	    g_string_free(string,TRUE);
   101 	return TRUE;
   102     }
   103 #endif
   104 }