~ubuntu-branches/ubuntu/vivid/libsdl2/vivid

« back to all changes in this revision

Viewing changes to src/filesystem/unix/SDL_sysfilesystem.c

  • Committer: Package Import Robot
  • Author(s): Manuel A. Fernandez Montecelo, Felix Geyer
  • Date: 2013-12-28 12:31:19 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20131228123119-e0k27gckmnzskfgb
Tags: 2.0.1+dfsg1-1
* New upstream release (Closes: #728974)
  - Remove patch applied upstream:
    bug-723797-false_positives_in_mouse_wheel_code.patch
* Bump Standards-Version to 3.9.5, no changes needed.

[ Felix Geyer ]
* Import upstream gpg key for uscan to verify the orig tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Simple DirectMedia Layer
 
3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
 
4
 
 
5
  This software is provided 'as-is', without any express or implied
 
6
  warranty.  In no event will the authors be held liable for any damages
 
7
  arising from the use of this software.
 
8
 
 
9
  Permission is granted to anyone to use this software for any purpose,
 
10
  including commercial applications, and to alter it and redistribute it
 
11
  freely, subject to the following restrictions:
 
12
 
 
13
  1. The origin of this software must not be misrepresented; you must not
 
14
     claim that you wrote the original software. If you use this software
 
15
     in a product, an acknowledgment in the product documentation would be
 
16
     appreciated but is not required.
 
17
  2. Altered source versions must be plainly marked as such, and must not be
 
18
     misrepresented as being the original software.
 
19
  3. This notice may not be removed or altered from any source distribution.
 
20
*/
 
21
#include "SDL_config.h"
 
22
 
 
23
#ifdef SDL_FILESYSTEM_UNIX
 
24
 
 
25
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
26
/* System dependent filesystem routines                                */
 
27
 
 
28
#include <errno.h>
 
29
#include <stdio.h>
 
30
#include <unistd.h>
 
31
#include <stdlib.h>
 
32
#include <sys/stat.h>
 
33
#include <sys/types.h>
 
34
#include <limits.h>
 
35
 
 
36
#ifdef __FREEBSD__
 
37
#include <sys/sysctl.h>
 
38
#endif
 
39
 
 
40
#include "SDL_error.h"
 
41
#include "SDL_stdinc.h"
 
42
#include "SDL_filesystem.h"
 
43
 
 
44
static char *
 
45
readSymLink(const char *path)
 
46
{
 
47
    char *retval = NULL;
 
48
    ssize_t len = 64;
 
49
    ssize_t rc = -1;
 
50
 
 
51
    while (1)
 
52
    {
 
53
        char *ptr = (char *) SDL_realloc(retval, (size_t) len);
 
54
        if (ptr == NULL) {
 
55
            SDL_OutOfMemory();
 
56
            break;
 
57
        }
 
58
 
 
59
        retval = ptr;
 
60
 
 
61
        rc = readlink(path, retval, len);
 
62
        if (rc == -1) {
 
63
            break;  /* not a symlink, i/o error, etc. */
 
64
        } else if (rc < len) {
 
65
            retval[rc] = '\0';  /* readlink doesn't null-terminate. */
 
66
            return retval;  /* we're good to go. */
 
67
        }
 
68
 
 
69
        len *= 2;  /* grow buffer, try again. */
 
70
    }
 
71
 
 
72
    SDL_free(retval);
 
73
    return NULL;
 
74
}
 
75
 
 
76
 
 
77
char *
 
78
SDL_GetBasePath(void)
 
79
{
 
80
    char *retval = NULL;
 
81
 
 
82
#if defined(__FREEBSD__)
 
83
    char fullpath[PATH_MAX];
 
84
    size_t buflen = sizeof (fullpath);
 
85
    const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
 
86
    if (sysctl(mib, SDL_arraysize(mib), fullpath, &buflen, NULL, 0) != -1) {
 
87
        retval = SDL_strdup(fullpath);
 
88
        if (!retval) {
 
89
            SDL_OutOfMemory();
 
90
            return NULL;
 
91
        }
 
92
    }
 
93
#elif defined(__SOLARIS__)
 
94
    const char *path = getexecname();
 
95
    if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */
 
96
        retval = SDL_strdup(path);
 
97
        if (!retval) {
 
98
            SDL_OutOfMemory();
 
99
            return NULL;
 
100
        }
 
101
    }
 
102
#endif
 
103
 
 
104
    /* is a Linux-style /proc filesystem available? */
 
105
    if (!retval && (access("/proc", F_OK) == 0)) {
 
106
#if defined(__FREEBSD__)
 
107
        retval = readSymLink("/proc/curproc/file");
 
108
#elif defined(__NETBSD__)
 
109
        retval = readSymLink("/proc/curproc/exe");
 
110
#else
 
111
        retval = readSymLink("/proc/self/exe");  /* linux. */
 
112
#endif
 
113
        if (retval == NULL) {
 
114
            /* older kernels don't have /proc/self ... try PID version... */
 
115
            char path[64];
 
116
            const int rc = (int) SDL_snprintf(path, sizeof(path),
 
117
                                              "/proc/%llu/exe",
 
118
                                              (unsigned long long) getpid());
 
119
            if ( (rc > 0) && (rc < sizeof(path)) ) {
 
120
                retval = readSymLink(path);
 
121
            }
 
122
        }
 
123
    }
 
124
 
 
125
    /* If we had access to argv[0] here, we could check it for a path,
 
126
        or troll through $PATH looking for it, too. */
 
127
 
 
128
    if (retval != NULL) { /* chop off filename. */
 
129
        char *ptr = SDL_strrchr(retval, '/');
 
130
        if (ptr != NULL) {
 
131
            *(ptr+1) = '\0';
 
132
        } else {  /* shouldn't happen, but just in case... */
 
133
            SDL_free(retval);
 
134
            retval = NULL;
 
135
        }
 
136
    }
 
137
 
 
138
    if (retval != NULL) {
 
139
        /* try to shrink buffer... */
 
140
        char *ptr = (char *) SDL_realloc(retval, strlen(retval) + 1);
 
141
        if (ptr != NULL)
 
142
            retval = ptr;  /* oh well if it failed. */
 
143
    }
 
144
 
 
145
    return retval;
 
146
}
 
147
 
 
148
char *
 
149
SDL_GetPrefPath(const char *org, const char *app)
 
150
{
 
151
    /*
 
152
     * We use XDG's base directory spec, even if you're not on Linux.
 
153
     *  This isn't strictly correct, but the results are relatively sane
 
154
     *  in any case.
 
155
     *
 
156
     * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
 
157
     */
 
158
    const char *envr = SDL_getenv("XDG_DATA_HOME");
 
159
    const char *append;
 
160
    char *retval = NULL;
 
161
    char *ptr = NULL;
 
162
    size_t len = 0;
 
163
 
 
164
    if (!envr) {
 
165
        /* You end up with "$HOME/.local/share/Game Name 2" */
 
166
        envr = SDL_getenv("HOME");
 
167
        if (!envr) {
 
168
            /* we could take heroic measures with /etc/passwd, but oh well. */
 
169
            SDL_SetError("neither XDG_DATA_HOME nor HOME environment is set");
 
170
            return NULL;
 
171
        }
 
172
        append = "/.local/share/";
 
173
    } else {
 
174
        append = "/";
 
175
    }
 
176
 
 
177
    len = SDL_strlen(envr);
 
178
    if (envr[len - 1] == '/')
 
179
        append += 1;
 
180
 
 
181
    len += SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
 
182
    retval = (char *) SDL_malloc(len);
 
183
    if (!retval) {
 
184
        SDL_OutOfMemory();
 
185
        return NULL;
 
186
    }
 
187
 
 
188
    SDL_snprintf(retval, len, "%s%s%s/%s/", envr, append, org, app);
 
189
 
 
190
    for (ptr = retval+1; *ptr; ptr++) {
 
191
        if (*ptr == '/') {
 
192
            *ptr = '\0';
 
193
            if (mkdir(retval, 0700) != 0 && errno != EEXIST)
 
194
                goto error;
 
195
            *ptr = '/';
 
196
        }
 
197
    }
 
198
    if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
 
199
error:
 
200
        SDL_SetError("Couldn't create directory '%s': ", retval, strerror(errno));
 
201
        SDL_free(retval);
 
202
        return NULL;
 
203
    }
 
204
 
 
205
    return retval;
 
206
}
 
207
 
 
208
#endif /* SDL_FILESYSTEM_UNIX */
 
209
 
 
210
/* vi: set ts=4 sw=4 expandtab: */