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