4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@ecs.soton.ac.uk>.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "gui_support.h"
36 /* Static prototypes */
37 static void write_data(gpointer data
, gint fd
, GdkInputCondition cond
);
39 typedef struct _PipedData PipedData
;
50 /****************************************************************
51 * EXTERNAL INTERFACE *
52 ****************************************************************/
55 /* An application has been double-clicked (or run in some other way) */
56 void run_app(char *path
)
59 char *argv
[] = {NULL
, NULL
};
61 apprun
= g_string_new(path
);
62 argv
[0] = g_string_append(apprun
, "/AppRun")->str
;
64 if (!spawn_full(argv
, home_dir
))
65 report_error(PROJECT
, "Failed to fork() child process");
67 g_string_free(apprun
, TRUE
);
70 /* Execute this program, passing all the URIs in the list as arguments.
71 * URIs that are files on the local machine will be passed as simple
72 * pathnames. The uri_list should be freed after this function returns.
74 void run_with_files(char *path
, GSList
*uri_list
)
80 if (stat(path
, &info
))
82 delayed_error(PROJECT
, _("Program not found - deleted?"));
86 argv
= g_malloc(sizeof(char *) * (g_slist_length(uri_list
) + 2));
88 if (S_ISDIR(info
.st_mode
))
89 argv
[argc
++] = make_path(path
, "AppRun")->str
;
95 char *uri
= (char *) uri_list
->data
;
98 local
= get_local_path(uri
);
100 argv
[argc
++] = local
;
103 uri_list
= uri_list
->next
;
108 if (!spawn_full(argv
, home_dir
))
109 delayed_error(PROJECT
, _("Failed to fork() child process"));
112 /* Run the program as '<path> -', piping the data to it via stdin.
113 * You can g_free() the data as soon as this returns.
115 void run_with_data(char *path
, gpointer data
, gulong length
)
117 char *argv
[] = {NULL
, "-", NULL
};
122 if (stat(path
, &info
))
124 delayed_error(PROJECT
, _("Program not found - deleted?"));
128 if (S_ISDIR(info
.st_mode
))
129 argv
[0] = make_path(path
, "AppRun")->str
;
135 delayed_error("pipe() failed", g_strerror(errno
));
138 close_on_exec(fds
[1], TRUE
);
139 close_on_exec(fds
[0], TRUE
);
144 delayed_error("fork() failed", g_strerror(errno
));
148 /* We are the child */
150 dup2(to_error_log
, STDERR_FILENO
);
151 close_on_exec(STDERR_FILENO
, FALSE
);
152 if (dup2(fds
[0], 0) == -1)
153 g_warning("dup2() failed: %s\n",
157 close_on_exec(0, FALSE
);
158 if (execv(argv
[0], argv
))
159 g_warning("execv(%s) failed: %s\n",
160 argv
[0], g_strerror(errno
));
164 /* We are the parent */
165 set_blocking(fds
[1], FALSE
);
166 pd
= g_new(PipedData
, 1);
167 pd
->data
= g_malloc(length
);
168 memcpy(pd
->data
, data
, length
);
171 pd
->tag
= gdk_input_add(fds
[1], GDK_INPUT_WRITE
,
180 /****************************************************************
181 * INTERNAL FUNCTIONS *
182 ****************************************************************/
185 static void write_data(gpointer data
, gint fd
, GdkInputCondition cond
)
187 PipedData
*pd
= (PipedData
*) data
;
189 while (pd
->sent
< pd
->length
)
193 sent
= write(fd
, pd
->data
+ pd
->sent
, pd
->length
- pd
->sent
);
199 delayed_error(_("ROX-Filer - Sending data to program"),
208 gdk_input_remove(pd
->tag
);