diff -Naur busybox-1.13.3.orig/init/init.c busybox-1.13.3/init/init.c --- busybox-1.13.3.orig/init/init.c 2009-05-29 17:37:17.000000000 +0200 +++ busybox-1.13.3/init/init.c 2009-05-29 17:31:19.000000000 +0200 @@ -820,6 +820,87 @@ } #endif +#if defined(__FreeBSD_kernel__) +#define BAD_OPEN_MESSAGE \ +"Error: /proc must be mounted\n" \ +" To mount /proc at boot you need an /etc/fstab line like:\n" \ +" /proc /proc proc defaults\n" \ +" In the meantime, run \"mount /proc /proc -t proc\"\n" + +#define MEMINFO_FILE "/proc/meminfo" +static int meminfo_fd = -1; + +static char buf[1024]; + +/* This macro opens filename only if necessary and seeks to 0 so + * that successive calls to the functions are more efficient. + * It also reads the current contents of the file into the global buf. + */ +#define FILE_TO_BUF(filename, fd) do{ \ + static int local_n; \ + if (fd == -1 && (fd = open(filename, O_RDONLY)) == -1) { \ + fputs(BAD_OPEN_MESSAGE, stderr); \ + fflush(NULL); \ + _exit(102); \ + } \ + lseek(fd, 0L, SEEK_SET); \ + if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) { \ + perror(filename); \ + fflush(NULL); \ + _exit(103); \ + } \ + buf[local_n] = '\0'; \ +}while(0) + +typedef struct mem_table_struct { + const char *name; /* memory type name */ + unsigned long *slot; /* slot in return struct */ +} mem_table_struct; + +static int compare_mem_table_structs(const void *a, const void *b){ + return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name); +} + +/* old but still kicking -- the important stuff */ +unsigned long kb_main_total; + +static void meminfo(void){ + char namebuf[16]; /* big enough to hold any row name */ + mem_table_struct findme = { namebuf, NULL}; + mem_table_struct *found; + char *head; + char *tail; + static const mem_table_struct mem_table[] = { + {"MemTotal", &kb_main_total}, // important + }; + const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct); + + FILE_TO_BUF(MEMINFO_FILE,meminfo_fd); + + head = buf; + for(;;){ + tail = strchr(head, ':'); + if(!tail) break; + *tail = '\0'; + if(strlen(head) >= sizeof(namebuf)){ + head = tail+1; + goto nextline; + } + strcpy(namebuf,head); + found = bsearch(&findme, mem_table, mem_table_count, + sizeof(mem_table_struct), compare_mem_table_structs + ); + head = tail+1; + if(!found) goto nextline; + *(found->slot) = strtoul(head,&tail,10); +nextline: + tail = strchr(head, '\n'); + if(!tail) break; + head = tail+1; + } +} +#endif + int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int init_main(int argc UNUSED_PARAM, char **argv) { @@ -881,10 +962,19 @@ /* Make sure there is enough memory to do something useful. */ if (ENABLE_SWAPONOFF) { +#if defined(__linux__) struct sysinfo info; if (!sysinfo(&info) && (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024) +#elif defined(__FreeBSD_kernel__) +# define S(X) ( ((unsigned long long)(X) << 10) >> shift) + const int shift = 10; + + meminfo(); + + if (S(kb_main_total) < 1024*1024) +#endif { message(L_CONSOLE, "Low memory, forcing swapon"); /* swapon -a requires /proc typically */