93 lines
2.4 KiB
C
93 lines
2.4 KiB
C
|
//
|
||
|
// An implementation of shm_open(), shm_unlink() from the GNU C Library
|
||
|
//
|
||
|
// Copyright (C) 2001,2002,2005 Free Software Foundation, Inc.
|
||
|
// Copyright (C) 2018 Leonid Plyushch
|
||
|
//
|
||
|
// This library is free software; you can redistribute it and/or
|
||
|
// modify it under the terms of the GNU Lesser General Public
|
||
|
// License as published by the Free Software Foundation; either
|
||
|
// version 2.1 of the License, or (at your option) any later version.
|
||
|
//
|
||
|
// This library is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
// Lesser General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Lesser General Public
|
||
|
// License along with this library; if not, write to the Free Software
|
||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
//
|
||
|
|
||
|
#define _GNU_SOURCE
|
||
|
#include <errno.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#ifdef __ANDROID__
|
||
|
#define SHMDIR "/data/data/com.termux/files/usr/tmp/"
|
||
|
#else
|
||
|
#define SHMDIR "/dev/shm/"
|
||
|
#endif
|
||
|
|
||
|
int shm_open(const char *name, int oflag, mode_t mode) {
|
||
|
size_t namelen;
|
||
|
char *fname;
|
||
|
int fd;
|
||
|
|
||
|
/* Construct the filename. */
|
||
|
while (name[0] == '/') ++name;
|
||
|
|
||
|
if (name[0] == '\0') {
|
||
|
/* The name "/" is not supported. */
|
||
|
errno = EINVAL;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
namelen = strlen(name);
|
||
|
fname = (char *) alloca(sizeof(SHMDIR) - 1 + namelen + 1);
|
||
|
memcpy(fname, SHMDIR, sizeof(SHMDIR) - 1);
|
||
|
memcpy(fname + sizeof(SHMDIR) - 1, name, namelen + 1);
|
||
|
|
||
|
fd = open(fname, oflag, mode);
|
||
|
if (fd != -1) {
|
||
|
/* We got a descriptor. Now set the FD_CLOEXEC bit. */
|
||
|
int flags = fcntl(fd, F_GETFD, 0);
|
||
|
flags |= FD_CLOEXEC;
|
||
|
flags = fcntl(fd, F_SETFD, flags);
|
||
|
|
||
|
if (flags == -1) {
|
||
|
/* Something went wrong. We cannot return the descriptor. */
|
||
|
int save_errno = errno;
|
||
|
close(fd);
|
||
|
fd = -1;
|
||
|
errno = save_errno;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return fd;
|
||
|
}
|
||
|
|
||
|
int shm_unlink(const char *name) {
|
||
|
size_t namelen;
|
||
|
char *fname;
|
||
|
|
||
|
/* Construct the filename. */
|
||
|
while (name[0] == '/') ++name;
|
||
|
|
||
|
if (name[0] == '\0') {
|
||
|
/* The name "/" is not supported. */
|
||
|
errno = EINVAL;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
namelen = strlen(name);
|
||
|
fname = (char *) alloca(sizeof(SHMDIR) - 1 + namelen + 1);
|
||
|
memcpy(fname, SHMDIR, sizeof(SHMDIR) - 1);
|
||
|
memcpy(fname + sizeof(SHMDIR) - 1, name, namelen + 1);
|
||
|
|
||
|
return unlink(fname);
|
||
|
}
|