r180: Updated filer action code to use exec instead of system (stops problems
[rox-filer/ma.git] / ROX-Filer / src / support.c
blob87419e9f4a949212c03da42fe3dac3ad7cec65da
1 /*
2 * $Id$
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)
10 * any later version.
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
15 * more details.
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
22 /* support.c - (non-GUI) useful routines */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <sys/param.h>
28 #include <unistd.h>
29 #include <pwd.h>
30 #include <grp.h>
31 #include <fcntl.h>
32 #include <sys/wait.h>
34 #include <glib.h>
36 #include "main.h"
37 #include "support.h"
39 /* Static prototypes */
42 /* Like g_strdup, but does realpath() too (if possible) */
43 char *pathdup(char *path)
45 char real[MAXPATHLEN];
47 g_return_val_if_fail(path != NULL, NULL);
49 if (realpath(path, real))
50 return g_strdup(real);
52 return g_strdup(path);
55 /* Join the path to the leaf (adding a / between them) and
56 * return a pointer to a buffer with the result. Buffer is valid until
57 * the next call to make_path.
59 GString *make_path(char *dir, char *leaf)
61 static GString *buffer = NULL;
63 if (!buffer)
64 buffer = g_string_new(NULL);
66 g_return_val_if_fail(dir != NULL, buffer);
67 g_return_val_if_fail(leaf != NULL, buffer);
69 g_string_sprintf(buffer, "%s%s%s",
70 dir,
71 dir[0] == '/' && dir[1] == '\0' ? "" : "/",
72 leaf);
74 return buffer;
77 /* Return our complete host name */
78 char *our_host_name()
80 static char *name = NULL;
82 if (!name)
84 char buffer[4096];
86 g_return_val_if_fail(gethostname(buffer, 4096) == 0,
87 "localhost");
89 buffer[4095] = '\0';
90 name = g_strdup(buffer);
93 return name;
96 /* fork() and run a new program.
97 * Returns the new PID, or 0 on failure.
99 pid_t spawn(char **argv)
101 return spawn_full(argv, NULL);
104 /* As spawn(), but cd to dir first (if dir is non-NULL) */
105 pid_t spawn_full(char **argv, char *dir)
107 int child;
109 child = fork();
111 if (child == -1)
112 return 0; /* Failure */
113 else if (child == 0)
115 /* We are the child process */
116 if (dir)
117 if (chdir(dir))
118 fprintf(stderr, "chdir() failed: %s\n",
119 g_strerror(errno));
120 dup2(to_error_log, STDERR_FILENO);
121 fcntl(STDERR_FILENO, F_SETFD, 0);
122 execvp(argv[0], argv);
123 fprintf(stderr, "execvp(%s, ...) failed: %s\n",
124 argv[0],
125 g_strerror(errno));
126 _exit(0);
129 /* We are the parent */
130 return child;
133 void debug_free_string(void *data)
135 g_print("Freeing string '%s'\n", (char *) data);
136 g_free(data);
139 char *user_name(uid_t uid)
141 struct passwd *passwd;
142 GString *tmp;
143 char *retval;
145 passwd = getpwuid(uid);
146 if (passwd)
147 return passwd->pw_name;
148 tmp = g_string_new(NULL);
149 g_string_sprintf(tmp, "[%d]", (int) uid);
150 retval = tmp->str;
151 g_string_free(tmp, FALSE);
152 return retval;
155 char *group_name(gid_t gid)
157 struct group *group;
158 GString *tmp;
159 char *retval;
161 group = getgrgid(gid);
162 if (group)
163 return group->gr_name;
164 tmp = g_string_new(NULL);
165 g_string_sprintf(tmp, "[%d]", (int) gid);
166 retval = tmp->str;
167 g_string_free(tmp, FALSE);
168 return retval;
171 /* Return a string in the form '23Mb' in a static buffer valid until
172 * the next call.
174 char *format_size(unsigned long size)
176 static char *buffer = NULL;
177 char *units;
179 if (size >= 2048)
181 size >>= 10;
182 if (size >= 2048)
184 size >>= 10;
185 if (size >= 2048)
187 size >>= 10;
188 units = "Gb";
190 else
191 units = "Mb";
193 else
194 units = "K";
196 else
197 units = "bytes";
199 if (buffer)
200 g_free(buffer);
201 buffer = g_strdup_printf("%ld %s", size, units);
203 return buffer;
206 /* Fork and exec argv. Wait and return the child's exit status.
207 * -1 if spawn fails.
209 int fork_exec_wait(char **argv)
211 pid_t child;
212 int status = -1;
214 child = spawn_full(argv, NULL);
216 while (child)
218 if (waitpid(child, &status, 0) == -1)
220 if (errno != EINTR)
221 return -1;
223 else
224 break;
227 return status;