Skip to content

Commit 0d73ab9

Browse files
committed
Fixed segfault on appimaged as described on issue #334
1 parent 8cbfebc commit 0d73ab9

File tree

1 file changed

+54
-33
lines changed

1 file changed

+54
-33
lines changed

appimaged.c

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,44 @@
11
/**************************************************************************
2-
*
2+
*
33
* Copyright (c) 2004-16 Simon Peter
4-
*
4+
*
55
* All Rights Reserved.
6-
*
6+
*
77
* Permission is hereby granted, free of charge, to any person obtaining a copy
88
* of this software and associated documentation files (the "Software"), to deal
99
* in the Software without restriction, including without limitation the rights
1010
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111
* copies of the Software, and to permit persons to whom the Software is
1212
* furnished to do so, subject to the following conditions:
13-
*
13+
*
1414
* The above copyright notice and this permission notice shall be included in
1515
* all copies or substantial portions of the Software.
16-
*
16+
*
1717
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
* THE SOFTWARE.
24-
*
24+
*
2525
**************************************************************************/
2626

2727
#ident "AppImage by Simon Peter, http://appimage.org/"
2828

2929
/*
30-
* Optional daempon to watch directories for AppImages
30+
* Optional daempon to watch directories for AppImages
3131
* and register/unregister them with the system
32-
*
32+
*
3333
* TODO (feel free to send pull requests):
3434
* - Switch to https://developer.gnome.org/gio/stable/GFileMonitor.html (but with subdirectories)
3535
* which would drop the dependency on libinotifytools.so.0
36-
* - Add and remove subdirectories on the fly at runtime -
36+
* - Add and remove subdirectories on the fly at runtime -
3737
* see https://github.com/paragone/configure-via-inotify/blob/master/inotify/src/inotifywatch.c
3838
*/
3939

4040
#include <stdio.h>
41+
#include <errno.h>
4142
#include <string.h>
4243
#include <stdlib.h>
4344
#include <unistd.h>
@@ -75,8 +76,8 @@ static GOptionEntry entries[] =
7576
#define EXCLUDE_CHUNK 1024
7677
#define WR_EVENTS (IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF)
7778

78-
/* Run the actual work in treads;
79-
* pthread allows to pass only one argument to the thread function,
79+
/* Run the actual work in treads;
80+
* pthread allows to pass only one argument to the thread function,
8081
* hence we use a struct as the argument in which the real arguments are */
8182
struct arg_struct {
8283
char* path;
@@ -104,12 +105,32 @@ void initially_register(const char *name, int level)
104105
{
105106
DIR *dir;
106107
struct dirent *entry;
107-
108-
if (!(dir = opendir(name)))
109-
fprintf(stderr, "opendir error\n");
110-
if (!(entry = readdir(dir)))
111-
fprintf(stderr, "readdir error\n");
112-
108+
109+
if (!(dir = opendir(name))) {
110+
if (verbose) {
111+
if (errno == EACCES) {
112+
g_print("_________________________\n");
113+
g_print("Permission denied on dir '%s'\n", name);
114+
}
115+
else {
116+
g_print("_________________________\n");
117+
g_print("Failed to open dir '%s'\n", name);
118+
}
119+
}
120+
closedir(dir);
121+
exit(0);
122+
return;
123+
}
124+
125+
if (!(entry = readdir(dir))) {
126+
if (verbose) {
127+
g_print("_________________________\n");
128+
g_print("Invalid directory stream descriptor '%s'\n", name);
129+
}
130+
closedir(dir);
131+
return;
132+
}
133+
113134
do {
114135
if (entry->d_type == DT_DIR) {
115136
char path[1024];
@@ -143,7 +164,7 @@ int add_dir_to_watch(char *directory)
143164
if(!inotifytools_watch_recursively(directory, WR_EVENTS) ) {
144165
fprintf(stderr, "%s\n", strerror(inotifytools_error()));
145166
exit(1);
146-
167+
147168
}
148169
initially_register(directory, 0);
149170
}
@@ -153,7 +174,7 @@ void handle_event(struct inotify_event *event)
153174
{
154175
int ret;
155176
gchar *absolute_path = g_build_path(G_DIR_SEPARATOR_S, inotifytools_filename_from_wd(event->wd), event->name, NULL);
156-
177+
157178
if(event->mask & IN_CLOSE_WRITE | event->mask & IN_MOVED_TO){
158179
if(g_file_test(absolute_path, G_FILE_TEST_IS_REGULAR)){
159180
pthread_t some_thread;
@@ -167,7 +188,7 @@ void handle_event(struct inotify_event *event)
167188
}
168189
}
169190
}
170-
191+
171192
if(event->mask & IN_MOVED_FROM | event->mask & IN_DELETE){
172193
pthread_t some_thread;
173194
struct arg_struct args;
@@ -179,23 +200,23 @@ void handle_event(struct inotify_event *event)
179200
pthread_join(some_thread, NULL);
180201
}
181202
}
182-
203+
183204
/* Too many FS events were received, some event notifications were potentially lost */
184205
if (event->mask & IN_Q_OVERFLOW){
185206
printf ("Warning: AN OVERFLOW EVENT OCCURRED\n");
186207
}
187-
208+
188209
if(event->mask & IN_IGNORED){
189210
printf ("Warning: AN IN_IGNORED EVENT OCCURRED\n");
190211
}
191-
212+
192213
}
193214

194215
int main(int argc, char ** argv) {
195-
216+
196217
GError *error = NULL;
197218
GOptionContext *context;
198-
219+
199220
context = g_option_context_new ("");
200221
g_option_context_add_main_entries (context, entries, NULL);
201222
// g_option_context_add_group (context, gtk_get_option_group (TRUE));
@@ -209,7 +230,7 @@ int main(int argc, char ** argv) {
209230
fprintf(stderr,"Version: %s\n", VERSION_NUMBER);
210231
exit(0);
211232
}
212-
233+
213234
if ( !inotifytools_initialize()){
214235
fprintf(stderr, "inotifytools_initialize error\n");
215236
exit(1);
@@ -223,7 +244,7 @@ int main(int argc, char ** argv) {
223244
gchar *global_systemd_file = "/usr/lib/systemd/user/appimaged.service";
224245
gchar *partial_path = g_strdup_printf("autostart/appimagekit-appimaged.desktop");
225246
gchar *destination = g_build_filename(g_get_user_config_dir(), partial_path, NULL);
226-
247+
227248
if(uninstall){
228249
if(g_file_test (installed_appimaged_location, G_FILE_TEST_EXISTS))
229250
fprintf(stderr, "* Please delete %s\n", installed_appimaged_location);
@@ -232,8 +253,8 @@ int main(int argc, char ** argv) {
232253
fprintf(stderr, "* To remove all AppImage desktop integration, run\n");
233254
fprintf(stderr, " find ~/.local/share -name 'appimagekit_*' -exec rm {} \\;\n\n");
234255
exit(0);
235-
}
236-
256+
}
257+
237258
if(install != NULL){
238259
if(((appimage_location != NULL)) && ((own_desktop_file_location != NULL))){
239260
printf("Running from within %s\n", appimage_location);
@@ -283,7 +304,7 @@ int main(int argc, char ** argv) {
283304
exit(1);
284305
}
285306
}
286-
307+
287308
add_dir_to_watch(user_bin_dir);
288309
add_dir_to_watch(g_build_filename(g_get_home_dir(), "/Downloads", NULL));
289310
add_dir_to_watch(g_build_filename(g_get_home_dir(), "/bin", NULL));
@@ -293,15 +314,15 @@ int main(int argc, char ** argv) {
293314
add_dir_to_watch(g_build_filename("/run/archiso/img_dev/Applications", NULL)); // Antergos Live media
294315
add_dir_to_watch(g_build_filename("/opt", NULL));
295316
add_dir_to_watch(g_build_filename("/usr/local/bin", NULL));
296-
317+
297318
struct inotify_event * event = inotifytools_next_event(-1);
298319
while (event) {
299320
if(verbose){
300321
inotifytools_printf(event, "%w%f %e\n");
301322
}
302-
fflush(stdout);
323+
fflush(stdout);
303324
handle_event(event);
304-
fflush(stdout);
325+
fflush(stdout);
305326
event = inotifytools_next_event(-1);
306327
}
307328
}

0 commit comments

Comments
 (0)