4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 1999, 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
29 #include "gui_support.h"
34 /* Static prototypes */
35 static void write_data(gpointer data
, gint fd
, GdkInputCondition cond
);
37 typedef struct _PipedData PipedData
;
48 /****************************************************************
49 * EXTERNAL INTERFACE *
50 ****************************************************************/
53 /* An application has been double-clicked (or run in some other way) */
54 void run_app(char *path
)
57 char *argv
[] = {NULL
, NULL
};
59 apprun
= g_string_new(path
);
60 argv
[0] = g_string_append(apprun
, "/AppRun")->str
;
62 if (!spawn_full(argv
, home_dir
))
63 report_error("ROX-Filer", "Failed to fork() child process");
65 g_string_free(apprun
, TRUE
);
68 /* Execute this program, passing all the URIs in the list as arguments.
69 * URIs that are files on the local machine will be passed as simple
70 * pathnames. The uri_list should be freed after this function returns.
72 void run_with_files(char *path
, GSList
*uri_list
)
78 if (stat(path
, &info
))
80 delayed_error("ROX-Filer", "Program not found - deleted?");
84 argv
= g_malloc(sizeof(char *) * (g_slist_length(uri_list
) + 2));
86 if (S_ISDIR(info
.st_mode
))
87 argv
[argc
++] = make_path(path
, "AppRun")->str
;
93 char *uri
= (char *) uri_list
->data
;
96 local
= get_local_path(uri
);
101 uri_list
= uri_list
->next
;
106 if (!spawn_full(argv
, home_dir
))
107 delayed_error("ROX-Filer", "Failed to fork() child process");
110 /* Run the program as '<path> -', piping the data to it via stdin.
111 * You can g_free() the data as soon as this returns.
113 void run_with_data(char *path
, gpointer data
, gulong length
)
115 char *argv
[] = {NULL
, "-", NULL
};
120 if (stat(path
, &info
))
122 delayed_error("ROX-Filer", "Program not found - deleted?");
126 if (S_ISDIR(info
.st_mode
))
127 argv
[0] = make_path(path
, "AppRun")->str
;
133 delayed_error("pipe() failed", g_strerror(errno
));
136 close_on_exec(fds
[1], TRUE
);
137 close_on_exec(fds
[0], TRUE
);
142 delayed_error("fork() failed", g_strerror(errno
));
146 /* We are the child */
148 dup2(to_error_log
, STDERR_FILENO
);
149 close_on_exec(STDERR_FILENO
, FALSE
);
150 if (dup2(fds
[0], 0) == -1)
151 g_warning("dup2() failed: %s\n",
155 close_on_exec(0, FALSE
);
156 if (execv(argv
[0], argv
))
157 g_warning("execv(%s) failed: %s\n",
158 argv
[0], g_strerror(errno
));
162 /* We are the parent */
163 set_blocking(fds
[1], FALSE
);
164 pd
= g_new(PipedData
, 1);
165 pd
->data
= g_malloc(length
);
166 memcpy(pd
->data
, data
, length
);
169 pd
->tag
= gdk_input_add(fds
[1], GDK_INPUT_WRITE
,
178 /****************************************************************
179 * INTERNAL FUNCTIONS *
180 ****************************************************************/
183 static void write_data(gpointer data
, gint fd
, GdkInputCondition cond
)
185 PipedData
*pd
= (PipedData
*) data
;
187 while (pd
->sent
< pd
->length
)
191 sent
= write(fd
, pd
->data
+ pd
->sent
, pd
->length
- pd
->sent
);
197 delayed_error("ROX-Filer - Sending data to program",
206 gdk_input_remove(pd
->tag
);