📄 proc.c
字号:
/* * Copyright (c) 1998-2000 Caucho Technology -- all rights reserved * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Developer Source License ("the License"). The following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright * notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include * an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and * may not be used to endorse products derived from this software. * "Resin" or "Caucho" may not appear in the names of products derived * from this software. * * 4. Caucho Technology requests that attribution be given to Resin * in any manner possible. We suggest using the "Resin Powered" * button or creating a "powered by Resin(tm)" link to * http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL CAUCHO OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES. * * @author Scott Ferguson * * $Id: proc.c,v 1.6 2001/08/02 00:29:40 ferg Exp $ */#include <linux/kernel.h>#include <linux/proc_fs.h>#include <linux/in.h>#include "hardcore.h"static struct proc_dir_entry *proc_net_resin = 0;// lock for all proc modificationsstatic spinlock_t g_proc_lock = SPIN_LOCK_UNLOCKED;/** * Sets the read parameters * * @param buffer the read buffer (any guarantees on size?) * @param start output start pointer into the buffer * @param read_offset user read offset into the buffer * @param buf_len size of the buffer * @param eof output set 1 if the user read everything * @param len the written buffer length */static intread_result(char *buffer, char **start, off_t read_offset, int buf_len, int *eof, int write_len){ if (read_offset >= write_len) { *start = buffer; *eof = 1; return 0; } *start = buffer + read_offset; write_len -= read_offset; if (write_len > buf_len) return buf_len; *eof = 1; return write_len;}/** * Returns the port number that we're listening to. */static intresin_port_read(char *buffer, char **start, off_t read_offset, int buf_len, int *eof, void *data){ int write_len; resin_t *resin = data; if (! resin || resin->is_dead) { *start = buffer; *eof = 1; return 0; } write_len = sprintf(buffer, "%d\n", resin->accept_port); return read_result(buffer, start, read_offset, buf_len, eof, write_len);}/** * Returns the srun configuration * * @param buffer the read buffer (any guarantees on size?) * @param start output start pointer into the buffer * @param read_offset user read offset into the buffer * @param buf_len size of the buffer * @param eof output set 1 if the user read everything * @param data system data (resin_t) */static intresin_srun_read(char *buffer, char **start, off_t read_offset, int buf_len, int *eof, void *data){ int write_len = 0; srun_t *srun = data; if (! srun || ! srun->is_live || srun->resin->is_dead) { *start = buffer; *eof = 1; return 0; } if (srun && srun->is_live) { write_len = sprintf(buffer, "%u.%u.%u.%u %d%s\n", NIPQUAD(srun->addr.s_addr), srun->port, srun->is_backup ? " backup" : ""); } return read_result(buffer, start, read_offset, buf_len, eof, write_len);}/** * Writes the srun configuration. The srun file is a list of lines * like "ip port backup?" * * 127.0.0.1 6802 * 127.0.0.1 6803 backup * * Currently, the write is only accepted if it's a complete block. Partial * writes are ignored. * * @param file named file * @param buffer ascii buffer * @param count how many bytes to write to the buffer * @param data system data (resin_t) */static intresin_srun_write(struct file *file, const char *buffer, unsigned long count, void *data){ srun_t *srun = data; resin_t *resin = srun ? srun->resin : 0; int is_live = 0; struct in_addr addr; int port; int is_backup; int i, j; if (! resin || resin->is_dead || srun->session_index >= resin->srun_count) return 0; spin_lock_irq(&g_proc_lock); i = 0; is_live = 0; addr.s_addr = 0; port = 0; is_backup = 0; for (; i < count && (buffer[i] == ' ' || buffer[i] == '\t'); i++) { } /* blank line is a disabled srun */ if (i >= count) goto done; if (buffer[i] == '\n') { if (srun->is_live) srun_close(srun); goto done; } addr.s_addr = 0; for (j = 0; j < 4; j++) { int segment = 0; if (i < count && buffer[i] == '.') i++; for (; i < count && buffer[i] >= '0' && buffer[i] <= '9'; i++) segment = 10 * segment + buffer[i] - '0'; if (segment > 255) goto done; addr.s_addr = 256 * addr.s_addr + segment; } if ((addr.s_addr & 0xff000000) == 0 || (addr.s_addr & 0x000000ff) == 0) goto done; for (; i < count && (buffer[i] == ' ' || buffer[i] == '\t'); i++) { } port = 0; for (; i < count && buffer[i] >= '0' && buffer[i] <= '9'; i++) port = 10 * port + buffer[i] - '0'; for (; i < count && (buffer[i] == ' ' || buffer[i] == '\t'); i++) { } if (i < count && buffer[i] == 'b') is_backup = 1; if (srun->is_live) srun_close(srun); srun_create(resin, srun->session_index, addr.s_addr, port); done: spin_unlock_irq(&g_proc_lock); return count;}/** * Returns the number of configured sruns configuration * * @param buffer the read buffer (any guarantees on size?) * @param start output start pointer into the buffer * @param read_offset user read offset into the buffer * @param buf_len size of the buffer * @param eof output set 1 if the user read everything * @param data system data (resin_t) */static intresin_srun_count_read(char *buffer, char **start, off_t read_offset, int buf_len, int *eof, void *data){ int write_len; resin_t *resin = data; if (! resin || resin->is_dead) { *start = buffer; *eof = 1; return 0; } write_len = sprintf(buffer, "%d\n", resin->srun_count); return read_result(buffer, start, read_offset, buf_len, eof, write_len);}/** * Sets the number of sruns. * * @param file named file * @param buffer ascii buffer * @param count how many bytes to write to the buffer * @param data system data (resin_t) */static intresin_srun_count_write(struct file *file, const char *buffer, unsigned long count, void *data){ srun_t *srun = data; resin_t *resin = srun ? srun->resin : 0; int i; int srun_count; int has_digit = 0; int old_count; if (! srun || ! resin || resin->is_dead) return 0; spin_lock_irq(&g_proc_lock); old_count = resin->srun_count; i = 0; for (; i < count && (buffer[i] == ' ' || buffer[i] == '\t'); i++) { } srun_count = 0; has_digit = 0; for (; i < count && buffer[i] >= '0' && buffer[i] <= '9'; i++) { srun_count = 10 * srun_count + buffer[i] - '0'; has_digit = 1; } for (; (i < count && (buffer[i] == ' ' || buffer[i] == '\t' || buffer[i] == '\n')); i++) { } if (has_digit && i >= count && srun_count <= 64) { char buf[80]; for (i = srun_count; i < old_count; i++) { sprintf(buf, "srun-%d", i); remove_proc_entry(buf, proc_net_resin); srun_close(&resin->srun_list[i]); } srun_set_count(resin, srun_count); for (i = old_count; i < srun_count; i++) { struct proc_dir_entry *entry; sprintf(buf, "srun-%d", i); entry = create_proc_entry(buf, 0, proc_net_resin); if (entry) { entry->read_proc = resin_srun_read; entry->write_proc = resin_srun_write; entry->data = &resin->srun_list[i]; } } } spin_unlock_irq(&g_proc_lock); return count;}/** * Initialize the /proc/net/resin directory */voidresin_proc_init(resin_t *resin){ LOG(("resind: registering /proc/net/resin\n")); if (! proc_net_resin) { struct proc_dir_entry *entry; char buf[80]; int i; entry = create_proc_entry("net/resin", S_IFDIR, 0); if (entry) {#ifdef MODULE // ent->fill_inode = rpc_modcount;#endif proc_net_resin = entry; } entry = create_proc_entry("server_port", 0, proc_net_resin); if (entry) { entry->read_proc = resin_port_read; entry->data = resin; } entry = create_proc_entry("srun-count", 0, proc_net_resin); if (entry) { entry->data = resin; entry->read_proc = resin_srun_count_read; entry->write_proc = resin_srun_count_write; } for (i = 0; i < resin->srun_count; i++) { sprintf(buf, "srun-%d", i); entry = create_proc_entry(buf, 0, proc_net_resin); if (entry) { entry->data = &resin->srun_list[i]; entry->read_proc = resin_srun_read; entry->write_proc = resin_srun_write; } } }}voidresin_proc_exit(resin_t *resin){ LOG(("resind: unregistering /proc/net/resin\n")); if (proc_net_resin) { int i; remove_proc_entry("server_port", proc_net_resin); for (i = 0; i < resin->srun_count; i++) { char buf[80]; sprintf(buf, "srun-%d", i); remove_proc_entry(buf, proc_net_resin); } proc_net_resin = 0; remove_proc_entry("net/resin", 0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -