Ruby  2.0.0p353(2013-11-22revision43784)
etc.c
Go to the documentation of this file.
1 /************************************************
2 
3  etc.c -
4 
5  $Author: nagachika $
6  created at: Tue Mar 22 18:39:19 JST 1994
7 
8 ************************************************/
9 
10 #include "ruby.h"
11 #include "ruby/encoding.h"
12 
13 #include <sys/types.h>
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17 
18 #ifdef HAVE_GETPWENT
19 #include <pwd.h>
20 #endif
21 
22 #ifdef HAVE_GETGRENT
23 #include <grp.h>
24 #endif
25 
26 static VALUE sPasswd;
27 #ifdef HAVE_GETGRENT
28 static VALUE sGroup;
29 #endif
30 
31 #ifdef _WIN32
32 #include <shlobj.h>
33 #ifndef CSIDL_COMMON_APPDATA
34 #define CSIDL_COMMON_APPDATA 35
35 #endif
36 #endif
37 
38 #ifndef _WIN32
39 char *getenv();
40 #endif
41 char *getlogin();
42 
43 /* call-seq:
44  * getlogin -> String
45  *
46  * Returns the short user name of the currently logged in user.
47  * Unfortunately, it is often rather easy to fool ::getlogin.
48  *
49  * Avoid ::getlogin for security-related purposes.
50  *
51  * If ::getlogin fails, try ::getpwuid.
52  *
53  * See the unix manpage for <code>getpwuid(3)</code> for more detail.
54  *
55  * e.g.
56  * Etc.getlogin -> 'guest'
57  */
58 static VALUE
60 {
61  char *login;
62 
63  rb_secure(4);
64 #ifdef HAVE_GETLOGIN
65  login = getlogin();
66  if (!login) login = getenv("USER");
67 #else
68  login = getenv("USER");
69 #endif
70 
71  if (login)
72  return rb_tainted_str_new2(login);
73  return Qnil;
74 }
75 
76 #if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)
77 static VALUE
78 safe_setup_str(const char *str)
79 {
80  if (str == 0) str = "";
81  return rb_tainted_str_new2(str);
82 }
83 #endif
84 
85 #ifdef HAVE_GETPWENT
86 static VALUE
87 setup_passwd(struct passwd *pwd)
88 {
89  if (pwd == 0) rb_sys_fail("/etc/passwd");
90  return rb_struct_new(sPasswd,
91  safe_setup_str(pwd->pw_name),
92 #ifdef HAVE_ST_PW_PASSWD
93  safe_setup_str(pwd->pw_passwd),
94 #endif
95  UIDT2NUM(pwd->pw_uid),
96  GIDT2NUM(pwd->pw_gid),
97 #ifdef HAVE_ST_PW_GECOS
98  safe_setup_str(pwd->pw_gecos),
99 #endif
100  safe_setup_str(pwd->pw_dir),
101  safe_setup_str(pwd->pw_shell),
102 #ifdef HAVE_ST_PW_CHANGE
103  INT2NUM(pwd->pw_change),
104 #endif
105 #ifdef HAVE_ST_PW_QUOTA
106  INT2NUM(pwd->pw_quota),
107 #endif
108 #ifdef HAVE_ST_PW_AGE
109  PW_AGE2VAL(pwd->pw_age),
110 #endif
111 #ifdef HAVE_ST_PW_CLASS
112  safe_setup_str(pwd->pw_class),
113 #endif
114 #ifdef HAVE_ST_PW_COMMENT
115  safe_setup_str(pwd->pw_comment),
116 #endif
117 #ifdef HAVE_ST_PW_EXPIRE
118  INT2NUM(pwd->pw_expire),
119 #endif
120  0 /*dummy*/
121  );
122 }
123 #endif
124 
125 /* call-seq:
126  * getpwuid(uid) -> Passwd
127  *
128  * Returns the /etc/passwd information for the user with the given integer +uid+.
129  *
130  * The information is returned as a Passwd struct.
131  *
132  * If +uid+ is omitted, the value from <code>Passwd[:uid]</code> is returned
133  * instead.
134  *
135  * See the unix manpage for <code>getpwuid(3)</code> for more detail.
136  *
137  * === Example:
138  *
139  * Etc.getpwuid(0)
140  * #=> #<struct Struct::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
141  */
142 static VALUE
144 {
145 #if defined(HAVE_GETPWENT)
146  VALUE id;
147  rb_uid_t uid;
148  struct passwd *pwd;
149 
150  rb_secure(4);
151  if (rb_scan_args(argc, argv, "01", &id) == 1) {
152  uid = NUM2UIDT(id);
153  }
154  else {
155  uid = getuid();
156  }
157  pwd = getpwuid(uid);
158  if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", (int)uid);
159  return setup_passwd(pwd);
160 #else
161  return Qnil;
162 #endif
163 }
164 
165 /* call-seq:
166  * getpwnam(name) -> Passwd
167  *
168  * Returns the /etc/passwd information for the user with specified login
169  * +name+.
170  *
171  * The information is returned as a Passwd struct.
172  *
173  * See the unix manpage for <code>getpwnam(3)</code> for more detail.
174  *
175  * === Example:
176  *
177  * Etc.getpwnam('root')
178  * #=> #<struct Struct::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
179  */
180 static VALUE
182 {
183 #ifdef HAVE_GETPWENT
184  struct passwd *pwd;
185 
186  SafeStringValue(nam);
187  pwd = getpwnam(RSTRING_PTR(nam));
188  if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam);
189  return setup_passwd(pwd);
190 #else
191  return Qnil;
192 #endif
193 }
194 
195 #ifdef HAVE_GETPWENT
196 static int passwd_blocking = 0;
197 static VALUE
198 passwd_ensure(void)
199 {
200  endpwent();
201  passwd_blocking = (int)Qfalse;
202  return Qnil;
203 }
204 
205 static VALUE
206 passwd_iterate(void)
207 {
208  struct passwd *pw;
209 
210  setpwent();
211  while (pw = getpwent()) {
212  rb_yield(setup_passwd(pw));
213  }
214  return Qnil;
215 }
216 
217 static void
218 each_passwd(void)
219 {
220  if (passwd_blocking) {
221  rb_raise(rb_eRuntimeError, "parallel passwd iteration");
222  }
223  passwd_blocking = (int)Qtrue;
224  rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
225 }
226 #endif
227 
228 /* call-seq:
229  * Etc.passwd { |struct| block } -> Passwd
230  * Etc.passwd -> Passwd
231  *
232  * Provides a convenient Ruby iterator which executes a block for each entry
233  * in the /etc/passwd file.
234  *
235  * The code block is passed an Passwd struct.
236  *
237  * See ::getpwent above for details.
238  *
239  * Example:
240  *
241  * require 'etc'
242  *
243  * Etc.passwd {|u|
244  * puts u.name + " = " + u.gecos
245  * }
246  *
247  */
248 static VALUE
250 {
251 #ifdef HAVE_GETPWENT
252  struct passwd *pw;
253 
254  rb_secure(4);
255  if (rb_block_given_p()) {
256  each_passwd();
257  }
258  else if (pw = getpwent()) {
259  return setup_passwd(pw);
260  }
261 #endif
262  return Qnil;
263 }
264 
265 /* call-seq:
266  * Etc::Passwd.each { |struct| block } -> Passwd
267  * Etc::Passwd.each -> Enumerator
268  *
269  * Iterates for each entry in the /etc/passwd file if a block is given.
270  *
271  * If no block is given, returns the Enumerator.
272  *
273  * The code block is passed an Passwd struct.
274  *
275  * See ::getpwent above for details.
276  *
277  * Example:
278  *
279  * require 'etc'
280  *
281  * Etc::Passwd.each {|u|
282  * puts u.name + " = " + u.gecos
283  * }
284  *
285  * Etc::Passwd.collect {|u| u.gecos}
286  * Etc::Passwd.collect {|u| u.gecos}
287  *
288  */
289 static VALUE
291 {
292 #ifdef HAVE_GETPWENT
293  RETURN_ENUMERATOR(obj, 0, 0);
294  each_passwd();
295 #endif
296  return obj;
297 }
298 
299 /* Resets the process of reading the /etc/passwd file, so that the next call
300  * to ::getpwent will return the first entry again.
301  */
302 static VALUE
304 {
305 #ifdef HAVE_GETPWENT
306  setpwent();
307 #endif
308  return Qnil;
309 }
310 
311 /* Ends the process of scanning through the /etc/passwd file begun with
312  * ::getpwent, and closes the file.
313  */
314 static VALUE
316 {
317 #ifdef HAVE_GETPWENT
318  endpwent();
319 #endif
320  return Qnil;
321 }
322 
323 /* Returns an entry from the /etc/passwd file.
324  *
325  * The first time it is called it opens the file and returns the first entry;
326  * each successive call returns the next entry, or +nil+ if the end of the file
327  * has been reached.
328  *
329  * To close the file when processing is complete, call ::endpwent.
330  *
331  * Each entry is returned as a Passwd struct.
332  *
333  */
334 static VALUE
336 {
337 #ifdef HAVE_GETPWENT
338  struct passwd *pw;
339 
340  if (pw = getpwent()) {
341  return setup_passwd(pw);
342  }
343 #endif
344  return Qnil;
345 }
346 
347 #ifdef HAVE_GETGRENT
348 static VALUE
349 setup_group(struct group *grp)
350 {
351  VALUE mem;
352  char **tbl;
353 
354  mem = rb_ary_new();
355  tbl = grp->gr_mem;
356  while (*tbl) {
357  rb_ary_push(mem, safe_setup_str(*tbl));
358  tbl++;
359  }
360  return rb_struct_new(sGroup,
361  safe_setup_str(grp->gr_name),
362 #ifdef HAVE_ST_GR_PASSWD
363  safe_setup_str(grp->gr_passwd),
364 #endif
365  GIDT2NUM(grp->gr_gid),
366  mem);
367 }
368 #endif
369 
370 /* call-seq:
371  * getgrgid(group_id) -> Group
372  *
373  * Returns information about the group with specified integer +group_id+,
374  * as found in /etc/group.
375  *
376  * The information is returned as a Group struct.
377  *
378  * See the unix manpage for <code>getgrgid(3)</code> for more detail.
379  *
380  * === Example:
381  *
382  * Etc.getgrgid(100)
383  * #=> #<struct Struct::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>
384  *
385  */
386 static VALUE
388 {
389 #ifdef HAVE_GETGRENT
390  VALUE id;
391  gid_t gid;
392  struct group *grp;
393 
394  rb_secure(4);
395  if (rb_scan_args(argc, argv, "01", &id) == 1) {
396  gid = NUM2GIDT(id);
397  }
398  else {
399  gid = getgid();
400  }
401  grp = getgrgid(gid);
402  if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", (int)gid);
403  return setup_group(grp);
404 #else
405  return Qnil;
406 #endif
407 }
408 
409 /* call-seq:
410  * getgrnam(name) -> Group
411  *
412  * Returns information about the group with specified +name+, as found in
413  * /etc/group.
414  *
415  * The information is returned as a Group struct.
416  *
417  * See the unix manpage for <code>getgrnam(3)</code> for more detail.
418  *
419  * === Example:
420  *
421  * Etc.getgrnam('users')
422  * #=> #<struct Struct::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>
423  *
424  */
425 static VALUE
427 {
428 #ifdef HAVE_GETGRENT
429  struct group *grp;
430 
431  rb_secure(4);
432  SafeStringValue(nam);
433  grp = getgrnam(RSTRING_PTR(nam));
434  if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam);
435  return setup_group(grp);
436 #else
437  return Qnil;
438 #endif
439 }
440 
441 #ifdef HAVE_GETGRENT
442 static int group_blocking = 0;
443 static VALUE
444 group_ensure(void)
445 {
446  endgrent();
447  group_blocking = (int)Qfalse;
448  return Qnil;
449 }
450 
451 
452 static VALUE
453 group_iterate(void)
454 {
455  struct group *pw;
456 
457  setgrent();
458  while (pw = getgrent()) {
459  rb_yield(setup_group(pw));
460  }
461  return Qnil;
462 }
463 
464 static void
465 each_group(void)
466 {
467  if (group_blocking) {
468  rb_raise(rb_eRuntimeError, "parallel group iteration");
469  }
470  group_blocking = (int)Qtrue;
471  rb_ensure(group_iterate, 0, group_ensure, 0);
472 }
473 #endif
474 
475 /* Provides a convenient Ruby iterator which executes a block for each entry
476  * in the /etc/group file.
477  *
478  * The code block is passed an Group struct.
479  *
480  * See ::getgrent above for details.
481  *
482  * Example:
483  *
484  * require 'etc'
485  *
486  * Etc.group {|g|
487  * puts g.name + ": " + g.mem.join(', ')
488  * }
489  *
490  */
491 static VALUE
493 {
494 #ifdef HAVE_GETGRENT
495  struct group *grp;
496 
497  rb_secure(4);
498  if (rb_block_given_p()) {
499  each_group();
500  }
501  else if (grp = getgrent()) {
502  return setup_group(grp);
503  }
504 #endif
505  return Qnil;
506 }
507 
508 #ifdef HAVE_GETGRENT
509 /* call-seq:
510  * Etc::Group.each { |group| block } -> obj
511  * Etc::Group.each -> Enumerator
512  *
513  * Iterates for each entry in the /etc/group file if a block is given.
514  *
515  * If no block is given, returns the Enumerator.
516  *
517  * The code block is passed a Group struct.
518  *
519  * Example:
520  *
521  * require 'etc'
522  *
523  * Etc::Group.each {|g|
524  * puts g.name + ": " + g.mem.join(', ')
525  * }
526  *
527  * Etc::Group.collect {|g| g.name}
528  * Etc::Group.select {|g| !g.mem.empty?}
529  *
530  */
531 static VALUE
532 etc_each_group(VALUE obj)
533 {
534  RETURN_ENUMERATOR(obj, 0, 0);
535  each_group();
536  return obj;
537 }
538 #endif
539 
540 /* Resets the process of reading the /etc/group file, so that the next call
541  * to ::getgrent will return the first entry again.
542  */
543 static VALUE
545 {
546 #ifdef HAVE_GETGRENT
547  setgrent();
548 #endif
549  return Qnil;
550 }
551 
552 /* Ends the process of scanning through the /etc/group file begun by
553  * ::getgrent, and closes the file.
554  */
555 static VALUE
557 {
558 #ifdef HAVE_GETGRENT
559  endgrent();
560 #endif
561  return Qnil;
562 }
563 
564 /* Returns an entry from the /etc/group file.
565  *
566  * The first time it is called it opens the file and returns the first entry;
567  * each successive call returns the next entry, or +nil+ if the end of the file
568  * has been reached.
569  *
570  * To close the file when processing is complete, call ::endgrent.
571  *
572  * Each entry is returned as a Group struct
573  */
574 static VALUE
576 {
577 #ifdef HAVE_GETGRENT
578  struct group *gr;
579 
580  if (gr = getgrent()) {
581  return setup_group(gr);
582  }
583 #endif
584  return Qnil;
585 }
586 
587 #define numberof(array) (sizeof(array) / sizeof(*(array)))
588 
589 #ifdef _WIN32
591 UINT rb_w32_system_tmpdir(WCHAR *path, UINT len);
592 VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
593 #endif
594 
595 /*
596  * Returns system configuration directory.
597  *
598  * This is typically "/etc", but is modified by the prefix used when Ruby was
599  * compiled. For example, if Ruby is built and installed in /usr/local, returns
600  * "/usr/local/etc".
601  */
602 static VALUE
604 {
605 #ifdef _WIN32
607 #else
608  return rb_filesystem_str_new_cstr(SYSCONFDIR);
609 #endif
610 }
611 
612 /*
613  * Returns system temporary directory; typically "/tmp".
614  */
615 static VALUE
617 {
618  VALUE tmpdir;
619 #ifdef _WIN32
620  WCHAR path[_MAX_PATH];
621  UINT len = rb_w32_system_tmpdir(path, numberof(path));
622  if (!len) return Qnil;
624 #else
625  tmpdir = rb_filesystem_str_new_cstr("/tmp");
626 #endif
627  FL_UNSET(tmpdir, FL_TAINT|FL_UNTRUSTED);
628  return tmpdir;
629 }
630 
631 /*
632  * The Etc module provides access to information typically stored in
633  * files in the /etc directory on Unix systems.
634  *
635  * The information accessible consists of the information found in the
636  * /etc/passwd and /etc/group files, plus information about the system's
637  * temporary directory (/tmp) and configuration directory (/etc).
638  *
639  * The Etc module provides a more reliable way to access information about
640  * the logged in user than environment variables such as +$USER+.
641  *
642  * == Example:
643  *
644  * require 'etc'
645  *
646  * login = Etc.getlogin
647  * info = Etc.getpwnam(login)
648  * username = info.gecos.split(/,/).first
649  * puts "Hello #{username}, I see your login name is #{login}"
650  *
651  * Note that the methods provided by this module are not always secure.
652  * It should be used for informational purposes, and not for security.
653  *
654  * All operations defined in this module are class methods, so that you can
655  * include the Etc module into your class.
656  */
657 void
658 Init_etc(void)
659 {
660  VALUE mEtc;
661 
662  mEtc = rb_define_module("Etc");
663  rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);
664 
665  rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1);
666  rb_define_module_function(mEtc, "getpwnam", etc_getpwnam, 1);
667  rb_define_module_function(mEtc, "setpwent", etc_setpwent, 0);
668  rb_define_module_function(mEtc, "endpwent", etc_endpwent, 0);
669  rb_define_module_function(mEtc, "getpwent", etc_getpwent, 0);
670  rb_define_module_function(mEtc, "passwd", etc_passwd, 0);
671 
672  rb_define_module_function(mEtc, "getgrgid", etc_getgrgid, -1);
673  rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1);
674  rb_define_module_function(mEtc, "group", etc_group, 0);
675  rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0);
676  rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0);
677  rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0);
678  rb_define_module_function(mEtc, "sysconfdir", etc_sysconfdir, 0);
679  rb_define_module_function(mEtc, "systmpdir", etc_systmpdir, 0);
680 
681  sPasswd = rb_struct_define("Passwd",
682  "name", "passwd", "uid", "gid",
683 #ifdef HAVE_ST_PW_GECOS
684  "gecos",
685 #endif
686  "dir", "shell",
687 #ifdef HAVE_ST_PW_CHANGE
688  "change",
689 #endif
690 #ifdef HAVE_ST_PW_QUOTA
691  "quota",
692 #endif
693 #ifdef HAVE_ST_PW_AGE
694  "age",
695 #endif
696 #ifdef HAVE_ST_PW_CLASS
697  "uclass",
698 #endif
699 #ifdef HAVE_ST_PW_COMMENT
700  "comment",
701 #endif
702 #ifdef HAVE_ST_PW_EXPIRE
703  "expire",
704 #endif
705  NULL);
706  /* Define-const: Passwd
707  *
708  * Passwd is a Struct that contains the following members:
709  *
710  * name::
711  * contains the short login name of the user as a String.
712  * passwd::
713  * contains the encrypted password of the user as a String.
714  * an 'x' is returned if shadow passwords are in use. An '*' is returned
715  * if the user cannot log in using a password.
716  * uid::
717  * contains the integer user ID (uid) of the user.
718  * gid::
719  * contains the integer group ID (gid) of the user's primary group.
720  * dir::
721  * contains the path to the home directory of the user as a String.
722  * shell::
723  * contains the path to the login shell of the user as a String.
724  *
725  * === The following members below are optional, and must be compiled with special flags:
726  *
727  * gecos::
728  * contains a longer String description of the user, such as
729  * a full name. Some Unix systems provide structured information in the
730  * gecos field, but this is system-dependent.
731  * must be compiled with +HAVE_ST_PW_GECOS+
732  * change::
733  * password change time(integer) must be compiled with +HAVE_ST_PW_CHANGE+
734  * quota::
735  * quota value(integer) must be compiled with +HAVE_ST_PW_QUOTA+
736  * age::
737  * password age(integer) must be compiled with +HAVE_ST_PW_AGE+
738  * class::
739  * user access class(string) must be compiled with +HAVE_ST_PW_CLASS+
740  * comment::
741  * comment(string) must be compiled with +HAVE_ST_PW_COMMENT+
742  * expire::
743  * account expiration time(integer) must be compiled with +HAVE_ST_PW_EXPIRE+
744  */
745  rb_define_const(mEtc, "Passwd", sPasswd);
748 
749 #ifdef HAVE_GETGRENT
750  sGroup = rb_struct_define("Group", "name",
751 #ifdef HAVE_ST_GR_PASSWD
752  "passwd",
753 #endif
754  "gid", "mem", NULL);
755 
756  /* Define-const: Group
757  *
758  * Group is a Struct that is only available when compiled with +HAVE_GETGRENT+.
759  *
760  * The struct contains the following members:
761  *
762  * name::
763  * contains the name of the group as a String.
764  * passwd::
765  * contains the encrypted password as a String. An 'x' is
766  * returned if password access to the group is not available; an empty
767  * string is returned if no password is needed to obtain membership of
768  * the group.
769  *
770  * Must be compiled with +HAVE_ST_GR_PASSWD+.
771  * gid::
772  * contains the group's numeric ID as an integer.
773  * mem::
774  * is an Array of Strings containing the short login names of the
775  * members of the group.
776  */
777  rb_define_const(mEtc, "Group", sGroup);
779  rb_define_singleton_method(sGroup, "each", etc_each_group, 0);
780 #endif
781 }
#define NUM2UIDT(v)
Definition: ruby.h:338
static VALUE sPasswd
Definition: etc.c:26
static VALUE etc_getpwnam(VALUE obj, VALUE nam)
Definition: etc.c:181
static VALUE etc_endgrent(VALUE obj)
Definition: etc.c:556
#define INT2NUM(x)
Definition: ruby.h:1178
static VALUE etc_group(VALUE obj)
Definition: etc.c:492
rb_uid_t getuid(void)
Definition: win32.c:2392
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1497
#define FL_TAINT
Definition: ruby.h:1115
static VALUE etc_setpwent(VALUE obj)
Definition: etc.c:303
static VALUE etc_getpwent(VALUE obj)
Definition: etc.c:335
#define Qtrue
Definition: ruby.h:434
static VALUE etc_setgrent(VALUE obj)
Definition: etc.c:544
const int id
Definition: nkf.c:209
VALUE rb_struct_new(VALUE,...)
Definition: struct.c:421
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
static VALUE etc_getgrnam(VALUE obj, VALUE nam)
Definition: etc.c:426
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
static VALUE etc_systmpdir(void)
Definition: etc.c:616
#define CSIDL_COMMON_APPDATA
Definition: win32.c:370
VALUE rb_tainted_str_new2(const char *)
static VALUE etc_getpwuid(int argc, VALUE *argv, VALUE obj)
Definition: etc.c:143
char * getenv()
#define FL_UNTRUSTED
Definition: ruby.h:1116
static VALUE etc_passwd(VALUE obj)
Definition: etc.c:249
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
Definition: win32.c:1953
void Init_etc(void)
Definition: etc.c:658
int rb_block_given_p(void)
Definition: eval.c:672
VALUE rb_eRuntimeError
Definition: error.c:510
VALUE rb_ary_new(void)
Definition: array.c:424
static VALUE etc_getgrgid(int argc, VALUE *argv, VALUE obj)
Definition: etc.c:387
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2202
int argc
Definition: ruby.c:130
#define Qfalse
Definition: ruby.h:433
UINT rb_w32_system_tmpdir(WCHAR *path, UINT len)
Definition: win32.c:460
#define numberof(array)
Definition: etc.c:587
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1512
VALUE rb_yield(VALUE)
Definition: vm_eval.c:934
VALUE rb_mEnumerable
Definition: enum.c:20
static VALUE etc_getlogin(VALUE obj)
Definition: etc.c:59
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
#define PRIsVALUE
Definition: ruby.h:147
#define Qnil
Definition: ruby.h:435
int type
Definition: tcltklib.c:111
unsigned long VALUE
Definition: ruby.h:104
void rb_extend_object(VALUE obj, VALUE module)
Definition: eval.c:1234
#define NUM2GIDT(v)
Definition: ruby.h:344
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
void rb_sys_fail(const char *mesg)
Definition: error.c:1899
#define FL_UNSET(x, f)
Definition: ruby.h:1150
#define RSTRING_PTR(str)
Definition: ruby.h:866
char * getlogin()
Definition: win32.c:762
static VALUE etc_each_passwd(VALUE obj)
Definition: etc.c:290
VALUE rb_w32_special_folder(int type)
Definition: win32.c:449
static VALUE etc_endpwent(VALUE obj)
Definition: etc.c:315
#define GIDT2NUM(v)
Definition: ruby.h:341
rb_encoding * rb_filesystem_encoding(void)
Definition: encoding.c:1248
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:220
#define SafeStringValue(v)
Definition: ruby.h:552
VALUE rb_filesystem_str_new_cstr(const char *)
Definition: string.c:614
#define UIDT2NUM(v)
Definition: ruby.h:335
rb_gid_t getgid(void)
Definition: win32.c:2406
void rb_secure(int)
Definition: safe.c:79
VALUE rb_struct_define(const char *,...)
Definition: struct.c:264
VALUE rb_define_module(const char *name)
Definition: class.c:617
#define NULL
Definition: _sdbm.c:103
static VALUE etc_sysconfdir(VALUE obj)
Definition: etc.c:603
VALUE rb_eArgError
Definition: error.c:512
static VALUE etc_getgrent(VALUE obj)
Definition: etc.c:575
char ** argv
Definition: ruby.c:131