static void com_select_callback(int fd, const struct osl_object *query)
{
struct para_buffer pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
};
.flags = LS_FLAG_FULL_PATH | LS_FLAG_ADMISSIBLE_ONLY,
.mode = LS_MODE_VERBOSE,
};
- struct para_buffer pb = {.max_size = SHMMAX - 1};
+ struct para_buffer pb = {.max_size = shm_get_shmmax() - 1};
time_t current_time;
int ret;
free(status_items);
status_items = pb.buf;
memset(&pb, 0, sizeof(pb));
- pb.max_size = SHMMAX - 1;
+ pb.max_size = shm_get_shmmax() - 1;
pb.flags = PBF_SIZE_PREFIX;
ret = print_list_item(&d, &opts, &pb, current_time);
if (ret < 0) {
{
struct ls_options *opts = query->data;
char *p, *pattern_start = (char *)query->data + sizeof(*opts);
- struct para_buffer b = {.max_size = SHMMAX,
+ struct para_buffer b = {.max_size = shm_get_shmmax(),
.flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0,
.max_size_handler = pass_buffer_as_shm, .private_data = &fd};
int i = 0, ret;
char afsi_buf[AFSI_SIZE];
uint32_t flags = read_u32(buf + CAB_FLAGS_OFFSET);
struct afs_info default_afsi = {.last_played = 0};
- struct para_buffer msg = {.max_size = SHMMAX,
+ struct para_buffer msg = {.max_size = shm_get_shmmax(),
.max_size_handler = pass_buffer_as_shm, .private_data = &fd};
uint16_t afhi_offset, chunks_offset;
{
struct touch_action_data tad = {.cto = query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
{
struct com_rm_action_data crd = {.flags = *(uint32_t *)query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
struct cpsi_action_data cad = {
.flags = *(unsigned *)query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
void aft_check_callback(int fd, __a_unused const struct osl_object *query)
{
struct para_buffer pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
};
struct lsatt_action_data laad = {
.flags = *(unsigned *) query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
char *p;
int ret = 1, ret2 = 0;
struct para_buffer pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
};
struct osl_object obj = {.data = old, .size = size};
struct osl_row *row;
struct para_buffer pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
};
struct remove_attribute_action_data raad = {
.num_removed = 0,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
struct lsblob_action_data lbad = {
.flags = *(uint32_t *)query->data,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
struct rmblob_data rmbd = {
.num_removed = 0,
.pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
}
#include "para.h"
#include "error.h"
#include "ipc.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
int ret = shmdt(addr);
return ret < 0? -ERRNO_TO_PARA_ERROR(errno) : 1;
}
+
+# if defined __FreeBSD__ || defined __NetBSD__
+# define SYSCTL_SHMMAX_VARIABLE "kern.ipc.shmmax"
+# elif defined __APPLE__
+# define SYSCTL_SHMMAX_VARIABLE "kern.sysv.shmmax"
+# else
+# undef SYSCTL_SHMMAX_VARIABLE
+# endif
+
+size_t shm_get_shmmax(void)
+{
+ static size_t shmmax;
+
+ if (shmmax > 0) /* only dance once */
+ return shmmax;
+#ifdef __linux__ /* get it from proc fs */
+ {
+ int fd = open("/proc/sys/kernel/shmmax", O_RDONLY);
+ if (fd >= 0) {
+ char buf[100] = "";
+ int ret = read(fd, buf, sizeof(buf) - 1);
+ if (ret > 0) {
+ buf[ret] = '\0';
+ shmmax = strtoul(buf, NULL, 10);
+ }
+ }
+ }
+#elif defined SYSCTL_SHMMAX_VARIABLE
+ {
+ size_t len = sizeof(shmmax);
+ sysctlbyname(SYSCTL_SHMMAX_VARIABLE, &shmmax, &len, NULL, 0);
+ }
+#elif defined SHMMAX
+ shmmax = SHMMAX;
+#endif
+ if (shmmax == 0) {
+ PARA_WARNING_LOG("unable to determine shmmax\n");
+ shmmax = 65535; /* last ressort */
+ }
+ PARA_INFO_LOG("shmmax: %zu\n", shmmax);
+ return shmmax;
+}
int shm_attach(int id, enum shm_attach_mode mode, void **result);
int shm_detach(void *addr);
int shm_destroy(int id);
-
-#ifndef SHMMAX
-#define SHMMAX 65535
-#endif
+size_t shm_get_shmmax(void);
void mood_check_callback(int fd, __a_unused const struct osl_object *query)
{
struct para_buffer pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
};
void playlist_check_callback(int fd, __a_unused const struct osl_object *query)
{
struct para_buffer pb = {
- .max_size = SHMMAX,
+ .max_size = shm_get_shmmax(),
.private_data = &fd,
.max_size_handler = pass_buffer_as_shm
};