From c15f3bee8d46f05afe1d3f582778d74c7e706485 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Thu, 14 Aug 2008 15:24:00 +0200 Subject: 2008-08-14 Madhusudan.C.S * ChangeLog: New file added to procfs * AUTHORS: New file added to procfs * COPYING: New file added to procfs * README: New file added to procfs * Makefile: New file added to procfs * bootstrap.c: New file added to procfs * netfs.c: New file added to procfs * node.c: New file added to procfs * procfs.c: New file added to procfs * procfs.h: New file added to procfs * procfs_dir.c: New file added to procfs * procfs_nonpid_files.c: New file added to procfs * procfs_pid.h: New file added to procfs * procfs_pid_files.c: New file added to procfs --- AUTHORS | 10 + COPYING | 340 +++++++++++++++++++++++++++++ ChangeLog | 20 ++ Makefile | 40 ++++ README | 0 bootstrap.c | 95 +++++++++ netfs.c | 466 ++++++++++++++++++++++++++++++++++++++++ node.c | 195 +++++++++++++++++ procfs.c | 149 +++++++++++++ procfs.h | 218 +++++++++++++++++++ procfs_dir.c | 575 ++++++++++++++++++++++++++++++++++++++++++++++++++ procfs_nonpid_files.c | 462 ++++++++++++++++++++++++++++++++++++++++ procfs_pid.h | 86 ++++++++ procfs_pid_files.c | 570 +++++++++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 3226 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Makefile create mode 100644 README create mode 100644 bootstrap.c create mode 100644 netfs.c create mode 100644 node.c create mode 100644 procfs.c create mode 100644 procfs.h create mode 100644 procfs_dir.c create mode 100644 procfs_nonpid_files.c create mode 100644 procfs_pid.h create mode 100644 procfs_pid_files.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..622b648 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,10 @@ +Written By +~~~~~~~~~~ + +Madhusudan.C.S + + +Mentored By +~~~~~~~~~~~ + +Olaf Buddenhagen diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..36f6bf5 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,20 @@ +2008-08-14 Madhusudan.C.S + + * ChangeLog: New file added to procfs + * AUTHORS: New file added to procfs + * COPYING: New file added to procfs + * README: New file added to procfs + * Makefile: New file added to procfs + * bootstrap.c: New file added to procfs + * netfs.c: New file added to procfs + * node.c: New file added to procfs + * procfs.c: New file added to procfs + * procfs.h: New file added to procfs + * procfs_dir.c: New file added to procfs + * procfs_nonpid_files.c: New file added to procfs + * procfs_pid.h: New file added to procfs + * procfs_pid_files.c: New file added to procfs + +2008-05-13 Madhusudan.C.S + + * /sources/hurd/procfs: New directory added to the repository diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dae406d --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +# Makefile - for procfs +# +# Copyright (C) 1997, 2000 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, or (at +# your option) any later version. +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +dir := procfs +makemode := server + +target = procfs + +CC = gcc +CFLAGS = -Wall -g -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 +INCLUDES = -I. + +SRCS = procfs.c bootstrap.c netfs.c procfs_dir.c node.c procfs_pid_files.c procfs_nonpid_files.c +LCLHDRS = procfs.h procfs_pid.h + +OBJS = $(SRCS:.c=.o) +HURDLIBS = -lnetfs -lfshelp -liohelp -lthreads -lports -lihash -lps -lshouldbeinlibc + +all: $(target) + +$(target): $(OBJS) + $(CC) $(CFLAGS) -o $(target) $(OBJS) $(HURDLIBS) + +%.o: %.c $(LCLHDRS) + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/bootstrap.c b/bootstrap.c new file mode 100644 index 0000000..73d31f0 --- /dev/null +++ b/bootstrap.c @@ -0,0 +1,95 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + bootstrap.c -- This file is functions for starting up + and initializers for the procfs translator + defined in procfs.h + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. +*/ + +#include +#include +#include + +#include "procfs.h" + +struct ps_context *ps_context; + +/* This function is used to initialize the whole translator, can be + effect called as bootstrapping the translator. */ +error_t procfs_init () +{ + error_t err; + + err = ps_context_create (getproc (), &ps_context); + + return err; +} + +/* Create a new procfs filesystem. */ +error_t procfs_create (char *procfs_root, int fsid, + struct procfs **fs) +{ + error_t err; + /* This is the enclosing directory for this filesystem's + root node */ + struct procfs_dir *topmost_root_dir; + + /* And also a topmost-root node, just used for locking + TOPMOST_ROOT_DIR. */ + struct node *topmost_root; + + /* The new node for the filesystem's root. */ + struct procfs *new = malloc (sizeof (struct procfs)); + + if (! new) + return ENOMEM; + + new->fsid = fsid; + new->next_inode = 2; + + hurd_ihash_init (&new->inode_mappings, + offsetof (struct procfs_dir_entry, inode_locp)); + spin_lock_init (&new->inode_mappings_lock); + + topmost_root = netfs_make_node (0); + if (! topmost_root) + err = ENOMEM; + else + { + err = procfs_dir_create (new, topmost_root, procfs_root, + &topmost_root_dir); + if (! err) + { + /* ADDITIONAL BOOTSTRAPPING OF THE ROOT NODE */ + err = procfs_dir_null_lookup (topmost_root_dir, &new->root); + } + } + + if (err) + { + hurd_ihash_destroy (&new->inode_mappings); + free (new); + } + else + *fs = new; + + return err; +} + diff --git a/netfs.c b/netfs.c new file mode 100644 index 0000000..31ffe1b --- /dev/null +++ b/netfs.c @@ -0,0 +1,466 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "procfs.h" + +/* Trivial definitions. */ + +/* Make sure that NP->nn_stat is filled with current information. CRED + identifies the user responsible for the operation. */ +error_t +netfs_validate_stat (struct node *node, struct iouser *cred) +{ + return procfs_refresh_node (node); +} + +/* This should sync the file NODE completely to disk, for the user CRED. If + WAIT is set, return only after sync is completely finished. */ +error_t +netfs_attempt_sync (struct iouser *cred, struct node *node, int wait) +{ + return 0; +} + +/* Attempt to create a new directory named NAME in DIR for USER with mode + MODE. */ +error_t netfs_attempt_mkdir (struct iouser *user, struct node *dir, + char *name, mode_t mode) +{ + return EROFS; +} + +/* Attempt to remove directory named NAME in DIR for USER. */ +error_t netfs_attempt_rmdir (struct iouser *user, + struct node *dir, char *name) +{ + return EROFS; +} + +/* Attempt to set the passive translator record for FILE to ARGZ (of length + ARGZLEN) for user CRED. */ +error_t netfs_set_translator (struct iouser *cred, struct node *node, + char *argz, size_t argzlen) +{ + return EROFS; +} + +/* Attempt to create a file named NAME in DIR for USER with MODE. Set *NODE + to the new node upon return. On any error, clear *NODE. *NODE should be + locked on success; no matter what, unlock DIR before returning. */ +error_t +netfs_attempt_create_file (struct iouser *user, struct node *dir, + char *name, mode_t mode, struct node **node) +{ + *node = NULL; + mutex_unlock (&dir->lock); + return EROFS; +} + +/* Node NODE is being opened by USER, with FLAGS. NEWNODE is nonzero if we + just created this node. Return an error if we should not permit the open + to complete because of a permission restriction. */ +error_t +netfs_check_open_permissions (struct iouser *user, struct node *node, + int flags, int newnode) +{ + error_t err = procfs_refresh_node (node); + if (!err && (flags & O_READ)) + err = fshelp_access (&node->nn_stat, S_IREAD, user); + if (!err && (flags & O_WRITE)) + err = fshelp_access (&node->nn_stat, S_IWRITE, user); + if (!err && (flags & O_EXEC)) + err = fshelp_access (&node->nn_stat, S_IEXEC, user); + return err; +} + +/* This should attempt a utimes call for the user specified by CRED on node + NODE, to change the atime to ATIME and the mtime to MTIME. */ +error_t +netfs_attempt_utimes (struct iouser *cred, struct node *node, + struct timespec *atime, struct timespec *mtime) +{ + error_t err = procfs_refresh_node (node); + int flags = TOUCH_CTIME; + + if (! err) + err = fshelp_isowner (&node->nn_stat, cred); + + if (! err) + { + if (atime) + node->nn_stat.st_atim = *atime; + else + flags |= TOUCH_ATIME; + + if (mtime) + node->nn_stat.st_mtim = *mtime; + else + flags |= TOUCH_MTIME; + + fshelp_touch (&node->nn_stat, flags, procfs_maptime); + } + + return err; +} + +/* Return the valid access types (bitwise OR of O_READ, O_WRITE, and O_EXEC) + in *TYPES for file NODE and user CRED. */ +error_t +netfs_report_access (struct iouser *cred, struct node *node, int *types) +{ + error_t err = procfs_refresh_node (node); + + if (! err) + { + *types = 0; + if (fshelp_access (&node->nn_stat, S_IREAD, cred) == 0) + *types |= O_READ; + if (fshelp_access (&node->nn_stat, S_IWRITE, cred) == 0) + *types |= O_WRITE; + if (fshelp_access (&node->nn_stat, S_IEXEC, cred) == 0) + *types |= O_EXEC; + } + + return err; +} + +/* The granularity with which we allocate space to return our result. */ +#define DIRENTS_CHUNK_SIZE (8*1024) + +/* Returned directory entries are aligned to blocks this many bytes long. + Must be a power of two. */ +#define DIRENT_ALIGN 4 +#define DIRENT_NAME_OFFS offsetof (struct dirent, d_name) + +/* Length is structure before the name + the name + '\0', all + padded to a four-byte alignment. */ +#define DIRENT_LEN(name_len) \ + ((DIRENT_NAME_OFFS + (name_len) + 1 + (DIRENT_ALIGN - 1)) \ + & ~(DIRENT_ALIGN - 1)) + + + +/* Fetch a directory */ +error_t +netfs_get_dirents (struct iouser *cred, struct node *dir, + int first_entry, int max_entries, char **data, + mach_msg_type_number_t *data_len, + vm_size_t max_data_len, int *data_entries) +{ + error_t err = procfs_refresh_node (dir); + struct procfs_dir_entry *dir_entry; + + if (! err) + { + if (dir->nn->dir) + { + if (! procfs_dir_refresh (dir->nn->dir, dir == dir->nn->fs->root)) + { + for (dir_entry = dir->nn->dir->ordered; first_entry > 0 && + dir_entry; first_entry--, + dir_entry = dir_entry->ordered_next); + if (! dir_entry ) + max_entries = 0; + + if (max_entries != 0) + { + size_t size = 0; + char *p; + int count = 0; + + + if (max_data_len == 0) + size = DIRENTS_CHUNK_SIZE; + else if (max_data_len > DIRENTS_CHUNK_SIZE) + size = DIRENTS_CHUNK_SIZE; + else + size = max_data_len; + + *data = mmap (0, size, PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); + + err = ((void *) *data == (void *) -1) ? errno : 0; + + if (! err) + { + p = *data; + + /* This gets all the actual entries present. */ + + while ((max_entries == -1 || count < max_entries) && dir_entry) + { + struct dirent hdr; + size_t name_len = strlen (dir_entry->name); + size_t sz = DIRENT_LEN (name_len); + int entry_type = IFTODT (dir_entry->stat.st_mode); + + if ((p - *data) + sz > size) + { + if (max_data_len > 0) + break; + else /* The Buffer Size must be increased. */ + { + vm_address_t extension = (vm_address_t)(*data + size); + err = vm_allocate (mach_task_self (), &extension, + DIRENTS_CHUNK_SIZE, 0); + + if (err) + break; + + size += DIRENTS_CHUNK_SIZE; + } + } + + hdr.d_namlen = name_len; + hdr.d_fileno = dir_entry->stat.st_ino; + hdr.d_reclen = sz; + hdr.d_type = entry_type; + + memcpy (p, &hdr, DIRENT_NAME_OFFS); + strcpy (p + DIRENT_NAME_OFFS, dir_entry->name); + + p += sz; + + count++; + dir_entry = dir_entry->ordered_next; + } + + if (err) + munmap (*data, size); + else + { + vm_address_t alloc_end = (vm_address_t)(*data + size); + vm_address_t real_end = round_page (p); + if (alloc_end > real_end) + munmap ((caddr_t) real_end, alloc_end - real_end); + *data_len = p - *data; + *data_entries = count; + } + } + } + else + { + *data_len = 0; + *data_entries = 0; + } + } + } + else + return ENOTDIR; + } + + return err; +} + +/* Lookup NAME in DIR for USER; set *NODE to the found name upon return. If + the name was not found, then return ENOENT. On any error, clear *NODE. + (*NODE, if found, should be locked, this call should unlock DIR no matter + what.) */ +error_t netfs_attempt_lookup (struct iouser *user, struct node *dir, + char *name, struct node **node) +{ + error_t err = procfs_refresh_node (dir); + + if (! err) + err = procfs_dir_lookup (dir->nn->dir, name, node); + + return err; +} + +/* Delete NAME in DIR for USER. */ +error_t netfs_attempt_unlink (struct iouser *user, struct node *dir, + char *name) +{ + return EROFS; +} + +/* Note that in this one call, neither of the specific nodes are locked. */ +error_t netfs_attempt_rename (struct iouser *user, struct node *fromdir, + char *fromname, struct node *todir, + char *toname, int excl) +{ + return EROFS; +} + +/* This should attempt a chmod call for the user specified by CRED on node + NODE, to change the owner to UID and the group to GID. */ +error_t netfs_attempt_chown (struct iouser *cred, struct node *node, + uid_t uid, uid_t gid) +{ + return EROFS; +} + +/* This should attempt a chauthor call for the user specified by CRED on node + NODE, to change the author to AUTHOR. */ +error_t netfs_attempt_chauthor (struct iouser *cred, struct node *node, + uid_t author) +{ + return EROFS; +} + +/* This should attempt a chmod call for the user specified by CRED on node + NODE, to change the mode to MODE. Unlike the normal Unix and Hurd meaning + of chmod, this function is also used to attempt to change files into other + types. If such a transition is attempted which is impossible, then return + EOPNOTSUPP. */ +error_t netfs_attempt_chmod (struct iouser *cred, struct node *node, + mode_t mode) +{ + return EROFS; +} + +/* Attempt to turn NODE (user CRED) into a symlink with target NAME. */ +error_t netfs_attempt_mksymlink (struct iouser *cred, struct node *node, + char *name) +{ + return EROFS; +} + +/* Attempt to turn NODE (user CRED) into a device. TYPE is either S_IFBLK or + S_IFCHR. */ +error_t netfs_attempt_mkdev (struct iouser *cred, struct node *node, + mode_t type, dev_t indexes) +{ + return EROFS; +} + + +/* This should attempt a chflags call for the user specified by CRED on node + NODE, to change the flags to FLAGS. */ +error_t netfs_attempt_chflags (struct iouser *cred, struct node *node, + int flags) +{ + return EROFS; +} + +/* This should attempt to set the size of the file NODE (for user CRED) to + SIZE bytes long. */ +error_t netfs_attempt_set_size (struct iouser *cred, struct node *node, + off_t size) +{ + return EROFS; +} + +/* This should attempt to fetch filesystem status information for the remote + filesystem, for the user CRED. */ +error_t +netfs_attempt_statfs (struct iouser *cred, struct node *node, + struct statfs *st) +{ + bzero (st, sizeof *st); + st->f_type = PROCFILESYSTEM; + st->f_fsid = getpid (); + return 0; +} + +/* This should sync the entire remote filesystem. If WAIT is set, return + only after sync is completely finished. */ +error_t netfs_attempt_syncfs (struct iouser *cred, int wait) +{ + return 0; +} + +/* Create a link in DIR with name NAME to FILE for USER. Note that neither + DIR nor FILE are locked. If EXCL is set, do not delete the target, but + return EEXIST if NAME is already found in DIR. */ +error_t netfs_attempt_link (struct iouser *user, struct node *dir, + struct node *file, char *name, int excl) +{ + return EROFS; +} + +/* Attempt to create an anonymous file related to DIR for USER with MODE. + Set *NODE to the returned file upon success. No matter what, unlock DIR. */ +error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir, + mode_t mode, struct node **node) +{ + *node = NULL; + mutex_unlock (&dir->lock); + return EROFS; +} + +/* Read the contents of NODE (a symlink), for USER, into BUF. */ +error_t netfs_attempt_readlink (struct iouser *user, struct node *node, char *buf) +{ + error_t err = procfs_refresh_node (node); + if (! err) + { + struct procfs_dir_entry *dir_entry = node->nn->dir_entry; + if (dir_entry) + bcopy (dir_entry->symlink_target, buf, node->nn_stat.st_size); + else + err = EINVAL; + } + return err; +} + +/* Read from the file NODE for user CRED starting at OFFSET and continuing for + up to *LEN bytes. Put the data at DATA. Set *LEN to the amount + successfully read upon return. */ +error_t netfs_attempt_read (struct iouser *cred, struct node *node, + off_t offset, size_t *len, void *data) +{ + error_t err; + err = procfs_refresh_node (node); + + if (! err) + { + if (*len > 0) + procfs_write_files_contents (node, offset, + len, data); + if (*len > 0) + if (offset >= *len) + *len = 0; + } + + return err; +} + +/* Write to the file NODE for user CRED starting at OFFSET and continuing for up + to *LEN bytes from DATA. Set *LEN to the amount seccessfully written upon + return. */ +error_t netfs_attempt_write (struct iouser *cred, struct node *node, + off_t offset, size_t *len, void *data) +{ + return EROFS; +} + +/* The user must define this function. Node NP is all done; free + all its associated storage. */ +void netfs_node_norefs (struct node *np) +{ + mutex_lock (&np->lock); + *np->prevp = np->next; + np->next->prevp = np->prevp; + procfs_remove_node (np); +} + diff --git a/node.c b/node.c new file mode 100644 index 0000000..f11fa7b --- /dev/null +++ b/node.c @@ -0,0 +1,195 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + node.c -- This file contains function defintions to handle + node creation and destruction. + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. +*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "procfs.h" + +/* Return a new node in NODE, with a name NAME, and return the + new node with a single reference in NODE. */ +error_t procfs_create_node (struct procfs_dir_entry *dir_entry, + const char *fs_path, struct node **node) +{ + struct node *new; + struct netnode *nn = malloc (sizeof (struct netnode)); + error_t err; + + if (! nn) + return ENOMEM; + if (! fs_path) + fs_path = strdup (""); + nn->fs = dir_entry->dir->fs; + nn->dir_entry = dir_entry; + nn->dir = NULL; + nn->fs_path = strdup (fs_path); + + new = netfs_make_node (nn); + if (! new) + { + free (nn); + return ENOMEM; + } + + fshelp_touch (&new->nn_stat, TOUCH_ATIME|TOUCH_MTIME|TOUCH_CTIME, + procfs_maptime); + + spin_lock (&nn->fs->inode_mappings_lock); + err = hurd_ihash_add (&nn->fs->inode_mappings, dir_entry->stat.st_ino, dir_entry); + spin_unlock (&nn->fs->inode_mappings_lock); + + if (err) + { + free (nn); + free (new); + return err; + } + + dir_entry->node = new; + *node = new; + + return 0; +} + +/* Update the directory entry for NAME to reflect ST and SYMLINK_TARGET. + True is returned if successful, or false if there was a memory allocation + error. TIMESTAMP is used to record the time of this update. */ +static void +update_entry (struct procfs_dir_entry *dir_entry, const struct stat *st, + const char *symlink_target, time_t timestamp) +{ + ino_t ino; + struct procfs *fs = dir_entry->dir->fs; + + if (dir_entry->stat.st_ino) + ino = dir_entry->stat.st_ino; + else + ino = fs->next_inode++; + + dir_entry->name_timestamp = timestamp; + + if (st) + /* The ST and SYMLINK_TARGET parameters are only valid if ST isn't 0. */ + { + dir_entry->stat = *st; + dir_entry->stat_timestamp = timestamp; + + if (!dir_entry->symlink_target || !symlink_target + || strcmp (dir_entry->symlink_target, symlink_target) != 0) + { + if (dir_entry->symlink_target) + free (dir_entry->symlink_target); + dir_entry->symlink_target = symlink_target ? strdup (symlink_target) : 0; + } + } + + /* The st_ino field is always valid. */ + dir_entry->stat.st_ino = ino; + dir_entry->stat.st_fsid = fs->fsid; + dir_entry->stat.st_fstype = PROCFILESYSTEM; +} + +/* Refresh stat information for NODE */ +error_t procfs_refresh_node (struct node *node) +{ + struct netnode *nn = node->nn; + struct procfs_dir_entry *dir_entry = nn->dir_entry; + + if (! dir_entry) + /* This is a deleted node, don't attempt to do anything. */ + return 0; + else + { + error_t err = 0; + + struct timeval tv; + maptime_read (procfs_maptime, &tv); + + time_t timestamp = tv.tv_sec; + + struct procfs_dir *dir = dir_entry->dir; + + mutex_lock (&dir->node->lock); + + if (! dir_entry->self_p) + /* This is a deleted entry, just awaiting disposal; do so. */ + { +#if 0 + nn->dir_entry = 0; + free_entry (dir_entry); + return 0; +#endif + } + + else if (dir_entry->noent) + err = ENOENT; + else + { + if (*(dir_entry->name)) + { + err = procfs_dir_refresh (dir_entry->dir, + dir_entry->dir->node == dir_entry->dir->fs->root); + if (!err && dir_entry->noent) + err = ENOENT; + + if (err == ENOENT) + { + dir_entry->noent = 1; /* A negative entry. */ + dir_entry->name_timestamp = timestamp; + } + } + else + { + /* Refresh the root node with the old stat + information. */ + update_entry (dir_entry, &netfs_root_node->nn_stat, NULL, timestamp); + } + } + + node->nn_stat = dir_entry->stat; + node->nn_translated = S_ISLNK (dir_entry->stat.st_mode) ? S_IFLNK : 0; + if (!nn->dir && S_ISDIR (dir_entry->stat.st_mode)) + procfs_dir_create (nn->fs, node, nn->fs_path, &nn->dir); + + mutex_unlock (&dir->node->lock); + + return err; + } +} + +/* Remove NODE from its entry */ +error_t procfs_remove_node (struct node *node) +{ + + /* STUB */ + + return 0; +} diff --git a/procfs.c b/procfs.c new file mode 100644 index 0000000..1fd0d61 --- /dev/null +++ b/procfs.c @@ -0,0 +1,149 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + procfs.c -- This file is the main file of the translator. + This has important definitions and initializes + the translator + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "procfs.h" + +/* Defines this Tanslator Name */ +char *netfs_server_name = PROCFS_SERVER_NAME; +char *netfs_server_version = PROCFS_SERVER_VERSION; +int netfs_maxsymlinks = 12; + +static const struct argp_child argp_children[] = + { + {&netfs_std_startup_argp, 0, NULL, 0}, + {0} + }; + + +const char *argp_program_version = "/proc pseudo-filesystem (" PROCFS_SERVER_NAME + ") " PROCFS_SERVER_VERSION "\n" +"Copyright (C) 2008 Free Software Foundation\n" +"This is free software; see the source for copying conditions. There is NO\n" +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +"\n"; + +static char *args_doc = "PROCFSROOT"; +static char *doc = "proc pseudo-filesystem for Hurd implemented as a translator. " +"This is still under very humble and initial stages of development.\n" +"Any Contribution or help is welcome. The code may not even compile"; + + +/* The Filesystem */ +struct procfs *procfs; + +/* The FILESYSTEM component of PROCFS_FS. */ +char *procfs_root = ""; + +volatile struct mapped_time_value *procfs_maptime; + +/* Startup options. */ +static const struct argp_option procfs_options[] = + { + { 0 } + }; + + +/* argp parser function for parsing single procfs command line options */ +static error_t +parse_procfs_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case ARGP_KEY_ARG: + if (state->arg_num > 1) + argp_usage (state); + break; + + case ARGP_KEY_NO_ARGS: + argp_usage(state); + break; + + default: + return ARGP_ERR_UNKNOWN; + } +} + +/* Program entry point. */ +int +main (int argc, char **argv) +{ + error_t err; + mach_port_t bootstrap, underlying_node; + struct stat underlying_stat; + + struct argp argp = + { + procfs_options, parse_procfs_opt, + args_doc, doc, argp_children, + NULL, NULL + }; + + + /* Parse the command line arguments */ +// argp_parse (&argp, argc, argv, 0, 0, 0); + + task_get_bootstrap_port (mach_task_self (), &bootstrap); + + netfs_init (); + + if (maptime_map (0, 0, &procfs_maptime)) + { + perror (PROCFS_SERVER_NAME ": Cannot map time"); + return 1; + } + + procfs_init (); + + err = procfs_create (procfs_root, getpid (), &procfs); + if (err) + error (4, err, "%s", procfs_root); + + /* Create our root node */ + netfs_root_node = procfs->root; + + /* Start netfs activities */ + underlying_node = netfs_startup (bootstrap, 0); + if (io_stat (underlying_node, &underlying_stat)) + error (1, err, "cannot stat underling node"); + + /* Initialize stat information of the root node. */ + netfs_root_node->nn_stat = underlying_stat; + netfs_root_node->nn_stat.st_mode = + S_IFDIR | (underlying_stat.st_mode & ~S_IFMT & ~S_ITRANS); + + for (;;) + netfs_server_loop (); + return 1; +} diff --git a/procfs.h b/procfs.h new file mode 100644 index 0000000..95d4ee3 --- /dev/null +++ b/procfs.h @@ -0,0 +1,218 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + procfs.h -- This file is the main header file of this + translator. This has important header + definitions for constants and functions + used in the translator. + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + + A portion of the code in this file is based on ftpfs code + present in the hurd repositories copyrighted to FSF. The + Copyright notice from that file is given below. + + Copyright (C) 1997,98,2002 Free Software Foundation, Inc. + Written by Miles Bader + This file is part of the GNU Hurd. +*/ + +#ifndef __PROCFS_H__ +#define __PROCFS_H__ + +#define PROCFS_SERVER_NAME "procfs" +#define PROCFS_SERVER_VERSION "0.0.1" + +/* /proc Filesystem type. */ +#define PROCFILESYSTEM "procfs" + +#define NUMBER_OF_FILES_PER_PID 1 +#define JIFFY_ADJUST 100 +#define PAGES_TO_BYTES(pages) ((pages) * sysconf(_SC_PAGESIZE)) +#define BYTES_TO_PAGES(bytes) ((bytes) / sysconf(_SC_PAGESIZE)) + +#include +#include +#include +#include +#include +#include + +/* A single entry in a directory. */ +struct procfs_dir_entry +{ + char *name; /* Name of this entry */ + size_t hv; /* Hash value of NAME */ + + /* The active node referred to by this name (may be 0). + NETFS_NODE_REFCNT_LOCK should be held while frobbing this. */ + struct node *node; + + struct stat stat; + char *symlink_target; + time_t stat_timestamp; + + /* The directory to which this entry belongs. */ + struct procfs_dir *dir; + + /* Link to next entry in hash bucket, and address of previous entry's (or + hash table's) pointer to this entry. If the SELF_P field is 0, then + this is a deleted entry, awaiting final disposal. */ + struct procfs_dir_entry *next, **self_p; + + /* Next entry in 'directory order', or 0 if none known. */ + struct procfs_dir_entry *ordered_next, **ordered_self_p; + + /* When the presence/absence of this file was last checked. */ + time_t name_timestamp; + + hurd_ihash_locp_t inode_locp; /* Used for removing this entry */ + + int noent : 1; /* A negative lookup result. */ + int valid : 1; /* Marker for GC'ing. */ +}; + +/* A directory. */ +struct procfs_dir +{ + /* Number of entries in HTABLE. */ + size_t num_entries; + + /* The number of entries that have nodes attached. We keep an additional + reference to our node if there are any, to prevent it from going away. */ + size_t num_live_entries; + + /* Hash table of entries. */ + struct procfs_dir_entry **htable; + size_t htable_len; /* # of elements in HTABLE (not bytes). */ + + /* List of dir entries in 'directory order', in a linked list using the + ORDERED_NEXT and ORDERED_SELF_P fields in each entry. Not all entries + in HTABLE need be in this list. */ + struct procfs_dir_entry *ordered; + + /* The filesystem node that this is the directory for. */ + struct node *node; + + /* The filesystem this directory is in. */ + struct procfs *fs; + + /* The path to this directory in the filesystem. */ + const char *fs_path; + + time_t stat_timestamp; + time_t name_timestamp; + +}; + + +/* libnetfs node structure */ +struct netnode +{ + /* Name of this node */ + char *name; + + /* The path in the filesystem that corresponds + this node. */ + char *fs_path; + + /* The directory entry for this node. */ + struct procfs_dir_entry *dir_entry; + + /* The proc filesystem */ + struct procfs *fs; + + /* inode number, assigned to this netnode structure. */ + unsigned int inode_num; + + /* If this is a directory, the contents, or 0 if not fetched. */ + struct procfs_dir *dir; + + /* pointer to node structure, assigned to this node. */ + struct node *node; + + /* links to the previous and next nodes in the list */ + struct netnode *nextnode, *prevnode; + + /* link to parent netnode of this file or directory */ + struct netnode *parent; + + /* link to the first child netnode of this directory */ + struct netnode *child_first; +}; + +/* The actual procfs filesystem structure */ +struct procfs +{ + /* Root of the filesystem. */ + struct node *root; + + /* Inode numbers are assigned sequentially in order of creation. */ + ino_t next_inode; + int fsid; + + /* A hash table mapping inode numbers to directory entries. */ + struct hurd_ihash inode_mappings; + spin_lock_t inode_mappings_lock; +}; + +extern struct procfs *procfs; + +extern volatile struct mapped_time_value *procfs_maptime; + +extern struct ps_context *ps_context; + +/* Create a new procfs filesystem. */ +error_t procfs_create (char *procfs_root, int fsid, + struct procfs **fs); + +/* Initialize the procfs filesystem for use. */ +error_t procfs_init (); + +/* Refresh stat information for NODE */ +error_t procfs_refresh_node (struct node *node); + +/* Return a new node in NODE, with a name NAME, + and return the new node with a single + reference in NODE. */ +error_t procfs_create_node (struct procfs_dir_entry *dir_entry, + const char *fs_path, + struct node **node); + +/* Remove NODE from its entry */ +error_t procfs_remove_node (struct node *node); + +/* Return in DIR a new procfs directory, in the filesystem FS, + with node NODE and path PATH. */ +error_t procfs_dir_create (struct procfs *fs, struct node *node, + const char *path, struct procfs_dir **dir); + +/* Remove the specified DIR and free all its allocated + storage. */ +void procfs_dir_remove (struct procfs_dir *dir); + +/* Refresh DIR. */ +error_t procfs_dir_refresh (struct procfs_dir *dir, int isroot); + +/* Lookup NAME in DIR, returning its entry, or an error. + *NODE will contain the result node, locked, and with + an additional reference, or 0 if an error occurs. */ +error_t procfs_dir_lookup (struct procfs_dir *dir, const char *name, + struct node **node); + +#endif /* __PROCFS_H__ */ diff --git a/procfs_dir.c b/procfs_dir.c new file mode 100644 index 0000000..b9b0410 --- /dev/null +++ b/procfs_dir.c @@ -0,0 +1,575 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + procfs_dir.c -- This file contains definitions to perform + directory operations such as creating, + removing and refreshing directories. + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + + A portion of the code in this file is based on ftpfs code + present in the hurd repositories copyrighted to FSF. The + Copyright notice from that file is given below. + + Copyright (C) 1997,98,2002 Free Software Foundation, Inc. + Written by Miles Bader + This file is part of the GNU Hurd. +*/ + + +#include +#include +#include +#include +#include + +#include "procfs.h" + +/* Initial HASHTABLE length for the new directories to be created. */ +#define INIT_HTABLE_LEN 5 + +struct procfs_dir_entry **cur_entry; + +/* Return in DIR a new procfs directory, in the filesystem FS, + with node NODE and path PATH. */ +error_t procfs_dir_create (struct procfs *fs, struct node *node, + const char *path, struct procfs_dir **dir) +{ + struct procfs_dir *new = malloc (sizeof (struct procfs_dir)); + if (!new) + return ENOMEM; + struct procfs_dir_entry **htable = calloc (INIT_HTABLE_LEN, + sizeof (struct procfs_dir_entry *)); + if (!htable) + return ENOMEM; + + /* Hold a reference to the new dir's node. */ + spin_lock (&netfs_node_refcnt_lock); + node->references++; + spin_unlock (&netfs_node_refcnt_lock); + + new->num_entries = 0; + new->num_live_entries = 0; + new->htable_len = INIT_HTABLE_LEN; + new->htable = htable; + new->ordered = NULL; + new->fs_path = path; + new->fs = fs; + new->node = node; + new->stat_timestamp = 0; + new->name_timestamp = 0; + + *dir = new; + + return 0; +} + +/* Put the directory entry DIR_ENTRY into the hash table HTABLE. */ +static void +insert (struct procfs_dir_entry *dir_entry, + struct procfs_dir_entry **htable, size_t htable_len) +{ + struct procfs_dir_entry **new_htable = &htable[dir_entry->hv % htable_len]; + if (*new_htable) + (*new_htable)->self_p = &dir_entry->next; + dir_entry->next = *new_htable; + dir_entry->self_p = new_htable; + *new_htable = dir_entry; +} + +/* Calculate NAME's hash value. */ +static size_t +hash (const char *name) +{ + size_t hash_value = 0; + while (*name) + hash_value = ((hash_value << 5) + *name++) & 0xFFFFFF; + return hash_value; +} + +/* Extend the existing hashtable for DIR to accomodate values for new length + NEW_LEN. We retain all the previous entries. */ +static error_t +rehash (struct procfs_dir *dir, size_t new_len) +{ + int count; + size_t old_len = dir->htable_len; + struct procfs_dir_entry **old_htable = dir->htable; + struct procfs_dir_entry **new_htable = (struct procfs_dir_entry **) + malloc (new_len * sizeof (struct procfs_dir_entry *)); + + if (! new_htable) + return ENOMEM; + + bzero (new_htable, new_len * sizeof (struct procfs_dir_entry *)); + + for (count = 0; count < old_len; count++) + while (old_htable[count]) + { + struct procfs_dir_entry *dir_entry = old_htable[count]; + + /* Remove DIR_ENTRY from the old table */ + old_htable[count] = dir_entry->next; + + insert (dir_entry, new_htable, new_len); + } + + free (old_htable); + + dir->htable = new_htable; + dir->htable_len = new_len; + + return 0; +} + +/* Lookup NAME in DIR and return its entry. If there is no such entry, and + DNEW, the decision variable, is true, then a new entry is allocated and + returned, otherwise 0 is returned (if DNEW is true then 0 can be returned + if a memory allocation error occurs). */ +struct procfs_dir_entry * +lookup_entry (struct procfs_dir *dir, const char *name, int dnew) +{ + size_t hv = hash (name); + struct procfs_dir_entry *dir_entry = dir->htable[hv % dir->htable_len]; + + while (dir_entry && strcmp (name, dir_entry->name) != 0) + dir_entry = dir_entry->next; + + if (!dir_entry && dnew) + { + if (dir->num_entries > dir->htable_len) + /* Grow the hash table. */ + if (rehash (dir, (dir->htable_len + 1) * 2 - 1) != 0) + return 0; + + dir_entry = + (struct procfs_dir_entry *) malloc (sizeof (struct procfs_dir_entry)); + + if (dir_entry) + { + dir_entry->hv = hv; + dir_entry->name = strdup (name); + dir_entry->node = 0; + dir_entry->dir = dir; + dir_entry->stat_timestamp = 0; + bzero (&dir_entry->stat, sizeof dir_entry->stat); + dir_entry->symlink_target = 0; + dir_entry->noent = 0; + dir_entry->valid = 0; + dir_entry->name_timestamp = 0; + dir_entry->ordered_next = 0; + dir_entry->ordered_self_p = 0; + dir_entry->next = 0; + dir_entry->self_p = 0; + insert (dir_entry, dir->htable, dir->htable_len); + dir->num_entries++; + } + } + + return dir_entry; +} + + +/* Lookup NAME in DIR, returning its entry, or an error. + *NODE will contain the result node, locked, and with + an additional reference, or 0 if an error occurs. */ +error_t procfs_dir_lookup (struct procfs_dir *dir, const char *name, + struct node **node) +{ + struct procfs_dir_entry *dir_entry = 0; + error_t err = 0; + char *fs_path = dir->fs_path; + + struct timeval tv; + maptime_read (procfs_maptime, &tv); + + time_t timestamp = tv.tv_sec; + + if (*name == '\0' || strcmp (name, ".") == 0) + /* Current directory -- just add an additional reference to DIR's node + and return it. */ + { + netfs_nref (dir->node); + *node = dir->node; + return 0; + } + else if (strcmp (name, "..") == 0) + /* Parent directory. */ + { + if (dir->node->nn->dir_entry) + { + *node = dir->node->nn->dir_entry->dir->node; + mutex_lock (&(*node)->lock); + netfs_nref (*node); + } + else + { + err = ENOENT; /* No .. */ + *node = 0; + } + + mutex_unlock (&dir->node->lock); + + return err; + } + + err = procfs_dir_refresh (dir, dir->node == dir->fs->root); + if (!err && !dir_entry) + dir_entry = lookup_entry (dir, name, 0); + + if (! err) + { + if (dir_entry && !dir_entry->noent) + /* We've got a dir entry, get a node for it. */ + { + /* If there's already a node, add a ref so that it doesn't go + away. */ + spin_lock (&netfs_node_refcnt_lock); + if (dir_entry->node) + dir_entry->node->references++; + spin_unlock (&netfs_node_refcnt_lock); + + if (! dir_entry->node) + /* No node; make one and install it into E. */ + { + if (! fs_path) + err = EROFS; + + if (! err) + { + err = procfs_create_node (dir_entry, fs_path, &dir_entry->node); + + if (!err && dir->num_live_entries++ == 0) + /* Keep a reference to dir's node corresponding to + children. */ + { + spin_lock (&netfs_node_refcnt_lock); + dir->node->references++; + spin_unlock (&netfs_node_refcnt_lock); + } + } + } + + if (! err) + { + *node = dir_entry->node; + /* We have to unlock DIR's node before locking the child node + because the locking order is always child-parent. We know + the child node won't go away because we already hold the + additional reference to it. */ + mutex_unlock (&dir->node->lock); + mutex_lock (&dir_entry->node->lock); + } + } + else + err = ENOENT; + } + + if (err) + { + *node = 0; + mutex_unlock (&dir->node->lock); + } + +#if 0 + if (fs_path) + free (fs_path); +#endif + + return err; +} + +/* Lookup the null name in DIR, and return a node for it in NODE. Unlike + procfs_dir_lookup, this won't attempt to validate the existance of the + entry (to avoid opening a new connection if possible) -- that will happen + the first time the entry is refreshed. Also unlink ftpfs_dir_lookup, this + function doesn't expect DIR to be locked, and won't return *NODE locked. + This function is only used for bootstrapping the root node. */ +error_t +procfs_dir_null_lookup (struct procfs_dir *dir, struct node **node) +{ + struct procfs_dir_entry *dir_entry; + error_t err = 0; + + dir_entry = lookup_entry (dir, "", 1); + if (! dir_entry) + return ENOMEM; + + if (! dir_entry->noent) + /* We've got a dir entry, get a node for it. */ + { + /* If there's already a node, add a ref so that it doesn't go away. */ + spin_lock (&netfs_node_refcnt_lock); + if (dir_entry->node) + dir_entry->node->references++; + spin_unlock (&netfs_node_refcnt_lock); + + if (! dir_entry->node) + /* No node; make one and install it into DIR_ENTRY. */ + { + err = procfs_create_node (dir_entry, dir->fs_path, &dir_entry->node); + + if (!err && dir->num_live_entries++ == 0) + /* Keep a reference to dir's node corresponding to children. */ + { + spin_lock (&netfs_node_refcnt_lock); + dir->node->references++; + spin_unlock (&netfs_node_refcnt_lock); + } + } + + if (! err) + *node = dir_entry->node; + } + else + err = ENOENT; + + return err; +} + +/* Remove the specified DIR and free all its allocated + storage. */ +void procfs_dir_remove (struct procfs_dir *dir) +{ + + /* STUB */ + + return 0; +} + +/* Make all the directory entries invalid */ +static void +make_dir_invalid (struct procfs_dir *dir) +{ + int count; + size_t len = dir->htable_len; + struct procfs_dir_entry **htable = dir->htable; + struct procfs_dir_entry *dir_entry; + + for (count = 0; count < len; count++) + { + dir_entry = htable[count]; + while (dir_entry) + { + dir_entry->valid = 0; + dir_entry = dir_entry->next; + } + } +} + +/* Checks if the DIR name is in list of + Active pids. */ +int is_in_pid_list (struct procfs_dir *dir) +{ + int dir_name; + int count; + pid_t *pids = NULL; + int pidslen = 0; + error_t err; + + if (dir->node->nn) + { + dir_name = atoi (dir->node->nn->dir_entry->name); + err = proc_getallpids (getproc (), &pids, &pidslen); + + for (count = 0; count < pidslen; ++count) + if (pids[count] == dir_name) + return 1; + } + + return 0; + +} + +/* Checks if DIR is a directory that + represents a pid. */ +int check_parent (struct procfs_dir *dir) +{ + if (dir == dir->fs->root) + return 0; + else + if (is_in_pid_list (dir)) + return 1; + else + return 0; + +} + +/* Refresh DIR. */ +error_t procfs_dir_refresh (struct procfs_dir *dir, int isroot) +{ + error_t err; + int is_parent_pid; + struct node *node; + make_dir_invalid (dir); + + struct timeval tv; + maptime_read (procfs_maptime, &tv); + + time_t timestamp = tv.tv_sec; + cur_entry = &dir->ordered; + if (isroot) + err = procfs_fill_root_dir(dir, timestamp); + else + { + err = update_dir_entries (dir, timestamp); + is_parent_pid = check_parent (dir); + if (is_parent_pid) + err = procfs_create_files (dir, &node, timestamp); + } + + return err; +} + +/* Update the directory entry for NAME to reflect STAT and SYMLINK_TARGET. + This also creates a valid linked list of entries imposing ordering on + them. */ +struct procfs_dir_entry* +update_entries_list (struct procfs_dir *dir, const char *name, + const struct stat *stat, time_t timestamp, + const char *symlink_target) +{ + ino_t ino; + struct procfs_dir_entry *dir_entry = lookup_entry (dir, name, 1); + struct procfs *fs = dir->fs; + + if (! dir_entry) + return ENOMEM; + + if (dir_entry->stat.st_ino) + ino = dir_entry->stat.st_ino; + else + ino = fs->next_inode++; + + dir_entry->name_timestamp = timestamp; + + if (stat) + /* The ST and SYMLINK_TARGET parameters are only valid if ST isn't 0. */ + { + dir_entry->stat = *stat; + dir_entry->stat_timestamp = timestamp; + + if (!dir_entry->symlink_target || !symlink_target + || strcmp (dir_entry->symlink_target, symlink_target) != 0) + { + if (dir_entry->symlink_target) + free (dir_entry->symlink_target); + dir_entry->symlink_target = symlink_target ? strdup (symlink_target) : 0; + } + } + + /* The st_ino field is always valid. */ + dir_entry->stat.st_ino = ino; + dir_entry->stat.st_fsid = fs->fsid; + dir_entry->stat.st_fstype = PROCFILESYSTEM; + + dir_entry->valid = 1; + + if (! dir_entry->ordered_self_p) + /* Position DIR_ENTRY in the ordered chain following the previously seen entry. */ + { + /* The PREV_ENTRY_NEXT_P field holds a pointer to the NEXT-field of the + previous entry, or a pointer to the ORDERED field in the directory. */ + dir_entry->ordered_self_p = cur_entry; + + if (*dir_entry->ordered_self_p) + /* Update the self_p pointer of the previous successor. */ + (*dir_entry->ordered_self_p)->ordered_self_p = &dir_entry->ordered_next; + + /* DIR_ENTRY comes before the previous successor. */ + dir_entry->ordered_next = *dir_entry->ordered_self_p; + + *dir_entry->ordered_self_p = dir_entry; /* Put DIR_ENTRY there. */ + } + + /* Put the next entry after this one. */ + cur_entry = &dir_entry->ordered_next; + + return dir_entry; +} + +/* Fills DIR, the root directory with all the pids of + processes running in the system as directories. */ +error_t +procfs_fill_root_dir(struct procfs_dir *dir, time_t timestamp) +{ + error_t err; + char *data; + pid_t *pids; + int pidslen; + struct stat *stat = (struct stat *) malloc (sizeof (struct stat)); + stat->st_mode = S_IFDIR; + + int count; + char *dir_name_pid; + struct node *node; + struct procfs_dir *new_dir; + struct procfs_dir_entry *dir_entry; + + pids = NULL; + pidslen = 0; + err = proc_getallpids (getproc (), &pids, &pidslen); + + if (!err) + { + for (count = 0; count < pidslen; count++) + { + if (asprintf (&dir_name_pid, "%d", pids[count]) == -1) + return errno; + +#if 0 + node = (struct node *) malloc (sizeof (struct node)); + new_dir = (struct procfs_dir *) malloc (sizeof (struct procfs_dir )); + + if (! node || ! new_dir ) + return ENOMEM; +#endif + dir_entry = update_entries_list (dir, dir_name_pid, + stat, timestamp, NULL); + err = procfs_create_node (dir_entry, dir_name_pid, &node); + + procfs_dir_create (dir->fs, node, + dir_name_pid, &new_dir); + free(dir_name_pid); + } + } + + if ((err = procfs_create_uptime (dir, &node, timestamp)) != 0) + return err; + + if ((err = procfs_create_stat (dir, &node, timestamp)) != 0) + return err; + + if ((err = procfs_create_version (dir, &node, timestamp)) != 0) + return err; + + if ((err = procfs_create_meminfo (dir, &node, timestamp)) != 0) + return err; + + if ((err = procfs_create_loadavg (dir, &node, timestamp)) != 0) + return err; + + return 0; +} + +error_t update_dir_entries (struct procfs_dir *dir) +{ + /* STUB */ + return 0; +} diff --git a/procfs_nonpid_files.c b/procfs_nonpid_files.c new file mode 100644 index 0000000..104ae8b --- /dev/null +++ b/procfs_nonpid_files.c @@ -0,0 +1,462 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + procfs_nonpid_files.c -- This file contains function definitions + to create and update the non-Per PID + files and their contents. + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + + A portion of the code in this file is based on vmstat.c code + present in the hurd repositories copyrighted to FSF. The + Copyright notice from that file is given below. + + Copyright (C) 1997,98,2002 Free Software Foundation, Inc. + Written by Miles Bader + This file is part of the GNU Hurd. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "procfs.h" + +typedef long long val_t; +#define BADVAL ((val_t) - 1LL) + +/* default pager port (must be privileged to fetch this). */ +mach_port_t def_pager; +struct default_pager_info def_pager_info; + +error_t procfs_create_uptime (struct procfs_dir *dir, + struct node **node, + time_t timestamp) +{ + int err; + char *file_name, *file_path; + struct procfs_dir_entry *dir_entry; + + if (asprintf (&file_name, "%s", "uptime") == -1) + return errno; + if (asprintf (&file_path, "%s", "uptime") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + return err; +} + +error_t procfs_create_version(struct procfs_dir *dir, + struct node **node, + time_t timestamp) +{ + int err; + char *file_name, *file_path; + struct procfs_dir_entry *dir_entry; + + if (asprintf (&file_name, "%s", "version") == -1) + return errno; + if (asprintf (&file_path, "%s", "version") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + return 0; +} + +error_t procfs_create_stat (struct procfs_dir *dir, + struct node **node, + time_t timestamp) +{ + int err; + char *file_name, *file_path; + struct procfs_dir_entry *dir_entry; + + if (asprintf (&file_name, "%s", "stat") == -1) + return errno; + if (asprintf (&file_path, "%s", "stat") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + return err; +} + +error_t procfs_create_meminfo (struct procfs_dir *dir, + struct node **node, + time_t timestamp) +{ + int err; + char *file_name, *file_path; + struct procfs_dir_entry *dir_entry; + + if (asprintf (&file_name, "%s", "meminfo") == -1) + return errno; + if (asprintf (&file_path, "%s", "meminfo") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + return err; +} + +error_t procfs_create_loadavg (struct procfs_dir *dir, + struct node **node, + time_t timestamp) +{ + int err; + char *file_name, *file_path; + struct procfs_dir_entry *dir_entry; + + if (asprintf (&file_name, "%s", "loadavg") == -1) + return errno; + if (asprintf (&file_path, "%s", "loadavg") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + return err; +} + +error_t get_uptime (double *uptime_secs) +{ + struct timeval boot_time, uptime, now; + error_t err; + struct proc_stat *ps; + + err = _proc_stat_create (1, ps_context, &ps); + + if (err) + return err; + + err = proc_stat_set_flags (ps, PSTAT_TASK_BASIC); + if (!err && !(ps->flags & PSTAT_TASK_BASIC)) + err = EGRATUITOUS; + + if (! err) + { + time_value_t *const tv = &proc_stat_task_basic_info (ps)->creation_time; + boot_time.tv_sec = tv->seconds; + boot_time.tv_usec = tv->microseconds; + if (gettimeofday (&now, 0) < 0) + error (0, errno, "gettimeofday"); + timersub (&now, &boot_time, &uptime); + *uptime_secs = (double)uptime.tv_sec + ((double)uptime.tv_usec / 1000000); + } + + _proc_stat_free (ps); + return err; +} + +error_t get_total_times (double *total_user_time_secs , double *total_system_time_secs ) +{ + error_t err; + pid_t *pids; + int pidslen = 0, count; + struct proc_stat *ps; + struct task_thread_times_info live_threads_times; + + *total_user_time_secs = 0; + *total_system_time_secs = 0; + + pids = NULL; + err = proc_getallpids (getproc (), &pids, &pidslen); + + if (!err) + for (count = 0; count < pidslen; count++) + { + err = _proc_stat_create (pids[count], ps_context, &ps); + if (err) + return err; + + err = proc_stat_set_flags (ps, PSTAT_TASK_BASIC); + if (!err && !(ps->flags & PSTAT_TASK_BASIC)) + err = EGRATUITOUS; + + if (! err) + { + *total_user_time_secs += + ((double) (proc_stat_task_basic_info (ps)->user_time.seconds)) + + (((double) (proc_stat_task_basic_info (ps)->user_time.microseconds)) / + (1000 * 1000)); + + *total_system_time_secs += + ((double) (proc_stat_task_basic_info (ps)->system_time.seconds)) + + (((double) (proc_stat_task_basic_info (ps)->system_time.microseconds)) / (1000 * 1000)); + + error_t err = set_field_value (ps, PSTAT_TASK); + if (! err) + { + err = get_task_thread_times (ps->task, &live_threads_times); + if (! err) + { + *total_user_time_secs += ((double) (live_threads_times.user_time.seconds)) + + (((double) (live_threads_times.user_time.microseconds)) / (1000 * 1000)); + *total_system_time_secs += ((double) (live_threads_times.system_time.seconds)) + + (((double) (live_threads_times.system_time.microseconds)) / (1000 * 1000)); + + } + } + } + _proc_stat_free (ps); + } + + return err; +} + +error_t procfs_write_nonpid_stat (struct dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *stat_data; + error_t err; + double uptime_secs, total_user_time_secs; + double total_system_time_secs, idle_time_secs; + + err = get_uptime (&uptime_secs); + if (! err) + { + err = get_total_times (&total_user_time_secs, &total_system_time_secs); + if (! err) + { + idle_time_secs = uptime_secs - + total_system_time_secs; + + /* If the values are multiplied by 100, it iss done so to adjust + values in seconds to jiffies. */ + if (asprintf (&stat_data, "cpu %ld %ld %ld %ld %ld %ld %d %d %d\n" + "cpu0 %ld %ld %ld %ld %ld %ld %d %d %d\n" + "intr %ld %ld %ld %ld %ld %ld %d %d %d\n", + (long)(total_user_time_secs * 100), 0, + (long)(total_system_time_secs * 100), + (long) (idle_time_secs * 100), 0, 0, 0, 0, + 0, (long)(total_user_time_secs * 100), 0, + (long)(total_system_time_secs * 100), + (long)(idle_time_secs * 100), 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == -1) + return errno; + } + } + + memcpy (data, stat_data, strlen(stat_data)); + *len = strlen (data); + + free (stat_data); + return err; +} + +/* Makes sure the default pager port and associated + info exists, and returns 0 if not (after printing + an error). */ +static int +ensure_def_pager_info () +{ + error_t err; + + if (def_pager == MACH_PORT_NULL) + { + mach_port_t host; + + err = get_privileged_ports (&host, 0); + if (err == EPERM) + { + /* We are not root, so try opening the /servers file. */ + def_pager = file_name_lookup (_SERVERS_DEFPAGER, O_READ, 0); + if (def_pager == MACH_PORT_NULL) + { + error (0, errno, _SERVERS_DEFPAGER); + return 0; + } + } + if (def_pager == MACH_PORT_NULL) + { + if (err) + { + error (0, err, "get_privileged_ports"); + return 0; + } + + err = vm_set_default_memory_manager (host, &def_pager); + mach_port_deallocate (mach_task_self (), host); + + if (err) + { + error (0, err, "vm_set_default_memory_manager"); + return 0; + } + } + } + + if (!MACH_PORT_VALID (def_pager)) + { + if (def_pager == MACH_PORT_NULL) + { + error (0, 0, + "No default pager running, so no swap information available"); + def_pager = MACH_PORT_DEAD; /* so we don't try again */ + } + return 0; + } + + err = default_pager_info (def_pager, &def_pager_info); + if (err) + error (0, err, "default_pager_info"); + return (err == 0); +} + +#define SWAP_FIELD(getter, expr) \ + static val_t getter () \ + { return ensure_def_pager_info () ? (val_t) (expr) : BADVAL; } + +SWAP_FIELD (get_swap_size, def_pager_info.dpi_total_space) +SWAP_FIELD (get_swap_free, def_pager_info.dpi_free_space) +SWAP_FIELD (get_swap_page_size, def_pager_info.dpi_page_size) +SWAP_FIELD (get_swap_active, (def_pager_info.dpi_total_space + - def_pager_info.dpi_free_space)) + +error_t procfs_write_nonpid_meminfo (struct dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *meminfo_data; + error_t err; + struct vm_statistics vmstats; + + err = vm_statistics (mach_task_self (), &vmstats); + + unsigned long mem_size = ((vmstats.free_count + + vmstats.active_count + vmstats.inactive_count + + vmstats.wire_count) * vmstats.pagesize) / 1024; + + if (! err) + if (asprintf (&meminfo_data, "MemTotal:\t%lu kB\n" + "MemFree:\t%lu kB\n" + "Buffers:\t%ld kB\n" + "Cached:\t\t%ld kB\n" + "SwapCached:\t%ld kB\n" + "Active:\t\t%lu kB\n" + "Inactive:\t%lu kB\n" + "HighTotal:\t%lu kB\n" + "HighFree:\t%lu kB\n" + "LowTotal:\t%lu kB\n" + "LowFree:\t%lu kB\n" + "SwapTotal:\t%lu kB\n" + "SwapFree:\t%lu kB\n", + mem_size, (PAGES_TO_BYTES(vmstats.free_count)) / 1024 , 0, 0, 0, + (PAGES_TO_BYTES(vmstats.active_count)) / 1024, + (PAGES_TO_BYTES(vmstats.inactive_count)) / 1024, 0, 0, 0, 0, + get_swap_size (), get_swap_free ()) == -1) + return errno; + + memcpy (data, meminfo_data, strlen(meminfo_data)); + *len = strlen (data); + + free (meminfo_data); + return err; +} + +error_t procfs_write_nonpid_loadavg (struct dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *loadavg_data; + error_t err; + processor_set_info_t info; + natural_t *count; + struct host_load_info *load; + mach_port_t host; + + err = ps_host_load_info (&load); + if (err) + error (0, err, "ps_host_load_info"); + + if (! err) + if (asprintf (&loadavg_data, "%.2f %.2f %.2f %d/%d %d\n", + (double)load->avenrun[0] / (double)LOAD_SCALE, + (double)load->avenrun[1] / (double)LOAD_SCALE, + (double)load->avenrun[2] / (double)LOAD_SCALE, 0, 0, 0) == -1) + return errno; + + memcpy (data, loadavg_data, strlen(loadavg_data)); + *len = strlen (data); + + free (loadavg_data); + return err; +} + +error_t procfs_write_nonpid_uptime (struct dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *uptime_data; + error_t err; + double uptime_secs, total_user_time_secs; + double total_system_time_secs, idle_time_secs; + + err = get_uptime (&uptime_secs); + if (! err) + { + err = get_total_times (&total_user_time_secs, + &total_system_time_secs); + if (! err) + { + idle_time_secs = uptime_secs - + total_system_time_secs; + + if (asprintf (&uptime_data, "%.2f %.2f \n", + uptime_secs, idle_time_secs) == -1) + return errno; + } + } + + + memcpy (data, uptime_data, strlen(uptime_data)); + *len = strlen (data); + + free (uptime_data); + return err; +} diff --git a/procfs_pid.h b/procfs_pid.h new file mode 100644 index 0000000..811cca8 --- /dev/null +++ b/procfs_pid.h @@ -0,0 +1,86 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + procfs_pid.h -- This is the header file of which contains defintions + for structure of directory with PID as the name and + structure of each file in this directory. + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. +*/ + +#ifndef __PROCFS_PID_H__ +#define __PROCFS_PID_H__ + +struct procfs_pid_files +{ + struct procfs_cwd *procfs_cwd; + struct procfs_environ *procfs_environ; + struct procfs_cpu *procfs_cpu; + struct procfs_root *procfs_root; + struct procfs_exe *procfs_exe; + struct procfs_stat *_procfs_stat; + struct procfs_statm *procfs_statm; +}; + +struct procfs_stat +{ + pid_t pid; + char *comm; + char *state; + pid_t ppid; + pid_t pgid; + pid_t sid; + int tty_nr; + pid_t tty_pgrp; + unsigned flags; + long unsigned minflt; + long unsigned cminflt; + long unsigned majflt; + long unsigned cmajflt; + time_t utime; + time_t stime; + time_t cutime; + time_t cstime; + long priority; + long nice; + long num_threads; + long itrealvalue; + long long unsigned starttime; + long unsigned vsize; + long rss; + long unsigned rlim; + long unsigned startcode; + long unsigned endcode; + long unsigned startstack; + long unsigned kstkesp; + long unsigned kstkeip; + long unsigned signal; + long unsigned blocked; + long unsigned sigignore; + long unsigned sigcatch; + long unsigned wchan; + long unsigned nswap; + long unsigned cnswap; + int exit_signal; + int processor; + unsigned rt_priority; + unsigned policy; + long long unsigned delayacct_blkio_ticks; +}; + +#endif diff --git a/procfs_pid_files.c b/procfs_pid_files.c new file mode 100644 index 0000000..1012510 --- /dev/null +++ b/procfs_pid_files.c @@ -0,0 +1,570 @@ +/* procfs -- a translator for providing GNU/Linux compatible + proc pseudo-filesystem + + procfs_pid_files.c -- This file contains definitions to perform + file operations such as creating, writing to, + reading from and removing files that holds + information for each process with PID + + Copyright (C) 2008, FSF. + Written as a Summer of Code Project + + + procfs is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + procfs 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + + A portion of the code in this file is based on ftpfs code + present in the hurd repositories copyrighted to FSF. The + Copyright notice from that file is given below. + +*/ + +#include +#include +#include +#include +#include +#include + +#include "procfs.h" +#include "procfs_pid.h" + +/* Update the files named NAME within the directory named + PID also with SYMLINK TARGET if necessary. */ +struct procfs_dir_entry* +update_pid_entries (struct procfs_dir *dir, const char *name, + time_t timestamp, + const char *symlink_target) +{ + struct procfs_dir_entry *dir_entry; + struct stat *stat = (struct stat *) malloc (sizeof (struct stat)); + stat->st_mode = S_IFREG; + + dir_entry = update_entries_list (dir, name, stat, + timestamp, symlink_target); + + return dir_entry; +} + +/* Creates files to store process information for DIR + whose names are pids and returns these files in *NODE. */ +error_t +procfs_create_files (struct procfs_dir *dir, + struct node **node, + time_t timestamp) +{ + int err; + char *file_name, *file_path; + struct procfs_dir_entry *dir_entry; + + if (asprintf (&file_name, "%s", "stat") == -1) + return errno; + if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "stat") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + if (asprintf (&file_name, "%s", "status") == -1) + return errno; + if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "status") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + if (asprintf (&file_name, "%s", "cmdline") == -1) + return errno; + if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "cmdline") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + + if (asprintf (&file_name, "%s", "statm") == -1) + return errno; + if (asprintf (&file_path, "%s/%s", dir->node->nn->dir_entry->name, "statm") == -1) + return errno; + + dir_entry = update_pid_entries (dir, file_name, timestamp, NULL); + err = procfs_create_node (dir_entry, file_path, node); + + free (file_name); + free (file_path); + +#if 0 + nodes_list = &node_stat; + nodes_list++; + node = nodes_list; +#endif + + return err; +} + +/* Check if the PSTAT_FLAG is set in the corresponding PS + structure, if not set it and check again and return error + status accordingly. */ +error_t set_field_value (struct proc_stat *ps, int pstat_flag) +{ + error_t err; + + if (! (ps->flags & pstat_flag)) + { + err = proc_stat_set_flags (ps, pstat_flag); + if (err) + return err; + + /* This second check is done since ps.h specifies to + do so since the previous call would not have set + the required value. */ + if (! (ps->flags & pstat_flag)) + return EGRATUITOUS; + } + + return 0; +} + +/* Adjusts TIME_VAL structure having Seconds and + Microseconds into the value in jiffies. The + value of jiffy is a hack to adjust to what + procps uses. */ +time_t adjust_jiffy_time (time_value_t time_val) +{ + time_t jiffy_time = time_val.seconds * JIFFY_ADJUST; + jiffy_time += (time_val.microseconds * JIFFY_ADJUST) + / (1000 * 1000); + + return jiffy_time; +} + +/* Extract the user and system time for the live threads of + the process. This information is directly retrieved from + MACH since neither libps not proc makes this available. */ +error_t get_task_thread_times (task_t task, + struct task_thread_times_info *live_threads_times) +{ + error_t err; + size_t tkcount = TASK_THREAD_TIMES_INFO_COUNT; + + err = task_info (task, TASK_THREAD_TIMES_INFO, + (task_info_t) live_threads_times, &tkcount); + if (err == MACH_SEND_INVALID_DEST) + err = ESRCH; + + return err; +} + +/* Obtains the User Time in UTIME and System Time in STIME from + MACH directly since this is neither made available by libps + nor by proc server. */ +error_t get_live_threads_time (struct proc_stat *ps, + time_t *utime, time_t *stime) +{ + struct task_thread_times_info live_threads_times; + error_t err = set_field_value (ps, PSTAT_TASK); + + if (! err) + { + err = get_task_thread_times (ps->task, &live_threads_times); + if (! err) + { + *utime = adjust_jiffy_time ( + live_threads_times.user_time); + *stime = adjust_jiffy_time ( + live_threads_times.system_time); + } + } + + return err; +} + +/* Get the data for stat file into the structure + PROCFS_STAT. */ +error_t get_stat_data (pid_t pid, + struct procfs_stat **procfs_stat) +{ + error_t err; + struct procfs_stat *new = (struct procfs_stat *) + malloc (sizeof (struct procfs_stat)); + + struct proc_stat *ps; + time_t utime, stime; + + err = _proc_stat_create (pid, ps_context, &ps); + + new->pid = pid; + + if (! err) + { + err = set_field_value (ps, PSTAT_ARGS); + if (! err) + asprintf (&new->comm, "%s", ps->args); + } + + err = set_field_value (ps, PSTAT_STATE); + if (! err) + { + if (ps->state & PSTAT_STATE_P_STOP) + new->state = strdup ("T"); + if (ps->state & PSTAT_STATE_P_ZOMBIE) + new->state = strdup ("Z"); + if (ps->state & PSTAT_STATE_P_FG) + new->state = strdup ("+"); + if (ps->state & PSTAT_STATE_P_SESSLDR) + new->state = strdup ("s"); + if (ps->state & PSTAT_STATE_P_LOGINLDR) + new->state = strdup ("l"); + if (ps->state & PSTAT_STATE_P_FORKED) + new->state = strdup ("f"); + if (ps->state & PSTAT_STATE_P_NOMSG) + new->state = strdup ("m"); + if (ps->state & PSTAT_STATE_P_NOPARENT) + new->state = strdup ("p"); + if (ps->state & PSTAT_STATE_P_ORPHAN) + new->state = strdup ("o"); + if (ps->state & PSTAT_STATE_P_TRACE) + new->state = strdup ("x"); + if (ps->state & PSTAT_STATE_P_WAIT) + new->state = strdup ("w"); + if (ps->state & PSTAT_STATE_P_GETMSG) + new->state = strdup ("g"); + } + + err = set_field_value (ps, PSTAT_PROC_INFO); + if (! err) + { + new->ppid = ps->proc_info->ppid; + new->pgid = ps->proc_info->pgrp; + new->sid = ps->proc_info->session; + new->tty_pgrp = ps->proc_info->pgrp; + } + else + { + new->ppid = 0; + new->pgid = 0; + new->sid = 0; + new->tty_pgrp = 0; + } + + err = set_field_value (ps, PSTAT_STATE); + if (! err) + new->flags = ps->state; + else + new->flags = 0; + + err = set_field_value (ps, PSTAT_TASK_EVENTS); + if (! err) + { + new->minflt = ps->task_events_info->faults; + new->majflt = ps->task_events_info->pageins; + } + else + { + new->minflt = 0; + new->majflt = 0; + } + + /* This seems to be a bit inconsistent with setting of other + fields in this code. There are two reasons for this. + 1. The actual information required is not made available + by libps which should be directly obtained from MACH. + 2. The same code which is required to get the information + have to be reused in procfs_nonpid_files.c */ + err = get_live_threads_time (ps, &utime, &stime); + if (! err) + { + new->utime = utime; + new->stime = stime; + } + else + { + new->utime = 0; + new->stime = 0; + } + + err = set_field_value (ps, PSTAT_TASK_BASIC); + if (! err) + { + new->cutime = adjust_jiffy_time ( + ps->task_basic_info->user_time); + new->cstime = adjust_jiffy_time ( + ps->task_basic_info->system_time); + + new->priority = ps->task_basic_info->base_priority; + new->starttime = adjust_jiffy_time ( + ps->task_basic_info->creation_time); + + new->vsize = ps->task_basic_info->virtual_size; + new->rss = ps->task_basic_info->resident_size; + } + else + { + new->cutime = 0; + new->cstime = 0; + new->priority = 0; + new->starttime = 0; + new->vsize = 0; + new->rss = 0; + } + + new->nice = getpriority (0, pid); + + err = set_field_value (ps, PSTAT_NUM_THREADS); + if (! err) + new->num_threads = ps->num_threads; + else + new->num_threads = 0; + + /* Not Supported in Linux 2.6 or later. */ + new->tty_nr = 0; + new->itrealvalue = 0; + new->nswap = 0; + new->cnswap = 0; + + /* Temporarily set to 0 until correct + values are found .*/ + new->cminflt = 0; + new->cmajflt = 0; + new->rlim = 0; + new->startcode = 0; + new->endcode = 0; + new->startstack = 0; + new->kstkesp = 0; + new->kstkeip = 0; + new->signal = 0; + new->blocked = 0; + new->sigignore = 0; + new->sigcatch = 0; + new->wchan = 0; + new->exit_signal = 0; + new->processor = 0; + new->rt_priority = 0; + new->policy = 0; + new->delayacct_blkio_ticks = 0; + + *procfs_stat = new; + _proc_stat_free (ps); + + return err; +} + +/* Writes required process information to stat file + within the directory represented by pid. Return + the data in DATA and actual length to be written + in LEN. */ +error_t +procfs_write_stat_file (struct procfs_dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + error_t err; + char *stat_data; + struct procfs_stat *procfs_stat; + pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); + + err = get_stat_data (pid, &procfs_stat); + + if (asprintf (&stat_data, "%d (%s) %s %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu \n", + procfs_stat->pid, procfs_stat->comm, + procfs_stat->state, procfs_stat->ppid, + procfs_stat->pgid, procfs_stat->sid, + procfs_stat->tty_nr, procfs_stat->tty_pgrp, + procfs_stat->flags, procfs_stat->minflt, + procfs_stat->cminflt, procfs_stat->majflt, + procfs_stat->cmajflt, procfs_stat->utime, + procfs_stat->stime, procfs_stat->cutime, + procfs_stat->cstime, procfs_stat->priority, + procfs_stat->nice, procfs_stat->num_threads, + procfs_stat->itrealvalue, procfs_stat->starttime, + procfs_stat->vsize, BYTES_TO_PAGES(procfs_stat->rss), + procfs_stat->rlim, procfs_stat->startcode, + procfs_stat->endcode, procfs_stat->startstack, + procfs_stat->kstkesp, procfs_stat->kstkeip, + procfs_stat->signal, procfs_stat->blocked, + procfs_stat->sigignore, procfs_stat->sigcatch, + procfs_stat->wchan, procfs_stat->nswap, + procfs_stat->cnswap, procfs_stat->exit_signal, + procfs_stat->processor, procfs_stat->rt_priority, + procfs_stat->policy, + procfs_stat->delayacct_blkio_ticks) == -1) + return errno; + + + memcpy (data, stat_data, strlen(stat_data)); + *len = strlen (data); + + free (stat_data); + free (procfs_stat); + + return err; +} + +/* Writes required process's command line information + to cmline file within the directory represented by + pid. Return the data in DATA and actual length to + be written in LEN. */ +error_t +procfs_write_cmdline_file (struct procfs_dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *cmdline_data; + error_t err; + struct proc_stat *ps; + pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); + err = _proc_stat_create (pid, ps_context, &ps); + + err = set_field_value (ps, PSTAT_ARGS); + + if (! err) + if (asprintf (&cmdline_data, "%s \n", ps->args) == -1) + return errno; + + memcpy (data, cmdline_data, strlen(cmdline_data)); + *len = strlen (data); + + _proc_stat_free (ps); + free (cmdline_data); + return err; +} + +/* Writes required process's information that is represented by + stat and statm in a human readable format to status file + within the directory represented by pid. Return the data + in DATA and actual length to be written in LEN. */ +error_t +procfs_write_status_file (struct procfs_dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *status_data; + error_t err; + struct proc_stat *ps; + struct procfs_stat *procfs_stat; + + pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); + err = _proc_stat_create (pid, ps_context, &ps); + + err = get_stat_data (pid, &procfs_stat); + + if (! err) + if (asprintf (&status_data, "Name:\t%s\nState:\t%s\nTgid:\t%d\nPid:\t%d\n", procfs_stat->comm, procfs_stat->state, procfs_stat->pid, procfs_stat->pid) == -1) + return errno; + + memcpy (data, status_data, strlen(status_data)); + *len = strlen (data); + + _proc_stat_free (ps); + + free (status_data); + free (procfs_stat); + + return err; +} + +/* Writes required process information to statm file + within the directory represented by pid. Return + the data in DATA and actual length to be written + in LEN. */ +error_t +procfs_write_statm_file (struct procfs_dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *statm_data; + error_t err; + struct proc_stat *ps; + struct procfs_stat *procfs_stat; + + pid_t pid = atoi (dir_entry->dir->node->nn->dir_entry->name); + err = _proc_stat_create (pid, ps_context, &ps); + + err = get_stat_data (pid, &procfs_stat); + + if (! err) + if (asprintf (&statm_data, "%lu %ld %d %d %d %d %d\n", + BYTES_TO_PAGES(procfs_stat->vsize), + BYTES_TO_PAGES(procfs_stat->rss), + 0, 0, 0, 0, 0) == -1) + return errno; + + memcpy (data, statm_data, strlen(statm_data)); + *len = strlen (data); + + _proc_stat_free (ps); + + free (statm_data); + free (procfs_stat); + + return err; +} + +/* Writes required process information to each of files + within directory represented by pid, for files specified + by NODE. Return the data in DATA and actual length of + data in LEN. */ +error_t +procfs_write_files_contents (struct node *node, + off_t offset, size_t *len, void *data) +{ + error_t err; + + if (! strcmp (node->nn->dir_entry->name, "stat")) + if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) + err = procfs_write_nonpid_stat (node->nn->dir_entry, + offset, len, data); + else + err = procfs_write_stat_file (node->nn->dir_entry, + offset, len, data); + + if (! strcmp (node->nn->dir_entry->name, "cmdline")) + err = procfs_write_cmdline_file (node->nn->dir_entry, + offset, len, data); + + if (! strcmp (node->nn->dir_entry->name, "status")) + err = procfs_write_status_file (node->nn->dir_entry, + offset, len, data); + + if (! strcmp (node->nn->dir_entry->name, "statm")) + err = procfs_write_statm_file (node->nn->dir_entry, + offset, len, data); + + if (! strcmp (node->nn->dir_entry->name, "meminfo")) + if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) + err = procfs_write_nonpid_meminfo (node->nn->dir_entry, + offset, len, data); + else + err = ENOENT; + + if (! strcmp (node->nn->dir_entry->name, "loadavg")) + if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) + err = procfs_write_nonpid_loadavg (node->nn->dir_entry, + offset, len, data); + else + err = ENOENT; + + if (! strcmp (node->nn->dir_entry->name, "uptime")) + if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) + err = procfs_write_nonpid_uptime (node->nn->dir_entry, + offset, len, data); + else + err = ENOENT; + + return err; +} -- cgit v1.2.3 From 802ea16ef91b30bc4fa9a61779b5c3602219bb1d Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Mon, 18 Aug 2008 16:53:00 +0200 Subject: 2008-08-18 Madhusudan.C.S * procfs/ChangeLog: ChangeLog: Revised. --- ChangeLog | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 36f6bf5..eb17552 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,20 +1,20 @@ 2008-08-14 Madhusudan.C.S - * ChangeLog: New file added to procfs - * AUTHORS: New file added to procfs - * COPYING: New file added to procfs - * README: New file added to procfs - * Makefile: New file added to procfs - * bootstrap.c: New file added to procfs - * netfs.c: New file added to procfs - * node.c: New file added to procfs - * procfs.c: New file added to procfs - * procfs.h: New file added to procfs - * procfs_dir.c: New file added to procfs - * procfs_nonpid_files.c: New file added to procfs - * procfs_pid.h: New file added to procfs - * procfs_pid_files.c: New file added to procfs + * ChangeLog: New file. + * AUTHORS: New file. + * COPYING: New file. + * README: New file. + * Makefile: New file. + * bootstrap.c: New file. + * netfs.c: New file. + * node.c: New file. + * procfs.c: New file. + * procfs.h: New file. + * procfs_dir.c: New file. + * procfs_nonpid_files.c: New file. + * procfs_pid.h: New file. + * procfs_pid_files.c: New file. 2008-05-13 Madhusudan.C.S - * /sources/hurd/procfs: New directory added to the repository + * /sources/hurd/procfs: New directory added to the repository. -- cgit v1.2.3 From 0419c2813a91d0746cc70f4ecab33efca4b9440c Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Mon, 18 Aug 2008 17:15:00 +0200 Subject: 2008-08-14 Madhusudan.C.S * procfs.h: (jiffy_t): New typedef. * procfs_pid.h: "procfs.h" is included. (struct procfs_pid_files): Changed all the occurrences of time_t to jiffy_t. * procfs_pid_files.c: Removed "procfs.h". (adjust_jiffy_time): Changed return type from time_t to jiffy_t. Changed the type of jiffy_time variable from time_t to jiffy_t. (get_live_threads_time): Changed the type of utime and stime from time_t to jiffy_t. (get_stat_data): Changed the type of utime and stime from time_t to jiffy_t. --- ChangeLog | 15 +++++++++++++++ procfs.h | 2 ++ procfs_pid.h | 10 ++++++---- procfs_pid_files.c | 9 ++++----- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb17552..7cf1661 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-08-14 Madhusudan.C.S + * procfs.h: (jiffy_t): New typedef. + * procfs_pid.h: "procfs.h" is included. + (struct procfs_pid_files): Changed all the + occurrences of time_t to jiffy_t. + * procfs_pid_files.c: Removed "procfs.h". + (adjust_jiffy_time): Changed return type + from time_t to jiffy_t. + Changed the type of jiffy_time variable + from time_t to jiffy_t. + (get_live_threads_time): Changed the type + of utime and stime from time_t to jiffy_t. + (get_stat_data): Changed the type of utime + and stime from time_t to jiffy_t. + 2008-08-14 Madhusudan.C.S * ChangeLog: New file. diff --git a/procfs.h b/procfs.h index 95d4ee3..fa2fb7f 100644 --- a/procfs.h +++ b/procfs.h @@ -53,6 +53,8 @@ #include #include +typedef unsigned long long jiffy_t; + /* A single entry in a directory. */ struct procfs_dir_entry { diff --git a/procfs_pid.h b/procfs_pid.h index 811cca8..566c83e 100644 --- a/procfs_pid.h +++ b/procfs_pid.h @@ -26,6 +26,8 @@ #ifndef __PROCFS_PID_H__ #define __PROCFS_PID_H__ +#include "procfs.h" + struct procfs_pid_files { struct procfs_cwd *procfs_cwd; @@ -52,10 +54,10 @@ struct procfs_stat long unsigned cminflt; long unsigned majflt; long unsigned cmajflt; - time_t utime; - time_t stime; - time_t cutime; - time_t cstime; + jiffy_t utime; + jiffy_t stime; + jiffy_t cutime; + jiffy_t cstime; long priority; long nice; long num_threads; diff --git a/procfs_pid_files.c b/procfs_pid_files.c index 1012510..55cc52c 100644 --- a/procfs_pid_files.c +++ b/procfs_pid_files.c @@ -37,7 +37,6 @@ #include #include -#include "procfs.h" #include "procfs_pid.h" /* Update the files named NAME within the directory named @@ -148,9 +147,9 @@ error_t set_field_value (struct proc_stat *ps, int pstat_flag) Microseconds into the value in jiffies. The value of jiffy is a hack to adjust to what procps uses. */ -time_t adjust_jiffy_time (time_value_t time_val) +jiffy_t adjust_jiffy_time (time_value_t time_val) { - time_t jiffy_time = time_val.seconds * JIFFY_ADJUST; + jiffy_t jiffy_time = time_val.seconds * JIFFY_ADJUST; jiffy_time += (time_val.microseconds * JIFFY_ADJUST) / (1000 * 1000); @@ -178,7 +177,7 @@ error_t get_task_thread_times (task_t task, MACH directly since this is neither made available by libps nor by proc server. */ error_t get_live_threads_time (struct proc_stat *ps, - time_t *utime, time_t *stime) + jiffy_t *utime, jiffy_t *stime) { struct task_thread_times_info live_threads_times; error_t err = set_field_value (ps, PSTAT_TASK); @@ -208,7 +207,7 @@ error_t get_stat_data (pid_t pid, malloc (sizeof (struct procfs_stat)); struct proc_stat *ps; - time_t utime, stime; + jiffy_t utime, stime; err = _proc_stat_create (pid, ps_context, &ps); -- cgit v1.2.3 From a027dcc41d381a3c76a5b20d4d55ad9821af2308 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Mon, 18 Aug 2008 17:27:00 +0200 Subject: 2008-08-18 Madhusudan.C.S * procfs_nonpid_files.c: (procfs_write_nonpid_version): New function. * procfs_pid_files.c: (procfs_write_files_contents): Add a check to find if the read is requested for the version file and corresponding a call to it. --- ChangeLog | 8 ++++++++ procfs_nonpid_files.c | 18 +++++++++++++++++- procfs_pid_files.c | 7 +++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7cf1661..6079292 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-08-18 Madhusudan.C.S + * procfs_nonpid_files.c: + (procfs_write_nonpid_version): New function. + * procfs_pid_files.c: + (procfs_write_files_contents): Add a check + to find if the read is requested for the + version file and corresponding a call to it. + 2008-08-14 Madhusudan.C.S * procfs.h: (jiffy_t): New typedef. * procfs_pid.h: "procfs.h" is included. diff --git a/procfs_nonpid_files.c b/procfs_nonpid_files.c index 104ae8b..ab1341f 100644 --- a/procfs_nonpid_files.c +++ b/procfs_nonpid_files.c @@ -269,7 +269,7 @@ error_t procfs_write_nonpid_stat (struct dir_entry *dir_entry, idle_time_secs = uptime_secs - total_system_time_secs; - /* If the values are multiplied by 100, it iss done so to adjust + /* If the values are multiplied by 100, it is done so to adjust values in seconds to jiffies. */ if (asprintf (&stat_data, "cpu %ld %ld %ld %ld %ld %ld %d %d %d\n" "cpu0 %ld %ld %ld %ld %ld %ld %d %d %d\n" @@ -460,3 +460,19 @@ error_t procfs_write_nonpid_uptime (struct dir_entry *dir_entry, free (uptime_data); return err; } + +error_t procfs_write_nonpid_version (struct dir_entry *dir_entry, + off_t offset, size_t *len, void *data) +{ + char *version_data; + error_t err = 0; + + if (asprintf (&version_data, "Linux version 2.6.18\n", NULL) == -1) + return errno; + + memcpy (data, version_data, strlen(version_data)); + *len = strlen (data); + + free (version_data); + return err; +} diff --git a/procfs_pid_files.c b/procfs_pid_files.c index 55cc52c..3ad7734 100644 --- a/procfs_pid_files.c +++ b/procfs_pid_files.c @@ -565,5 +565,12 @@ procfs_write_files_contents (struct node *node, else err = ENOENT; + if (! strcmp (node->nn->dir_entry->name, "version")) + if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) + err = procfs_write_nonpid_version (node->nn->dir_entry, + offset, len, data); + else + err = ENOENT; + return err; } -- cgit v1.2.3 From 5bb07a3cb626b18aedfa463b6b344bf0fd963e71 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Mon, 18 Aug 2008 19:34:00 +0200 Subject: 2008-08-18 Madhusudan.C.S * procfs_nonpid_files.c: (get_uptime): Changed the parameter type from double to struct timeval. Changed the parameter name from uptime_secs to uptime. Removed uptime variable. Changed timersub to use the passed pointer instead of the local variable. Removed the calculation of uptime_secs. (get_total_times): Changed the parameters type from double to struct timeval. Changed the parameters name from total_user_time_secs to total_user_time and total_system_time_secs to total_system_time. New variables total_user_time_tmp, total_system_time_tmp and tmpval of type struct timeval. Call timerclear to clear the tmp variables. Remove calculation of times in seconds and do the same on struct timeval variables throughout using the timeradd macro. Assign values of temporary local variables to the pointers passed as parameters. (procfs_write_nonpid_stat): Replaced variables that hold time in seconds with struct timeval type variables and jiffy_t type variables. Argument to get_uptime changed from uptime_secs to uptime. Arguments to get_total_times changed from total_user_time_secs to total_user_time and total_system_time_secs to total_system_time. Replace arithematic time subtraction with timersub macro. Convert all the times in struct timeval type variables to jiffy_t type. Changed the type casting for the asprintf arguments to be compatible with jiffy_t type. (procfs_write_nonpid_uptime): Replaced variables that hold time in seconds with struct timeval type variables. Argument to get_uptime changed from uptime_secs to uptime. Arguments to get_total_times changed from total_user_time_secs to total_user_time and total_system_time_secs to total_system_time. Replace arithematic time subtraction with timersub macro. Convert all the times in struct timeval type variables to seconds. --- ChangeLog | 53 +++++++++++++++++++ procfs_nonpid_files.c | 138 +++++++++++++++++++++++++++++++------------------- 2 files changed, 140 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6079292..2e027f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,56 @@ +2008-08-18 Madhusudan.C.S + * procfs_nonpid_files.c: (get_uptime): + Changed the parameter type from double to + struct timeval. + Changed the parameter name from uptime_secs + to uptime. + Removed uptime variable. + Changed timersub to use the passed pointer + instead of the local variable. + Removed the calculation of uptime_secs. + (get_total_times): Changed the parameters + type from double to struct timeval. + Changed the parameters name from + total_user_time_secs to total_user_time + and total_system_time_secs to + total_system_time. + New variables total_user_time_tmp, + total_system_time_tmp and tmpval of type + struct timeval. + Call timerclear to clear the tmp variables. + Remove calculation of times in seconds and + do the same on struct timeval variables + throughout using the timeradd macro. + Assign values of temporary local variables + to the pointers passed as parameters. + (procfs_write_nonpid_stat): Replaced + variables that hold time in seconds with + struct timeval type variables and jiffy_t + type variables. + Argument to get_uptime changed from + uptime_secs to uptime. + Arguments to get_total_times changed from + total_user_time_secs to total_user_time and + total_system_time_secs to total_system_time. + Replace arithematic time subtraction with + timersub macro. + Convert all the times in struct timeval type + variables to jiffy_t type. + Changed the type casting for the asprintf + arguments to be compatible with jiffy_t type. + (procfs_write_nonpid_uptime): Replaced + variables that hold time in seconds with + struct timeval type variables. + Argument to get_uptime changed from + uptime_secs to uptime. + Arguments to get_total_times changed from + total_user_time_secs to total_user_time and + total_system_time_secs to total_system_time. + Replace arithematic time subtraction with + timersub macro. + Convert all the times in struct timeval type + variables to seconds. + 2008-08-18 Madhusudan.C.S * procfs_nonpid_files.c: (procfs_write_nonpid_version): New function. diff --git a/procfs_nonpid_files.c b/procfs_nonpid_files.c index ab1341f..9cb0c57 100644 --- a/procfs_nonpid_files.c +++ b/procfs_nonpid_files.c @@ -166,9 +166,9 @@ error_t procfs_create_loadavg (struct procfs_dir *dir, return err; } -error_t get_uptime (double *uptime_secs) +error_t get_uptime (struct timeval *uptime) { - struct timeval boot_time, uptime, now; + struct timeval boot_time, now; error_t err; struct proc_stat *ps; @@ -188,15 +188,15 @@ error_t get_uptime (double *uptime_secs) boot_time.tv_usec = tv->microseconds; if (gettimeofday (&now, 0) < 0) error (0, errno, "gettimeofday"); - timersub (&now, &boot_time, &uptime); - *uptime_secs = (double)uptime.tv_sec + ((double)uptime.tv_usec / 1000000); + timersub (&now, &boot_time, uptime); } _proc_stat_free (ps); return err; } -error_t get_total_times (double *total_user_time_secs , double *total_system_time_secs ) +error_t get_total_times (struct timeval *total_user_time, + struct timeval *total_system_time) { error_t err; pid_t *pids; @@ -204,8 +204,12 @@ error_t get_total_times (double *total_user_time_secs , double *total_system_tim struct proc_stat *ps; struct task_thread_times_info live_threads_times; - *total_user_time_secs = 0; - *total_system_time_secs = 0; + struct timeval total_user_time_tmp; + struct timeval total_system_time_tmp; + struct timeval tmpval; + + timerclear (&total_user_time_tmp); + timerclear (&total_system_time_tmp); pids = NULL; err = proc_getallpids (getproc (), &pids, &pidslen); @@ -222,33 +226,40 @@ error_t get_total_times (double *total_user_time_secs , double *total_system_tim err = EGRATUITOUS; if (! err) - { - *total_user_time_secs += - ((double) (proc_stat_task_basic_info (ps)->user_time.seconds)) + - (((double) (proc_stat_task_basic_info (ps)->user_time.microseconds)) / - (1000 * 1000)); + { + tmpval.tv_sec = proc_stat_task_basic_info (ps)->user_time.seconds; + tmpval.tv_usec = proc_stat_task_basic_info (ps)->user_time.seconds; + timeradd (&total_user_time_tmp, &tmpval, &total_user_time_tmp); + + tmpval.tv_sec = proc_stat_task_basic_info (ps)->system_time.seconds; + tmpval.tv_usec = proc_stat_task_basic_info (ps)->system_time.seconds; + timeradd (&total_system_time_tmp, &tmpval, &total_system_time_tmp); - *total_system_time_secs += - ((double) (proc_stat_task_basic_info (ps)->system_time.seconds)) + - (((double) (proc_stat_task_basic_info (ps)->system_time.microseconds)) / (1000 * 1000)); - error_t err = set_field_value (ps, PSTAT_TASK); if (! err) { err = get_task_thread_times (ps->task, &live_threads_times); if (! err) { - *total_user_time_secs += ((double) (live_threads_times.user_time.seconds)) + - (((double) (live_threads_times.user_time.microseconds)) / (1000 * 1000)); - *total_system_time_secs += ((double) (live_threads_times.system_time.seconds)) + - (((double) (live_threads_times.system_time.microseconds)) / (1000 * 1000)); - + tmpval.tv_sec = live_threads_times.user_time.seconds; + tmpval.tv_usec = live_threads_times.user_time.microseconds; + timeradd (&total_user_time_tmp, &tmpval, &total_user_time_tmp); + + tmpval.tv_sec = live_threads_times.system_time.seconds; + tmpval.tv_usec = live_threads_times.system_time.microseconds; + timeradd (&total_system_time_tmp, &tmpval, &total_system_time_tmp); } } } _proc_stat_free (ps); } - + + total_user_time->tv_sec = total_user_time_tmp.tv_sec; + total_user_time->tv_usec = total_user_time_tmp.tv_usec; + + total_system_time->tv_sec = total_system_time_tmp.tv_sec; + total_system_time->tv_usec = total_system_time_tmp.tv_usec; + return err; } @@ -257,30 +268,45 @@ error_t procfs_write_nonpid_stat (struct dir_entry *dir_entry, { char *stat_data; error_t err; - double uptime_secs, total_user_time_secs; - double total_system_time_secs, idle_time_secs; + jiffy_t total_user_time_jiffy, total_system_time_jiffy; + jiffy_t idle_time_jiffy; + struct timeval uptime, total_user_time, total_system_time; + struct timeval idle_time; - err = get_uptime (&uptime_secs); + err = get_uptime (&uptime); + if (! err) { - err = get_total_times (&total_user_time_secs, &total_system_time_secs); + err = get_total_times (&total_user_time, &total_system_time); + if (! err) { - idle_time_secs = uptime_secs - - total_system_time_secs; - - /* If the values are multiplied by 100, it is done so to adjust - values in seconds to jiffies. */ - if (asprintf (&stat_data, "cpu %ld %ld %ld %ld %ld %ld %d %d %d\n" - "cpu0 %ld %ld %ld %ld %ld %ld %d %d %d\n" - "intr %ld %ld %ld %ld %ld %ld %d %d %d\n", - (long)(total_user_time_secs * 100), 0, - (long)(total_system_time_secs * 100), - (long) (idle_time_secs * 100), 0, 0, 0, 0, - 0, (long)(total_user_time_secs * 100), 0, - (long)(total_system_time_secs * 100), - (long)(idle_time_secs * 100), 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == -1) + timersub (&uptime, &total_system_time, + &idle_time); + + total_user_time_jiffy = 100 * ((double) total_user_time.tv_sec + + (double) total_user_time.tv_usec / (1000 * 1000)); + total_system_time_jiffy = 100 * ((double) total_system_time.tv_sec + + (double) total_system_time.tv_usec / (1000 * 1000)); + idle_time_jiffy = 100 * ((double) idle_time.tv_sec + + (double) idle_time.tv_usec / (1000 * 1000)); + + if (asprintf (&stat_data, "cpu %llu %llu %llu %llu %llu %llu %d %d %d\n" + "cpu0 %llu %llu %llu %llu %llu %llu %d %d %d\n" + "intr %llu %llu %llu %llu %llu %llu %d %d %d\n", + total_user_time_jiffy, (long long unsigned) 0, + total_system_time_jiffy, idle_time_jiffy, + (long long unsigned) 0, (long long unsigned) 0, + 0, 0, 0, + total_user_time_jiffy, (long long unsigned) 0, + total_system_time_jiffy, idle_time_jiffy, + (long long unsigned) 0, (long long unsigned) 0, + 0, 0, 0, + (long long unsigned) 0, + (long long unsigned) 0, (long long unsigned) 0, (long long unsigned) 0, + (long long unsigned) 0, + (long long unsigned) 0, (long long unsigned) 0, + (long long unsigned) 0, (long long unsigned) 0) == -1) return errno; } } @@ -434,23 +460,33 @@ error_t procfs_write_nonpid_uptime (struct dir_entry *dir_entry, { char *uptime_data; error_t err; - double uptime_secs, total_user_time_secs; - double total_system_time_secs, idle_time_secs; + double uptime_secs, idle_time_secs; + + struct timeval uptime_val; + struct timeval uptime, total_user_time, total_system_time; + struct timeval idle_time; + - err = get_uptime (&uptime_secs); + err = get_uptime (&uptime); if (! err) { - err = get_total_times (&total_user_time_secs, - &total_system_time_secs); + err = get_total_times (&total_user_time, + &total_system_time); if (! err) { - idle_time_secs = uptime_secs - - total_system_time_secs; - - if (asprintf (&uptime_data, "%.2f %.2f \n", + timersub (&uptime, &total_system_time, + &idle_time); + + uptime_secs = (double) uptime.tv_sec + + (double) uptime.tv_usec / (1000 * 1000); + + idle_time_secs = (double) idle_time.tv_sec + + (double) idle_time.tv_usec / (1000 * 1000); + + if (asprintf (&uptime_data, "%.2f %.2f\n", uptime_secs, idle_time_secs) == -1) return errno; - } + } } -- cgit v1.2.3 From 151d56afe0d7d9eb527fb0a194f383435b2c0f65 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Mon, 18 Aug 2008 19:45:00 +0200 Subject: 2008-08-18 Madhusudan.C.S * README: Initial Documentation. --- ChangeLog | 3 +++ README | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2e027f5..e5bb241 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2008-08-18 Madhusudan.C.S + * README: Initial Documentation. + 2008-08-18 Madhusudan.C.S * procfs_nonpid_files.c: (get_uptime): Changed the parameter type from double to diff --git a/README b/README index e69de29..28b4aa3 100644 --- a/README +++ b/README @@ -0,0 +1,77 @@ +~~~~~~~~~~~~~~~ +1. Introduction +~~~~~~~~~~~~~~~ + + This program is called procfs, the /proc translator. This +program provides a GNU/Linux compatible /proc pseudo file- +system on GNU Hurd. This is called a translator since it +translates the process related information stored in the +MACH Microkernel which is made available through the proc +server and the libps library into a virtual filesystem. + +~~~~~~~ +2. Goal +~~~~~~~ + + The major goal of writing this translator was to make the +process related tools like pgrep, pkill, kill which are +packaged in procps, killall, pstree which are packaged in +psmisc and various other process related tools that rely +on GNU/Linux's /proc filesystem to run out of the box on +Hurd. + +~~~~~~~~~~ +3. Install +~~~~~~~~~~ + + To install this translator you can simply do the following. +Just cd to the top level directory of the hurd main source +tree. Run the configure script with the following command. +(In BASH) + +$ ./configure + +(If your shell is something else run the equivalent command). + +Now you can run make with procfs as a parameter if you want +to build only procfs. + +$ make procfs + +(This first builds all the dependencies of procfs and then +builds procfs as a part of Hurd main source tree.) + +After building the translator, you get a binary named procfs. +You need to set it as a translator. To do so you can type the +following command from the top level directory of Hurd main +source tree directory from where you ran make. + +$ settrans -fgap /proc procfs/procfs + +Viola! You are done setting up the translator. + +~~~~~~~~~~ +4. Testing +~~~~~~~~~~ + + Now in case you want to use the debian hurd binaries to work +with tools like pgrep, pkill, kill, htop etc, you can just +download the binaries which I have uploaded here: + +http://madhusudancs.info/procfs-testing-how-to-mini + +The patches to the source packages will be made available soon. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +5. Reporting Bugs and contacts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + I request all of you to help me in identifying the bugs in +procfs or in the procps or htop packages, so that I can fix +them. You are also free to submit patches if you feel so. The +patches can be sent either to bug-hurd mailing list or to my +e-mail adress. The e-mail IDs are as follows: + +bug-hurd@gnu.org +madhusudancs@gmail.com +madhusudan@madhusudancs.info -- cgit v1.2.3 From 4cce52a1ec161008243f5bee63df7f6230c0f7e6 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Mon, 18 Aug 2008 20:26:00 +0200 Subject: 2008-08-18 Madhusudan.C.S * procfs_nonpid_files.c: (procfs_write_nonpid_stat): Changed to procfs_read_nonpid_stat. (procfs_write_nonpid_meminfo): Changed to procfs_read_nonpid_meminfo. (procfs_write_nonpid_loadavg): Changed to procfs_read_nonpid_loadavg. (procfs_write_nonpid_uptime): Changed to procfs_read_nonpid_uptime. (procfs_write_nonpid_version):Changed to procfs_read_nonpid_version. * procfs_pid_files.c: (procfs_write_stat_file): Changed to procfs_read_stat_file. Changed the comment correspondingly from Write to Read. (procfs_write_cmdline_file ): Changed to procfs_read_cmdline_file. Changed the comment correspondingly from Write to Read. (procfs_write_status_file): Changed to procfs_read_status_file. Changed the comment correspondingly from Write to Read. (procfs_write_statm_file): Changed to procfs_read_statm_file. Changed the comment correspondingly from Write to Read. (procfs_write_files_contents): Changed to procfs_read_files_contents. Changed the comment correspondingly from Write to Read. Changed the call to procfs_write_nonpid_stat to procfs_read_nonpid_stat. Changed the call to procfs_write_stat_file to procfs_read_stat_file. Changed the call to procfs_write_cmdline_file to procfs_read_cmdline_file. Changed the call to procfs_write_status_file to procfs_read_status_file. Changed the call to procfs_write_statm_file to procfs_read_statm_file. Changed the call to procfs_write_nonpid_meminfo to procfs_read_nonpid_meminfo. Changed the call to procfs_write_nonpid_loadavg to procfs_read_nonpid_loadavg. Changed the call to procfs_write_nonpid_uptime to procfs_read_nonpid_uptime. Changed the call to procfs_write_nonpid_version to procfs_read_nonpid_version. netfs.c: (netfs_attempt_read): Changed the call from procfs_write_files_contents to procfs_read_files_contents. --- ChangeLog | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ netfs.c | 2 +- procfs_nonpid_files.c | 10 +++++----- procfs_pid_files.c | 46 +++++++++++++++++++++--------------------- 4 files changed, 84 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index e5bb241..730ad72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,58 @@ +2008-08-18 Madhusudan.C.S + * procfs_nonpid_files.c: + (procfs_write_nonpid_stat): Changed to + procfs_read_nonpid_stat. + (procfs_write_nonpid_meminfo): Changed to + procfs_read_nonpid_meminfo. + (procfs_write_nonpid_loadavg): Changed to + procfs_read_nonpid_loadavg. + (procfs_write_nonpid_uptime): Changed to + procfs_read_nonpid_uptime. + (procfs_write_nonpid_version):Changed to + procfs_read_nonpid_version. + * procfs_pid_files.c: + (procfs_write_stat_file): Changed to + procfs_read_stat_file. + Changed the comment correspondingly from + Write to Read. + (procfs_write_cmdline_file ): Changed to + procfs_read_cmdline_file. + Changed the comment correspondingly from + Write to Read. + (procfs_write_status_file): Changed to + procfs_read_status_file. + Changed the comment correspondingly from + Write to Read. + (procfs_write_statm_file): Changed to + procfs_read_statm_file. + Changed the comment correspondingly from + Write to Read. + (procfs_write_files_contents): Changed to + procfs_read_files_contents. + Changed the comment correspondingly from + Write to Read. + Changed the call to procfs_write_nonpid_stat + to procfs_read_nonpid_stat. + Changed the call to procfs_write_stat_file + to procfs_read_stat_file. + Changed the call to procfs_write_cmdline_file + to procfs_read_cmdline_file. + Changed the call to procfs_write_status_file + to procfs_read_status_file. + Changed the call to procfs_write_statm_file + to procfs_read_statm_file. + Changed the call to procfs_write_nonpid_meminfo + to procfs_read_nonpid_meminfo. + Changed the call to procfs_write_nonpid_loadavg + to procfs_read_nonpid_loadavg. + Changed the call to procfs_write_nonpid_uptime + to procfs_read_nonpid_uptime. + Changed the call to procfs_write_nonpid_version + to procfs_read_nonpid_version. + netfs.c: (netfs_attempt_read): Changed + the call from procfs_write_files_contents + to procfs_read_files_contents. + 2008-08-18 Madhusudan.C.S * README: Initial Documentation. diff --git a/netfs.c b/netfs.c index 31ffe1b..7e00e4d 100644 --- a/netfs.c +++ b/netfs.c @@ -435,7 +435,7 @@ error_t netfs_attempt_read (struct iouser *cred, struct node *node, if (! err) { if (*len > 0) - procfs_write_files_contents (node, offset, + procfs_read_files_contents (node, offset, len, data); if (*len > 0) if (offset >= *len) diff --git a/procfs_nonpid_files.c b/procfs_nonpid_files.c index 9cb0c57..15c0919 100644 --- a/procfs_nonpid_files.c +++ b/procfs_nonpid_files.c @@ -263,7 +263,7 @@ error_t get_total_times (struct timeval *total_user_time, return err; } -error_t procfs_write_nonpid_stat (struct dir_entry *dir_entry, +error_t procfs_read_nonpid_stat (struct dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *stat_data; @@ -387,7 +387,7 @@ SWAP_FIELD (get_swap_page_size, def_pager_info.dpi_page_size) SWAP_FIELD (get_swap_active, (def_pager_info.dpi_total_space - def_pager_info.dpi_free_space)) -error_t procfs_write_nonpid_meminfo (struct dir_entry *dir_entry, +error_t procfs_read_nonpid_meminfo (struct dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *meminfo_data; @@ -427,7 +427,7 @@ error_t procfs_write_nonpid_meminfo (struct dir_entry *dir_entry, return err; } -error_t procfs_write_nonpid_loadavg (struct dir_entry *dir_entry, +error_t procfs_read_nonpid_loadavg (struct dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *loadavg_data; @@ -455,7 +455,7 @@ error_t procfs_write_nonpid_loadavg (struct dir_entry *dir_entry, return err; } -error_t procfs_write_nonpid_uptime (struct dir_entry *dir_entry, +error_t procfs_read_nonpid_uptime (struct dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *uptime_data; @@ -497,7 +497,7 @@ error_t procfs_write_nonpid_uptime (struct dir_entry *dir_entry, return err; } -error_t procfs_write_nonpid_version (struct dir_entry *dir_entry, +error_t procfs_read_nonpid_version (struct dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *version_data; diff --git a/procfs_pid_files.c b/procfs_pid_files.c index 3ad7734..ed3a3bd 100644 --- a/procfs_pid_files.c +++ b/procfs_pid_files.c @@ -367,12 +367,12 @@ error_t get_stat_data (pid_t pid, return err; } -/* Writes required process information to stat file +/* Reads required process information from stat file within the directory represented by pid. Return the data in DATA and actual length to be written in LEN. */ error_t -procfs_write_stat_file (struct procfs_dir_entry *dir_entry, +procfs_read_stat_file (struct procfs_dir_entry *dir_entry, off_t offset, size_t *len, void *data) { error_t err; @@ -417,12 +417,12 @@ procfs_write_stat_file (struct procfs_dir_entry *dir_entry, return err; } -/* Writes required process's command line information - to cmline file within the directory represented by - pid. Return the data in DATA and actual length to - be written in LEN. */ +/* Reads required process's command line information + from cmline file within the directory represented + by pid. Return the data in DATA and actual length + to be written in LEN. */ error_t -procfs_write_cmdline_file (struct procfs_dir_entry *dir_entry, +procfs_read_cmdline_file (struct procfs_dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *cmdline_data; @@ -445,12 +445,12 @@ procfs_write_cmdline_file (struct procfs_dir_entry *dir_entry, return err; } -/* Writes required process's information that is represented by - stat and statm in a human readable format to status file +/* Reads required process's information that is represented by + stat and statm in a human readable format from status file within the directory represented by pid. Return the data in DATA and actual length to be written in LEN. */ error_t -procfs_write_status_file (struct procfs_dir_entry *dir_entry, +procfs_read_status_file (struct procfs_dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *status_data; @@ -478,12 +478,12 @@ procfs_write_status_file (struct procfs_dir_entry *dir_entry, return err; } -/* Writes required process information to statm file +/* Reads required process information from statm file within the directory represented by pid. Return the data in DATA and actual length to be written in LEN. */ error_t -procfs_write_statm_file (struct procfs_dir_entry *dir_entry, +procfs_read_statm_file (struct procfs_dir_entry *dir_entry, off_t offset, size_t *len, void *data) { char *statm_data; @@ -514,60 +514,60 @@ procfs_write_statm_file (struct procfs_dir_entry *dir_entry, return err; } -/* Writes required process information to each of files +/* Reads required process information from each of files within directory represented by pid, for files specified by NODE. Return the data in DATA and actual length of data in LEN. */ error_t -procfs_write_files_contents (struct node *node, +procfs_read_files_contents (struct node *node, off_t offset, size_t *len, void *data) { error_t err; if (! strcmp (node->nn->dir_entry->name, "stat")) if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_write_nonpid_stat (node->nn->dir_entry, + err = procfs_read_nonpid_stat (node->nn->dir_entry, offset, len, data); else - err = procfs_write_stat_file (node->nn->dir_entry, + err = procfs_read_stat_file (node->nn->dir_entry, offset, len, data); if (! strcmp (node->nn->dir_entry->name, "cmdline")) - err = procfs_write_cmdline_file (node->nn->dir_entry, + err = procfs_read_cmdline_file (node->nn->dir_entry, offset, len, data); if (! strcmp (node->nn->dir_entry->name, "status")) - err = procfs_write_status_file (node->nn->dir_entry, + err = procfs_read_status_file (node->nn->dir_entry, offset, len, data); if (! strcmp (node->nn->dir_entry->name, "statm")) - err = procfs_write_statm_file (node->nn->dir_entry, + err = procfs_read_statm_file (node->nn->dir_entry, offset, len, data); if (! strcmp (node->nn->dir_entry->name, "meminfo")) if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_write_nonpid_meminfo (node->nn->dir_entry, + err = procfs_read_nonpid_meminfo (node->nn->dir_entry, offset, len, data); else err = ENOENT; if (! strcmp (node->nn->dir_entry->name, "loadavg")) if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_write_nonpid_loadavg (node->nn->dir_entry, + err = procfs_read_nonpid_loadavg (node->nn->dir_entry, offset, len, data); else err = ENOENT; if (! strcmp (node->nn->dir_entry->name, "uptime")) if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_write_nonpid_uptime (node->nn->dir_entry, + err = procfs_read_nonpid_uptime (node->nn->dir_entry, offset, len, data); else err = ENOENT; if (! strcmp (node->nn->dir_entry->name, "version")) if (! strcmp (node->nn->dir_entry->dir->fs_path, "")) - err = procfs_write_nonpid_version (node->nn->dir_entry, + err = procfs_read_nonpid_version (node->nn->dir_entry, offset, len, data); else err = ENOENT; -- cgit v1.2.3 From 80e2bfc9ee29a5ecac3a9b8eaa2d470ae30222c9 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 29 Aug 2008 18:42:00 +0200 Subject: 2008-08-29 Madhusudan.C.S * Makefile: (Copyright): 1997, 2000 -> 2008 (CC): Removed. (CFLAGS): Removed. (INCLUDES): Removed. (all): Removed. ($(target)): Removed. (%.o): Removed. (HURDLIBS): -lnetfs -> netfs, -lfshelp -> fshelp, -liohelp -> iohelp, -lthreads -> threads, -lports -> ports, -lihash -> ihash, -lps -> ps, -lshouldbeinlibc -> shouldbeinlibc. (include): Add include ../Makeconf --- ChangeLog | 16 ++++++++++++++++ Makefile | 18 ++++-------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 730ad72..a56b992 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2008-08-29 Madhusudan.C.S + * Makefile: (Copyright): 1997, 2000 -> 2008 + (CC): Removed. + (CFLAGS): Removed. + (INCLUDES): Removed. + (all): Removed. + ($(target)): Removed. + (%.o): Removed. + (HURDLIBS): -lnetfs -> netfs, + -lfshelp -> fshelp, + -liohelp -> iohelp, -lthreads -> threads, + -lports -> ports, -lihash -> ihash, + -lps -> ps, + -lshouldbeinlibc -> shouldbeinlibc. + (include): Add include ../Makeconf + 2008-08-18 Madhusudan.C.S * procfs_nonpid_files.c: (procfs_write_nonpid_stat): Changed to diff --git a/Makefile b/Makefile index dae406d..500a237 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Makefile - for procfs # -# Copyright (C) 1997, 2000 Free Software Foundation, Inc. +# Copyright (C) 2008 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -21,20 +21,10 @@ makemode := server target = procfs -CC = gcc -CFLAGS = -Wall -g -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -INCLUDES = -I. - SRCS = procfs.c bootstrap.c netfs.c procfs_dir.c node.c procfs_pid_files.c procfs_nonpid_files.c LCLHDRS = procfs.h procfs_pid.h OBJS = $(SRCS:.c=.o) -HURDLIBS = -lnetfs -lfshelp -liohelp -lthreads -lports -lihash -lps -lshouldbeinlibc - -all: $(target) - -$(target): $(OBJS) - $(CC) $(CFLAGS) -o $(target) $(OBJS) $(HURDLIBS) - -%.o: %.c $(LCLHDRS) - $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< +HURDLIBS = netfs fshelp iohelp threads ports ihash ps shouldbeinlibc + +include ../Makeconf -- cgit v1.2.3 From b33bac72fa26be8676a6da73e0b13f51bcd40034 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 29 Aug 2008 21:34:00 +0200 Subject: 2008-08-29 Madhusudan.C.S * ChangeLog: Revised. --- ChangeLog | 290 +++++++++++++++++++++++++++----------------------------------- 1 file changed, 127 insertions(+), 163 deletions(-) diff --git a/ChangeLog b/ChangeLog index a56b992..91399f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,170 +1,134 @@ -2008-08-29 Madhusudan.C.S - * Makefile: (Copyright): 1997, 2000 -> 2008 - (CC): Removed. - (CFLAGS): Removed. - (INCLUDES): Removed. - (all): Removed. - ($(target)): Removed. - (%.o): Removed. - (HURDLIBS): -lnetfs -> netfs, - -lfshelp -> fshelp, - -liohelp -> iohelp, -lthreads -> threads, - -lports -> ports, -lihash -> ihash, - -lps -> ps, - -lshouldbeinlibc -> shouldbeinlibc. - (include): Add include ../Makeconf - -2008-08-18 Madhusudan.C.S - * procfs_nonpid_files.c: - (procfs_write_nonpid_stat): Changed to - procfs_read_nonpid_stat. - (procfs_write_nonpid_meminfo): Changed to - procfs_read_nonpid_meminfo. - (procfs_write_nonpid_loadavg): Changed to - procfs_read_nonpid_loadavg. - (procfs_write_nonpid_uptime): Changed to - procfs_read_nonpid_uptime. - (procfs_write_nonpid_version):Changed to - procfs_read_nonpid_version. - * procfs_pid_files.c: - (procfs_write_stat_file): Changed to - procfs_read_stat_file. - Changed the comment correspondingly from - Write to Read. - (procfs_write_cmdline_file ): Changed to - procfs_read_cmdline_file. - Changed the comment correspondingly from - Write to Read. - (procfs_write_status_file): Changed to - procfs_read_status_file. - Changed the comment correspondingly from - Write to Read. - (procfs_write_statm_file): Changed to - procfs_read_statm_file. - Changed the comment correspondingly from - Write to Read. - (procfs_write_files_contents): Changed to - procfs_read_files_contents. - Changed the comment correspondingly from - Write to Read. - Changed the call to procfs_write_nonpid_stat - to procfs_read_nonpid_stat. - Changed the call to procfs_write_stat_file - to procfs_read_stat_file. - Changed the call to procfs_write_cmdline_file - to procfs_read_cmdline_file. - Changed the call to procfs_write_status_file - to procfs_read_status_file. - Changed the call to procfs_write_statm_file - to procfs_read_statm_file. - Changed the call to procfs_write_nonpid_meminfo - to procfs_read_nonpid_meminfo. - Changed the call to procfs_write_nonpid_loadavg - to procfs_read_nonpid_loadavg. - Changed the call to procfs_write_nonpid_uptime - to procfs_read_nonpid_uptime. - Changed the call to procfs_write_nonpid_version - to procfs_read_nonpid_version. - netfs.c: (netfs_attempt_read): Changed - the call from procfs_write_files_contents - to procfs_read_files_contents. - -2008-08-18 Madhusudan.C.S - * README: Initial Documentation. +2008-08-29 Madhusudan.C.S -2008-08-18 Madhusudan.C.S - * procfs_nonpid_files.c: (get_uptime): - Changed the parameter type from double to - struct timeval. - Changed the parameter name from uptime_secs - to uptime. - Removed uptime variable. - Changed timersub to use the passed pointer - instead of the local variable. - Removed the calculation of uptime_secs. - (get_total_times): Changed the parameters - type from double to struct timeval. - Changed the parameters name from - total_user_time_secs to total_user_time - and total_system_time_secs to - total_system_time. - New variables total_user_time_tmp, - total_system_time_tmp and tmpval of type - struct timeval. - Call timerclear to clear the tmp variables. - Remove calculation of times in seconds and - do the same on struct timeval variables - throughout using the timeradd macro. - Assign values of temporary local variables - to the pointers passed as parameters. - (procfs_write_nonpid_stat): Replaced - variables that hold time in seconds with - struct timeval type variables and jiffy_t - type variables. - Argument to get_uptime changed from - uptime_secs to uptime. - Arguments to get_total_times changed from - total_user_time_secs to total_user_time and - total_system_time_secs to total_system_time. - Replace arithematic time subtraction with - timersub macro. - Convert all the times in struct timeval type - variables to jiffy_t type. - Changed the type casting for the asprintf - arguments to be compatible with jiffy_t type. - (procfs_write_nonpid_uptime): Replaced - variables that hold time in seconds with - struct timeval type variables. - Argument to get_uptime changed from - uptime_secs to uptime. - Arguments to get_total_times changed from - total_user_time_secs to total_user_time and - total_system_time_secs to total_system_time. - Replace arithematic time subtraction with - timersub macro. - Convert all the times in struct timeval type - variables to seconds. + * Makefile: (Copyright): 1997, 2000 -> 2008. + (CC): Removed. + (CFLAGS): Removed. + (INCLUDES): Removed. + (all): Removed. + ($(target)): Removed. + (%.o): Removed. + (HURDLIBS): -lnetfs -> netfs, -lfshelp -> fshelp, + -liohelp -> iohelp, -lthreads -> threads, -lports -> ports, + -lihash -> ihash, -lps -> ps, -lshouldbeinlibc -> shouldbeinlibc. + (include): Add include ../Makeconf -2008-08-18 Madhusudan.C.S - * procfs_nonpid_files.c: - (procfs_write_nonpid_version): New function. - * procfs_pid_files.c: - (procfs_write_files_contents): Add a check - to find if the read is requested for the - version file and corresponding a call to it. +2008-08-18 Madhusudan.C.S + + * procfs_nonpid_files.c: (procfs_write_nonpid_stat): Changed to + procfs_read_nonpid_stat. + (procfs_write_nonpid_meminfo): Changed to procfs_read_nonpid_meminfo. + (procfs_write_nonpid_loadavg): Changed to procfs_read_nonpid_loadavg. + (procfs_write_nonpid_uptime): Changed to procfs_read_nonpid_uptime. + (procfs_write_nonpid_version):Changed to procfs_read_nonpid_version. + * procfs_pid_files.c: (procfs_write_stat_file): Changed to + procfs_read_stat_file. + Changed the comment correspondingly from Write to Read. + (procfs_write_cmdline_file ): Changed to procfs_read_cmdline_file. + Changed the comment correspondingly from Write to Read. + (procfs_write_status_file): Changed to procfs_read_status_file. + Changed the comment correspondingly from Write to Read. + (procfs_write_statm_file): Changed to procfs_read_statm_file. + Changed the comment correspondingly from Write to Read. + (procfs_write_files_contents): Changed to procfs_read_files_contents. + Changed the comment correspondingly from Write to Read. + Changed the call to procfs_write_nonpid_stat to procfs_read_nonpid_stat. + Changed the call to procfs_write_stat_file to procfs_read_stat_file. + Changed the call to procfs_write_cmdline_file to + procfs_read_cmdline_file. + Changed the call to procfs_write_status_file to + procfs_read_status_file. + Changed the call to procfs_write_statm_file to + procfs_read_statm_file. + Changed the call to procfs_write_nonpid_meminfo to + procfs_read_nonpid_meminfo. + Changed the call to procfs_write_nonpid_loadavg to + procfs_read_nonpid_loadavg. + Changed the call to procfs_write_nonpid_uptime to + procfs_read_nonpid_uptime. + Changed the call to procfs_write_nonpid_version to + procfs_read_nonpid_version. + netfs.c: (netfs_attempt_read): Changed the call from + procfs_write_files_contents to procfs_read_files_contents. -2008-08-14 Madhusudan.C.S - * procfs.h: (jiffy_t): New typedef. - * procfs_pid.h: "procfs.h" is included. - (struct procfs_pid_files): Changed all the - occurrences of time_t to jiffy_t. - * procfs_pid_files.c: Removed "procfs.h". - (adjust_jiffy_time): Changed return type - from time_t to jiffy_t. - Changed the type of jiffy_time variable - from time_t to jiffy_t. - (get_live_threads_time): Changed the type - of utime and stime from time_t to jiffy_t. - (get_stat_data): Changed the type of utime - and stime from time_t to jiffy_t. +2008-08-18 Madhusudan.C.S + + * README: Initial Documentation. + +2008-08-18 Madhusudan.C.S + + * procfs_nonpid_files.c: (get_uptime): Changed the parameter type from + double to struct timeval. + Changed the parameter name from uptime_secs to uptime. + Removed uptime variable. + Changed timersub to use the passed pointer instead of the local + variable. + Removed the calculation of uptime_secs. + (get_total_times): Changed the parameters type from double to struct + timeval. + Changed the parameters name from total_user_time_secs to + total_user_time and total_system_time_secs to total_system_time. + New variables total_user_time_tmp, total_system_time_tmp and tmpval + of type struct timeval. + Call timerclear to clear the tmp variables. + Remove calculation of times in seconds and do the same on struct + timeval variables throughout using the timeradd macro. + Assign values of temporary local variables to the pointers passed + as parameters. + (procfs_write_nonpid_stat): Replaced variables that hold time in + seconds with struct timeval type variables and jiffy_t type variables. + Argument to get_uptime changed from uptime_secs to uptime. + Arguments to get_total_times changed from total_user_time_secs to + total_user_time and total_system_time_secs to total_system_time. + Replace arithematic time subtraction with timersub macro. + Convert all the times in struct timeval type variables to jiffy_t type. + Changed the type casting for the asprintf arguments to be compatible + with jiffy_t type. + (procfs_write_nonpid_uptime): Replaced variables that hold time in + seconds with struct timeval type variables. + Argument to get_uptime changed from uptime_secs to uptime. + Arguments to get_total_times changed from total_user_time_secs to + total_user_time and total_system_time_secs to total_system_time. + Replace arithematic time subtraction with timersub macro. + Convert all the times in struct timeval type variables to seconds. + +2008-08-18 Madhusudan.C.S + + * procfs_nonpid_files.c: (procfs_write_nonpid_version): New function. + * procfs_pid_files.c: (procfs_write_files_contents): Add a check + to find if the read is requested for the version file and + corresponding a call to it. + +2008-08-14 Madhusudan.C.S + + * procfs.h: (jiffy_t): New typedef. + * procfs_pid.h: "procfs.h" is included. + (struct procfs_pid_files): Changed all the occurrences of time_t to + jiffy_t. + * procfs_pid_files.c: Removed "procfs.h". + (adjust_jiffy_time): Changed return type from time_t to jiffy_t. + Changed the type of jiffy_time variable from time_t to jiffy_t. + (get_live_threads_time): Changed the type of utime and stime from + time_t to jiffy_t. + (get_stat_data): Changed the type of utime and stime from time_t to + jiffy_t. -2008-08-14 Madhusudan.C.S +2008-08-14 Madhusudan.C.S - * ChangeLog: New file. - * AUTHORS: New file. - * COPYING: New file. - * README: New file. - * Makefile: New file. - * bootstrap.c: New file. - * netfs.c: New file. - * node.c: New file. - * procfs.c: New file. - * procfs.h: New file. - * procfs_dir.c: New file. - * procfs_nonpid_files.c: New file. - * procfs_pid.h: New file. - * procfs_pid_files.c: New file. + * ChangeLog: New file. + * AUTHORS: New file. + * COPYING: New file. + * README: New file. + * Makefile: New file. + * bootstrap.c: New file. + * netfs.c: New file. + * node.c: New file. + * procfs.c: New file. + * procfs.h: New file. + * procfs_dir.c: New file. + * procfs_nonpid_files.c: New file. + * procfs_pid.h: New file. + * procfs_pid_files.c: New file. -2008-05-13 Madhusudan.C.S +2008-05-13 Madhusudan.C.S - * /sources/hurd/procfs: New directory added to the repository. + * /sources/hurd/procfs: New directory added to the repository. -- cgit v1.2.3 From fdd74966f222b67aa3161e809c6e9d8aacb16b12 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Sat, 30 Aug 2008 22:20:00 +0200 Subject: 2008-08-29 Madhusudan.C.S * AUTHORS: File removed. * COPYING: Likewise. * README: Likewise. --- AUTHORS | 10 -- COPYING | 340 -------------------------------------------------------------- ChangeLog | 6 ++ README | 77 -------------- 4 files changed, 6 insertions(+), 427 deletions(-) delete mode 100644 AUTHORS delete mode 100644 COPYING delete mode 100644 README diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 622b648..0000000 --- a/AUTHORS +++ /dev/null @@ -1,10 +0,0 @@ -Written By -~~~~~~~~~~ - -Madhusudan.C.S - - -Mentored By -~~~~~~~~~~~ - -Olaf Buddenhagen diff --git a/COPYING b/COPYING deleted file mode 100644 index 60549be..0000000 --- a/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/ChangeLog b/ChangeLog index 91399f2..e22887d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-08-29 Madhusudan.C.S + + * AUTHORS: File removed. + * COPYING: Likewise. + * README: Likewise. + 2008-08-29 Madhusudan.C.S * Makefile: (Copyright): 1997, 2000 -> 2008. diff --git a/README b/README deleted file mode 100644 index 28b4aa3..0000000 --- a/README +++ /dev/null @@ -1,77 +0,0 @@ -~~~~~~~~~~~~~~~ -1. Introduction -~~~~~~~~~~~~~~~ - - This program is called procfs, the /proc translator. This -program provides a GNU/Linux compatible /proc pseudo file- -system on GNU Hurd. This is called a translator since it -translates the process related information stored in the -MACH Microkernel which is made available through the proc -server and the libps library into a virtual filesystem. - -~~~~~~~ -2. Goal -~~~~~~~ - - The major goal of writing this translator was to make the -process related tools like pgrep, pkill, kill which are -packaged in procps, killall, pstree which are packaged in -psmisc and various other process related tools that rely -on GNU/Linux's /proc filesystem to run out of the box on -Hurd. - -~~~~~~~~~~ -3. Install -~~~~~~~~~~ - - To install this translator you can simply do the following. -Just cd to the top level directory of the hurd main source -tree. Run the configure script with the following command. -(In BASH) - -$ ./configure - -(If your shell is something else run the equivalent command). - -Now you can run make with procfs as a parameter if you want -to build only procfs. - -$ make procfs - -(This first builds all the dependencies of procfs and then -builds procfs as a part of Hurd main source tree.) - -After building the translator, you get a binary named procfs. -You need to set it as a translator. To do so you can type the -following command from the top level directory of Hurd main -source tree directory from where you ran make. - -$ settrans -fgap /proc procfs/procfs - -Viola! You are done setting up the translator. - -~~~~~~~~~~ -4. Testing -~~~~~~~~~~ - - Now in case you want to use the debian hurd binaries to work -with tools like pgrep, pkill, kill, htop etc, you can just -download the binaries which I have uploaded here: - -http://madhusudancs.info/procfs-testing-how-to-mini - -The patches to the source packages will be made available soon. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -5. Reporting Bugs and contacts -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - I request all of you to help me in identifying the bugs in -procfs or in the procps or htop packages, so that I can fix -them. You are also free to submit patches if you feel so. The -patches can be sent either to bug-hurd mailing list or to my -e-mail adress. The e-mail IDs are as follows: - -bug-hurd@gnu.org -madhusudancs@gmail.com -madhusudan@madhusudancs.info -- cgit v1.2.3 From 7a8b315855fc8edba2003fa69cb86cf664f4c2ec Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Sat, 30 Aug 2008 22:48:00 +0200 Subject: 2008-08-30 Madhusudan.C.S * procfs_dir.c: (procfs_dir_create): Assign newly created directory to its pointer in netnode. (procfs_dir_remove): Removed function. (free_entry): New function. (ordered_unlink): Likewise. (delete): Likewise. (sweep): Likewise. (procfs_dir_entries_remove): Likewise. (is_in_pid_list): Removed call to make_dir_invalid (). (procfs_fill_root_dir): struct stat *stat -> struct stat stat. Add Read and Execute permissions to all in stat.st_mode. Set stat.st_nlink to 1. Set stat.st_size to 0. Add struct proc_stat *ps definition. Set struct proc_stat data from _proc_stat_create () function and set stat.st_uid and stat.st_gid from the data in that structure. * procfs_pid_files.c: (update_pid_entries): Add Read permissions to all in stat->st_mode. --- ChangeLog | 21 ++++++++++ procfs_dir.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++------- procfs_pid_files.c | 2 +- 3 files changed, 126 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index e22887d..0e62b6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2008-08-30 Madhusudan.C.S + + * procfs_dir.c: (procfs_dir_create): Assign newly created directory to + its pointer in netnode. + (procfs_dir_remove): Removed function. + (free_entry): New function. + (ordered_unlink): Likewise. + (delete): Likewise. + (sweep): Likewise. + (procfs_dir_entries_remove): Likewise. + (is_in_pid_list): Removed call to make_dir_invalid (). + (procfs_fill_root_dir): struct stat *stat -> struct stat stat. + Add Read and Execute permissions to all in stat.st_mode. + Set stat.st_nlink to 1. + Set stat.st_size to 0. + Add struct proc_stat *ps definition. + Set struct proc_stat data from _proc_stat_create () function and + set stat.st_uid and stat.st_gid from the data in that structure. + * procfs_pid_files.c: (update_pid_entries): Add Read permissions + to all in stat->st_mode. + 2008-08-29 Madhusudan.C.S * AUTHORS: File removed. diff --git a/procfs_dir.c b/procfs_dir.c index b9b0410..f76e6a4 100644 --- a/procfs_dir.c +++ b/procfs_dir.c @@ -77,6 +77,9 @@ error_t procfs_dir_create (struct procfs *fs, struct node *node, *dir = new; + if (fs->root != 0) + node->nn->dir = new; + return 0; } @@ -343,14 +346,50 @@ procfs_dir_null_lookup (struct procfs_dir *dir, struct node **node) return err; } -/* Remove the specified DIR and free all its allocated - storage. */ -void procfs_dir_remove (struct procfs_dir *dir) +/* Free the directory entry DIR_ENTRY and all resources it consumes. */ +void +free_entry (struct procfs_dir_entry *dir_entry) { - /* STUB */ + assert (! dir_entry->self_p); /* We should only free deleted nodes. */ + free (dir_entry->name); + if (dir_entry->symlink_target) + free (dir_entry->symlink_target); + free (dir_entry->node->nn->dir); + free (dir_entry->node->nn); + free (dir_entry->node); + free (dir_entry); +} + +/* Remove DIR_ENTRY from its position in the ordered_next chain. */ +static void +ordered_unlink (struct procfs_dir_entry *dir_entry) +{ + if (dir_entry->ordered_self_p) + *dir_entry->ordered_self_p = dir_entry->ordered_next; + if (dir_entry->ordered_next) + dir_entry->ordered_next->self_p = dir_entry->ordered_self_p; +} + +/* Delete DIR_ENTRY from its directory, freeing any resources it holds. */ +static void +delete (struct procfs_dir_entry *dir_entry, struct procfs_dir *dir) +{ + dir->num_entries--; - return 0; + /* Take out of the hash chain. */ + if (dir_entry->self_p) + *dir_entry->self_p = dir_entry->next; + if (dir_entry->next) + dir_entry->next->self_p = dir_entry->self_p; + + /* Take out of the directory ordered list. */ + ordered_unlink (dir_entry); + + /* If there's a node attached, we'll delete the entry whenever it goes + away, otherwise, just delete it now. */ + if (! dir_entry->node) + free_entry (dir_entry); } /* Make all the directory entries invalid */ @@ -373,6 +412,41 @@ make_dir_invalid (struct procfs_dir *dir) } } +/* Delete any entries in DIR which don't have their valid bit set. */ +static void +sweep (struct procfs_dir *dir) +{ + size_t len = dir->htable_len, i; + struct procfs_dir_entry **htable = dir->htable, *dir_entry; + + for (i = 0; i < len; i++) + { + dir_entry = htable[i]; + while (dir_entry) + { + if (!dir_entry->valid && !dir_entry->noent && dir->num_entries) + delete (dir_entry, dir); + dir_entry = dir_entry->next; + } + if (htable[i]) + { + free (htable[i]); + htable[i] = 0; + } + + } + +} + +/* Remove the specified DIR and free all its allocated + storage. */ +void procfs_dir_entries_remove (struct procfs_dir *dir) +{ + /* Free all entries. */ + make_dir_invalid (dir); + sweep (dir); +} + /* Checks if the DIR name is in list of Active pids. */ int is_in_pid_list (struct procfs_dir *dir) @@ -417,7 +491,6 @@ error_t procfs_dir_refresh (struct procfs_dir *dir, int isroot) error_t err; int is_parent_pid; struct node *node; - make_dir_invalid (dir); struct timeval tv; maptime_read (procfs_maptime, &tv); @@ -513,14 +586,18 @@ procfs_fill_root_dir(struct procfs_dir *dir, time_t timestamp) char *data; pid_t *pids; int pidslen; - struct stat *stat = (struct stat *) malloc (sizeof (struct stat)); - stat->st_mode = S_IFDIR; + struct stat stat; + stat.st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | + S_IROTH | S_IXOTH; + stat.st_nlink = 1; + stat.st_size = 0; int count; char *dir_name_pid; struct node *node; struct procfs_dir *new_dir; struct procfs_dir_entry *dir_entry; + struct proc_stat *ps; pids = NULL; pidslen = 0; @@ -540,13 +617,25 @@ procfs_fill_root_dir(struct procfs_dir *dir, time_t timestamp) if (! node || ! new_dir ) return ENOMEM; #endif - dir_entry = update_entries_list (dir, dir_name_pid, - stat, timestamp, NULL); - err = procfs_create_node (dir_entry, dir_name_pid, &node); - - procfs_dir_create (dir->fs, node, - dir_name_pid, &new_dir); - free(dir_name_pid); + err = _proc_stat_create (pids[count], ps_context, &ps); + if (! err) + { + err = set_field_value (ps, PSTAT_PROC_INFO); + if (! err) + { + stat.st_uid = proc_stat_proc_info (ps)->owner; + stat.st_gid = proc_stat_proc_info (ps)->pgrp; + + dir_entry = update_entries_list (dir, dir_name_pid, + &stat, timestamp, NULL); + err = procfs_create_node (dir_entry, dir_name_pid, &node); + + procfs_dir_create (dir->fs, node, + dir_name_pid, &new_dir); + free(dir_name_pid); + _proc_stat_free (ps); + } + } } } diff --git a/procfs_pid_files.c b/procfs_pid_files.c index ed3a3bd..4686153 100644 --- a/procfs_pid_files.c +++ b/procfs_pid_files.c @@ -48,7 +48,7 @@ update_pid_entries (struct procfs_dir *dir, const char *name, { struct procfs_dir_entry *dir_entry; struct stat *stat = (struct stat *) malloc (sizeof (struct stat)); - stat->st_mode = S_IFREG; + stat->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; dir_entry = update_entries_list (dir, name, stat, timestamp, symlink_target); -- cgit v1.2.3 From 7e7201c453ad7faa5d26625ca9d263ee625ef5ed Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Tue, 2 Sep 2008 00:33:00 +0200 Subject: 2008-09-02 Madhusudan.C.S * netfs.c: (netfs_get_dirents): Add call to procfs_dir_entries_remove(). --- ChangeLog | 5 +++++ netfs.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0e62b6f..1750c16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-09-02 Madhusudan.C.S + + * netfs.c: (netfs_get_dirents): Add call to + procfs_dir_entries_remove(). + 2008-08-30 Madhusudan.C.S * procfs_dir.c: (procfs_dir_create): Assign newly created directory to diff --git a/netfs.c b/netfs.c index 7e00e4d..4f6fd5c 100644 --- a/netfs.c +++ b/netfs.c @@ -278,6 +278,7 @@ netfs_get_dirents (struct iouser *cred, struct node *dir, return ENOTDIR; } + procfs_dir_entries_remove (dir->nn->dir); return err; } -- cgit v1.2.3 From e58f247f9c3a95ea2805fe132777d192ef51f6d1 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 12 Dec 2008 01:48:00 +0100 Subject: 2008-12-12 Samuel Thibault * procfs_nonpid_files.c (procfs_read_nonpid_meminfo): Divide by 1024 value returned by get_swap_size and get_swap_free to get kilobytes. --- ChangeLog | 6 ++++++ procfs_nonpid_files.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1750c16..67a106b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-12-12 Samuel Thibault + + * procfs_nonpid_files.c (procfs_read_nonpid_meminfo): Divide by + 1024 value returned by get_swap_size and get_swap_free to get + kilobytes. + 2008-09-02 Madhusudan.C.S * netfs.c: (netfs_get_dirents): Add call to diff --git a/procfs_nonpid_files.c b/procfs_nonpid_files.c index 15c0919..d8b3a7d 100644 --- a/procfs_nonpid_files.c +++ b/procfs_nonpid_files.c @@ -417,7 +417,7 @@ error_t procfs_read_nonpid_meminfo (struct dir_entry *dir_entry, mem_size, (PAGES_TO_BYTES(vmstats.free_count)) / 1024 , 0, 0, 0, (PAGES_TO_BYTES(vmstats.active_count)) / 1024, (PAGES_TO_BYTES(vmstats.inactive_count)) / 1024, 0, 0, 0, 0, - get_swap_size (), get_swap_free ()) == -1) + get_swap_size () / 1024, get_swap_free () / 1024) == -1) return errno; memcpy (data, meminfo_data, strlen(meminfo_data)); -- cgit v1.2.3 From edb4593c38d421b5d538b221a991b50c36fdba15 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 31 May 2010 02:23:00 +0200 Subject: 2010-05-31 Samuel Thibault * procfs_nonpid_files.c (procfs_read_nonpid_meminfo): Print swap sizes using %llu. --- ChangeLog | 5 +++++ procfs_nonpid_files.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67a106b..47cbeaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Samuel Thibault + + * procfs_nonpid_files.c (procfs_read_nonpid_meminfo): Print swap sizes + using %llu. + 2008-12-12 Samuel Thibault * procfs_nonpid_files.c (procfs_read_nonpid_meminfo): Divide by diff --git a/procfs_nonpid_files.c b/procfs_nonpid_files.c index d8b3a7d..2c1209e 100644 --- a/procfs_nonpid_files.c +++ b/procfs_nonpid_files.c @@ -412,8 +412,8 @@ error_t procfs_read_nonpid_meminfo (struct dir_entry *dir_entry, "HighFree:\t%lu kB\n" "LowTotal:\t%lu kB\n" "LowFree:\t%lu kB\n" - "SwapTotal:\t%lu kB\n" - "SwapFree:\t%lu kB\n", + "SwapTotal:\t%llu kB\n" + "SwapFree:\t%llu kB\n", mem_size, (PAGES_TO_BYTES(vmstats.free_count)) / 1024 , 0, 0, 0, (PAGES_TO_BYTES(vmstats.active_count)) / 1024, (PAGES_TO_BYTES(vmstats.inactive_count)) / 1024, 0, 0, 0, 0, -- cgit v1.2.3 From d76613f23eec2a66f4727c69fcec3b5e3be3da22 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Sun, 1 Aug 2010 13:28:31 +0200 Subject: Switch to the new ChangeLog style. * ChangeLog: Wipe out content, and add instructions about how to get it back. --- ChangeLog | 179 ++------------------------------------------------------------ 1 file changed, 4 insertions(+), 175 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47cbeaf..0cd74d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,177 +1,6 @@ -2010-05-31 Samuel Thibault +edb4593c38d421b5d538b221a991b50c36fdba15 is the last commit imported from CVS. +All commits after that one have valid author and committer information. - * procfs_nonpid_files.c (procfs_read_nonpid_meminfo): Print swap sizes - using %llu. +Use this to examine the change log for earlier changes: -2008-12-12 Samuel Thibault - - * procfs_nonpid_files.c (procfs_read_nonpid_meminfo): Divide by - 1024 value returned by get_swap_size and get_swap_free to get - kilobytes. - -2008-09-02 Madhusudan.C.S - - * netfs.c: (netfs_get_dirents): Add call to - procfs_dir_entries_remove(). - -2008-08-30 Madhusudan.C.S - - * procfs_dir.c: (procfs_dir_create): Assign newly created directory to - its pointer in netnode. - (procfs_dir_remove): Removed function. - (free_entry): New function. - (ordered_unlink): Likewise. - (delete): Likewise. - (sweep): Likewise. - (procfs_dir_entries_remove): Likewise. - (is_in_pid_list): Removed call to make_dir_invalid (). - (procfs_fill_root_dir): struct stat *stat -> struct stat stat. - Add Read and Execute permissions to all in stat.st_mode. - Set stat.st_nlink to 1. - Set stat.st_size to 0. - Add struct proc_stat *ps definition. - Set struct proc_stat data from _proc_stat_create () function and - set stat.st_uid and stat.st_gid from the data in that structure. - * procfs_pid_files.c: (update_pid_entries): Add Read permissions - to all in stat->st_mode. - -2008-08-29 Madhusudan.C.S - - * AUTHORS: File removed. - * COPYING: Likewise. - * README: Likewise. - -2008-08-29 Madhusudan.C.S - - * Makefile: (Copyright): 1997, 2000 -> 2008. - (CC): Removed. - (CFLAGS): Removed. - (INCLUDES): Removed. - (all): Removed. - ($(target)): Removed. - (%.o): Removed. - (HURDLIBS): -lnetfs -> netfs, -lfshelp -> fshelp, - -liohelp -> iohelp, -lthreads -> threads, -lports -> ports, - -lihash -> ihash, -lps -> ps, -lshouldbeinlibc -> shouldbeinlibc. - (include): Add include ../Makeconf - -2008-08-18 Madhusudan.C.S - - * procfs_nonpid_files.c: (procfs_write_nonpid_stat): Changed to - procfs_read_nonpid_stat. - (procfs_write_nonpid_meminfo): Changed to procfs_read_nonpid_meminfo. - (procfs_write_nonpid_loadavg): Changed to procfs_read_nonpid_loadavg. - (procfs_write_nonpid_uptime): Changed to procfs_read_nonpid_uptime. - (procfs_write_nonpid_version):Changed to procfs_read_nonpid_version. - * procfs_pid_files.c: (procfs_write_stat_file): Changed to - procfs_read_stat_file. - Changed the comment correspondingly from Write to Read. - (procfs_write_cmdline_file ): Changed to procfs_read_cmdline_file. - Changed the comment correspondingly from Write to Read. - (procfs_write_status_file): Changed to procfs_read_status_file. - Changed the comment correspondingly from Write to Read. - (procfs_write_statm_file): Changed to procfs_read_statm_file. - Changed the comment correspondingly from Write to Read. - (procfs_write_files_contents): Changed to procfs_read_files_contents. - Changed the comment correspondingly from Write to Read. - Changed the call to procfs_write_nonpid_stat to procfs_read_nonpid_stat. - Changed the call to procfs_write_stat_file to procfs_read_stat_file. - Changed the call to procfs_write_cmdline_file to - procfs_read_cmdline_file. - Changed the call to procfs_write_status_file to - procfs_read_status_file. - Changed the call to procfs_write_statm_file to - procfs_read_statm_file. - Changed the call to procfs_write_nonpid_meminfo to - procfs_read_nonpid_meminfo. - Changed the call to procfs_write_nonpid_loadavg to - procfs_read_nonpid_loadavg. - Changed the call to procfs_write_nonpid_uptime to - procfs_read_nonpid_uptime. - Changed the call to procfs_write_nonpid_version to - procfs_read_nonpid_version. - netfs.c: (netfs_attempt_read): Changed the call from - procfs_write_files_contents to procfs_read_files_contents. - -2008-08-18 Madhusudan.C.S - - * README: Initial Documentation. - -2008-08-18 Madhusudan.C.S - - * procfs_nonpid_files.c: (get_uptime): Changed the parameter type from - double to struct timeval. - Changed the parameter name from uptime_secs to uptime. - Removed uptime variable. - Changed timersub to use the passed pointer instead of the local - variable. - Removed the calculation of uptime_secs. - (get_total_times): Changed the parameters type from double to struct - timeval. - Changed the parameters name from total_user_time_secs to - total_user_time and total_system_time_secs to total_system_time. - New variables total_user_time_tmp, total_system_time_tmp and tmpval - of type struct timeval. - Call timerclear to clear the tmp variables. - Remove calculation of times in seconds and do the same on struct - timeval variables throughout using the timeradd macro. - Assign values of temporary local variables to the pointers passed - as parameters. - (procfs_write_nonpid_stat): Replaced variables that hold time in - seconds with struct timeval type variables and jiffy_t type variables. - Argument to get_uptime changed from uptime_secs to uptime. - Arguments to get_total_times changed from total_user_time_secs to - total_user_time and total_system_time_secs to total_system_time. - Replace arithematic time subtraction with timersub macro. - Convert all the times in struct timeval type variables to jiffy_t type. - Changed the type casting for the asprintf arguments to be compatible - with jiffy_t type. - (procfs_write_nonpid_uptime): Replaced variables that hold time in - seconds with struct timeval type variables. - Argument to get_uptime changed from uptime_secs to uptime. - Arguments to get_total_times changed from total_user_time_secs to - total_user_time and total_system_time_secs to total_system_time. - Replace arithematic time subtraction with timersub macro. - Convert all the times in struct timeval type variables to seconds. - -2008-08-18 Madhusudan.C.S - - * procfs_nonpid_files.c: (procfs_write_nonpid_version): New function. - * procfs_pid_files.c: (procfs_write_files_contents): Add a check - to find if the read is requested for the version file and - corresponding a call to it. - -2008-08-14 Madhusudan.C.S - - * procfs.h: (jiffy_t): New typedef. - * procfs_pid.h: "procfs.h" is included. - (struct procfs_pid_files): Changed all the occurrences of time_t to - jiffy_t. - * procfs_pid_files.c: Removed "procfs.h". - (adjust_jiffy_time): Changed return type from time_t to jiffy_t. - Changed the type of jiffy_time variable from time_t to jiffy_t. - (get_live_threads_time): Changed the type of utime and stime from - time_t to jiffy_t. - (get_stat_data): Changed the type of utime and stime from time_t to - jiffy_t. - -2008-08-14 Madhusudan.C.S - - * ChangeLog: New file. - * AUTHORS: New file. - * COPYING: New file. - * README: New file. - * Makefile: New file. - * bootstrap.c: New file. - * netfs.c: New file. - * node.c: New file. - * procfs.c: New file. - * procfs.h: New file. - * procfs_dir.c: New file. - * procfs_nonpid_files.c: New file. - * procfs_pid.h: New file. - * procfs_pid_files.c: New file. - -2008-05-13 Madhusudan.C.S - - * /sources/hurd/procfs: New directory added to the repository. + $ git show edb4593c38d421b5d538b221a991b50c36fdba15:ChangeLog -- cgit v1.2.3 From 5d011324a721d7cf3babfe6aa068e247c7f27f42 Mon Sep 17 00:00:00 2001 From: Jeremie Koenig Date: Fri, 13 Aug 2010 19:05:13 +0200 Subject: update_pid_entries(): fix awkwardly indented uninitialized memory leak * procfs_pid_files.c (update_pid_entries): Replace dynamic allocation of `stat' with automatic allocation. Memset `stat' to 0. --- procfs_pid_files.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/procfs_pid_files.c b/procfs_pid_files.c index 4686153..d44a2a2 100644 --- a/procfs_pid_files.c +++ b/procfs_pid_files.c @@ -46,14 +46,12 @@ update_pid_entries (struct procfs_dir *dir, const char *name, time_t timestamp, const char *symlink_target) { - struct procfs_dir_entry *dir_entry; - struct stat *stat = (struct stat *) malloc (sizeof (struct stat)); - stat->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; + struct stat stat; - dir_entry = update_entries_list (dir, name, stat, - timestamp, symlink_target); + memset (&stat, 0, sizeof stat); + stat->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; - return dir_entry; + return update_entries_list (dir, name, &stat, timestamp, symlink_target); } /* Creates files to store process information for DIR -- cgit v1.2.3 From 5af547e7fc9ddc0b472b99c6bdb7341f6204e43f Mon Sep 17 00:00:00 2001 From: Jeremie Koenig Date: Fri, 13 Aug 2010 19:05:14 +0200 Subject: Set an appropriate st_mode on symlinks. * procfs_pid_files.c (update_pid_entries): When symlink_target is not NULL, set st_size to the symlink length and st_mode to S_IFLNK | 0777. --- procfs_pid_files.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/procfs_pid_files.c b/procfs_pid_files.c index d44a2a2..26a0af3 100644 --- a/procfs_pid_files.c +++ b/procfs_pid_files.c @@ -49,7 +49,16 @@ update_pid_entries (struct procfs_dir *dir, const char *name, struct stat stat; memset (&stat, 0, sizeof stat); - stat->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; + if (symlink_target) + { + stat.st_size = strlen (symlink_target); + stat.st_mode = S_IFLNK | 0777; + } + else + { + stat.st_size = 0; + stat.st_mode = S_IFREG | 0444; + } return update_entries_list (dir, name, &stat, timestamp, symlink_target); } -- cgit v1.2.3 From 1b55547480eff13851f2d53ff96afbace11c6004 Mon Sep 17 00:00:00 2001 From: Jeremie Koenig Date: Mon, 16 Aug 2010 13:36:52 +0200 Subject: Implement /proc/mounts as a symlink to /etc/mtab * procfs_nonpid_files.c (procfs_create_mounts): New function. * procfs_dir.c (procfs_fill_root_dir): Call procfs_create_mounts. Signed-off-by: Jeremie Koenig --- procfs_dir.c | 3 +++ procfs_nonpid_files.c | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/procfs_dir.c b/procfs_dir.c index f76e6a4..bd1e49d 100644 --- a/procfs_dir.c +++ b/procfs_dir.c @@ -654,6 +654,9 @@ procfs_fill_root_dir(struct procfs_dir *dir, time_t timestamp) if ((err = procfs_create_loadavg (dir, &node, timestamp)) != 0) return err; + if ((err = procfs_create_mounts (dir, &node, timestamp)) != 0) + return err; + return 0; } diff --git a/procfs_nonpid_files.c b/procfs_nonpid_files.c index 2c1209e..f130066 100644 --- a/procfs_nonpid_files.c +++ b/procfs_nonpid_files.c @@ -166,6 +166,19 @@ error_t procfs_create_loadavg (struct procfs_dir *dir, return err; } +error_t procfs_create_mounts (struct procfs_dir *dir, + struct node **node, + time_t timestamp) +{ + struct procfs_dir_entry *dir_entry; + int err; + + dir_entry = update_pid_entries (dir, "mounts", timestamp, "/etc/mtab"); + err = procfs_create_node (dir_entry, "mounts", node); + + return err; +} + error_t get_uptime (struct timeval *uptime) { struct timeval boot_time, now; -- cgit v1.2.3