G:/ScriptBasic/source/tools/shared.h

Go to the documentation of this file.
00001 /* shared.h: shared info for cygwin
00002 
00003    Copyright 1998, 1999, 2000 Cygnus Solutions.
00004 
00005 This file is part of Cygwin.
00006 
00007 This software is a copyrighted work licensed under the terms of the
00008 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
00009 details. */
00010 
00011 /******** Functions declarations for use in methods below ********/
00012 
00013 /* Printf type functions */
00014 extern "C" void __api_fatal (const char *, ...) __attribute__ ((noreturn));
00015 extern "C" int __small_sprintf (char *dst, const char *fmt, ...);
00016 extern "C" int __small_vsprintf (char *dst, const char *fmt, va_list ap);
00017 
00018 /******** Deletion Queue Class ********/
00019 
00020 /* First pass at a file deletion queue structure.
00021 
00022    We can't keep this list in the per-process info, since
00023    one process may open a file, and outlive a process which
00024    wanted to unlink the file - and the data would go away.
00025 
00026    Perhaps the FILE_FLAG_DELETE_ON_CLOSE would be ok,
00027    but brief experimentation didn't get too far.
00028 */
00029 
00030 #define MAX_DELQUEUES_PENDING 100
00031 
00032 class delqueue_list
00033 {
00034   char name[MAX_DELQUEUES_PENDING][MAX_PATH];
00035   char inuse[MAX_DELQUEUES_PENDING];
00036   int empty;
00037 
00038 public:
00039   void init ();
00040   void queue_file (const char *dosname);
00041   void process_queue ();
00042 };
00043 
00044 /******** Process Table ********/
00045 
00046 /* Signal constants (have to define them here, unfortunately) */
00047 
00048 enum
00049 {
00050   __SIGFLUSH        = -2,
00051   __SIGSTRACE       = -1,
00052   __SIGCHILDSTOPPED =  0,
00053   __SIGOFFSET       =  3
00054 };
00055 
00056 class pinfo
00057 {
00058  public:
00059 
00060   /* If hProcess is set, it's because it came from a
00061      CreateProcess call.  This means it's process relative
00062      to the thing which created the process.  That's ok because
00063      we only use this handle from the parent. */
00064   HANDLE hProcess;
00065 
00066   HANDLE parent_alive;
00067 
00068   /* dwProcessId contains the processid used for sending signals.  It
00069    * will be reset in a child process when it is capable of receiving
00070    * signals.
00071    */
00072   DWORD dwProcessId;
00073 
00074   /* User information.
00075      The information is derived from the GetUserName system call,
00076      with the name looked up in /etc/passwd and assigned a default value
00077      if not found.  This data resides in the shared data area (allowing
00078      tasks to store whatever they want here) so it's for informational
00079      purposes only. */
00080   uid_t uid;        /* User ID */
00081   gid_t gid;        /* Group ID */
00082   pid_t pgid;       /* Process group ID */
00083   pid_t sid;        /* Session ID */
00084   int ctty;         /* Control tty */
00085   mode_t umask;
00086   char username[MAX_USER_NAME]; /* user's name */
00087 
00088   /* Extendend user information.
00089      The information is derived from the internal_getlogin call
00090      when on a NT system. */
00091   PSID psid;        /* user's SID */
00092   char sidbuf[MAX_SID_LEN];  /* buffer for user's SID */
00093   char logsrv[MAX_HOST_NAME]; /* Logon server, may be FQDN */
00094   char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */
00095 
00096   /* token is needed if sexec should be called. It can be set by a call
00097      to `set_impersonation_token()'. */
00098   HANDLE token;
00099   BOOL impersonated;
00100   uid_t orig_uid;        /* Remains intact also after impersonation */
00101   uid_t orig_gid;        /* Ditto */
00102   uid_t real_uid;        /* Remains intact on seteuid, replaced by setuid */
00103   gid_t real_gid;        /* Ditto */
00104 
00105   /* Filled when chroot() is called by the process or one of it's parents.
00106      Saved without trailing backslash. */
00107   char root[MAX_PATH+1];
00108   size_t rootlen;
00109 
00110   /* Non-zero if process was stopped by a signal. */
00111   char stopsig;
00112 
00113   struct sigaction& getsig (int);
00114   void copysigs (pinfo *);
00115   sigset_t& getsigmask ();
00116   void setsigmask (sigset_t);
00117   LONG* getsigtodo (int);
00118   HANDLE getthread2signal ();
00119   void setthread2signal (void *);
00120 
00121   /* Resources used by process. */
00122   long start_time;
00123   struct rusage rusage_self;
00124   struct rusage rusage_children;
00125 
00126 private:
00127   struct sigaction sigs[NSIG];
00128   sigset_t sig_mask;            /* one set for everything to ignore. */
00129   LONG _sigtodo[NSIG + __SIGOFFSET];
00130 #ifdef _MT_SAFE
00131   ThreadItem* thread2signal;  // NULL means means thread any other means a pthread
00132 #endif
00133 
00134 public:
00135 
00136   /* Pointer to mmap'ed areas for this process.  Set up by fork. */
00137   void *mmap_ptr;
00138 
00139   /* Used to spawn a child for fork(), among other things. */
00140   char progname[MAX_PATH];
00141 
00142   #define PINFO_ZERO ((((pinfo *) NULL)->progname + 1) - ((char *) NULL))
00143 
00144   /* Anything below this point is not zeroed automatically by allocate_pid */
00145 
00146   /* The pid stays the same, while the hProcess moves due to execs. */
00147   pid_t pid;
00148   /* Parent process id.  */
00149   pid_t ppid;
00150 
00151   /* Various flags indicating the state of the process.  See PID_
00152      constants below. */
00153   DWORD process_state;
00154 
00155   void record_death (int lock = 1);
00156 };
00157 
00158 #define ISSTATE(p, f)   (!!((p)->process_state & f))
00159 #define NOTSTATE(p, f)  (!((p)->process_state & f))
00160 
00161 #define PSIZE 128
00162 
00163 class pinfo_list
00164 {
00165  public:
00166   int next_pid;
00167   pinfo vec[PSIZE];
00168   char lock_info[MAX_PATH + 1];
00169   pinfo * operator[] (pid_t x);
00170   int size (void) { return PSIZE; }
00171   pinfo *allocate_pid (void);
00172   void init (void);
00173 };
00174 
00175 void __stdcall pinfo_init (PBYTE);
00176 pinfo *__stdcall procinfo (int n);
00177 
00178 enum
00179 {
00180   PROC_MAGIC = 0xaf08f000,
00181   PROC_FORK = PROC_MAGIC + 1,
00182   PROC_EXEC = PROC_MAGIC + 2,
00183   PROC_SPAWN = PROC_MAGIC + 3,
00184   PROC_FORK1 = PROC_MAGIC + 4   // Newer versions provide stack
00185                                 // location information
00186 };
00187 
00188 #define PROC_MAGIC_MASK 0xff00f000
00189 #define PROC_MAGIC_GENERIC 0xaf00f000
00190 #define PROC_MAGIC_VER_MASK 0x0ff0000
00191 
00192 #define EXEC_MAGIC_SIZE sizeof(child_info)
00193 class child_info
00194 {
00195 public:
00196   DWORD zero[1];        // must be zeroed
00197   DWORD cb;             // size of this record
00198   DWORD type;           // type of record
00199   int cygpid;           // cygwin pid of child process
00200   HANDLE subproc_ready; // used for synchronization with parent
00201   HANDLE shared_h;
00202   HANDLE console_h;
00203   HANDLE parent_alive;  // handle of thread used to track children
00204 };
00205 
00206 class child_info_fork: public child_info
00207 {
00208 public:
00209   HANDLE forker_finished;// for synchronization with child
00210   DWORD stacksize;      // size of parent stack
00211   void *heaptop;
00212   void *heapbase;
00213   void *heapptr;
00214   jmp_buf jmp;          // where child will jump to
00215   void *stacktop;       // location of top of parent stack
00216   void *stackbottom;    // location of bottom of parent stack
00217 };
00218 
00219 void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
00220 
00221 extern child_info_fork *child_proc_info;
00222 
00223 /* Process info for this process */
00224 extern pinfo *myself;
00225 
00226 /* non-NULL if this process is a child of a cygwin process */
00227 extern HANDLE parent_alive;
00228 
00229 /******** Registry Access ********/
00230 
00231 class reg_key
00232 {
00233 private:
00234 
00235   HKEY key;
00236   LONG key_is_invalid;
00237 
00238 public:
00239 
00240   reg_key (HKEY toplev, REGSAM access, ...);
00241   reg_key (REGSAM access, ...);
00242   reg_key (REGSAM access = KEY_ALL_ACCESS);
00243 
00244   void *operator new (size_t, void *p) {return p;}
00245   void build_reg (HKEY key, REGSAM access, va_list av);
00246 
00247   int error () {return key == (HKEY) INVALID_HANDLE_VALUE;}
00248 
00249   int kill (const char *child);
00250   int killvalue (const char *name);
00251 
00252   HKEY get_key ();
00253   int get_int (const char *,int def);
00254   int get_string (const char *, char *buf, size_t len, const char *def);
00255   int set_string (const char *,const char *);
00256   int set_int (const char *, int val);
00257 
00258   ~reg_key ();
00259 };
00260 
00261 /* Evaluates path to the directory of the local user registry hive */
00262 char *__stdcall get_registry_hive_path (const PSID psid, char *path);
00263 void __stdcall load_registry_hive (PSID psid);
00264 
00265 /******** Mount Table ********/
00266 
00267 /* Mount table entry */
00268 
00269 class mount_item
00270 {
00271 public:
00272   /* FIXME: Nasty static allocation.  Need to have a heap in the shared
00273      area [with the user being able to configure at runtime the max size].  */
00274 
00275   /* Win32-style mounted partition source ("C:\foo\bar").
00276      native_path[0] == 0 for unused entries.  */
00277   char native_path[MAX_PATH];
00278   int native_pathlen;
00279 
00280   /* POSIX-style mount point ("/foo/bar") */
00281   char posix_path[MAX_PATH];
00282   int posix_pathlen;
00283 
00284   unsigned flags;
00285 
00286   void init (const char *dev, const char *path, unsigned flags);
00287 
00288   struct mntent *getmntent ();
00289 };
00290 
00291 /* Warning: Decreasing this value will cause cygwin.dll to ignore existing
00292    higher numbered registry entries.  Don't change this number willy-nilly.
00293    What we need is to have a more dynamic allocation scheme, but the current
00294    scheme should be satisfactory for a long while yet.  */
00295 #define MAX_MOUNTS 30
00296 
00297 class mount_info
00298 {
00299   int posix_sorted[MAX_MOUNTS];
00300   int native_sorted[MAX_MOUNTS];
00301 public:
00302   int nmounts;
00303   mount_item mount[MAX_MOUNTS];
00304 
00305   /* Strings used by getmntent(). */
00306   char mnt_type[20];
00307   char mnt_opts[20];
00308   char mnt_fsname[MAX_PATH];
00309   char mnt_dir[MAX_PATH];
00310 
00311   /* cygdrive_prefix is used as the root of the path automatically
00312      prepended to a path when the path has no associated mount.
00313      cygdrive_flags are the default flags for the cygdrives. */
00314   char cygdrive[MAX_PATH];
00315   size_t cygdrive_len;
00316   unsigned cygdrive_flags;
00317 
00318   /* Increment when setting up a reg_key if mounts area had to be
00319      created so we know when we need to import old mount tables. */
00320   int had_to_create_mount_areas;
00321 
00322   void init ();
00323   int add_item (const char *dev, const char *path, unsigned flags, int reg_p);
00324   int del_item (const char *path, unsigned flags, int reg_p);
00325 
00326   void from_registry ();
00327   int add_reg_mount (const char * native_path, const char * posix_path,
00328                       unsigned mountflags);
00329   int del_reg_mount (const char * posix_path, unsigned mountflags);
00330 
00331   unsigned set_flags_from_win32_path (const char *path);
00332   int conv_to_win32_path (const char *src_path, char *win32_path,
00333                           char *full_win32_path, DWORD &devn, int &unit,
00334                           unsigned *flags = NULL);
00335   int conv_to_posix_path (const char *src_path, char *posix_path,
00336                           int keep_rel_p);
00337   struct mntent *getmntent (int x);
00338 
00339   int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
00340   int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags);
00341   int get_cygdrive_prefixes (char *user, char *system);
00342 
00343   void import_v1_mounts ();
00344 
00345 private:
00346 
00347   void sort ();
00348   void read_mounts (reg_key& r);
00349   void read_v1_mounts (reg_key r, unsigned which);
00350   void mount_slash ();
00351   void to_registry ();
00352 
00353   int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
00354   void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
00355   void slash_drive_to_win32_path (const char *path, char *buf, int trailing_slash_p);
00356   void read_cygdrive_info_from_registry ();
00357 };
00358 
00359 /******** TTY Support ********/
00360 
00361 /* tty tables */
00362 
00363 #define INP_BUFFER_SIZE 256
00364 #define OUT_BUFFER_SIZE 256
00365 #define NTTYS           128
00366 #define TTY_CONSOLE     0x40000000
00367 #define tty_attached(p) ((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
00368 
00369 /* Input/Output/ioctl events */
00370 
00371 #define OUTPUT_DONE_EVENT       "cygtty%d.output.done"
00372 #define IOCTL_REQUEST_EVENT     "cygtty%d.ioctl.request"
00373 #define IOCTL_DONE_EVENT        "cygtty%d.ioctl.done"
00374 #define RESTART_OUTPUT_EVENT    "cygtty%d.output.restart"
00375 #define OUTPUT_MUTEX            "cygtty%d.output.mutex"
00376 #define TTY_SLAVE_ALIVE         "cygtty%x.slave_alive"
00377 #define TTY_MASTER_ALIVE        "cygtty%x.master_alive"
00378 
00379 #include <sys/termios.h>
00380 
00381 enum
00382 {
00383   TTY_INITIALIZED = 1,          /* Set if tty is initialized */
00384   TTY_RSTCONS = 2               /* Set if console needs to be set to "non-cooked" */
00385 };
00386 
00387 #define TTYISSETF(x)    __ISSETF (tc, x, TTY)
00388 #define TTYSETF(x)      __SETF (tc, x, TTY)
00389 #define TTYCLEARF(x)    __CLEARF (tc, x, TTY)
00390 #define TTYCONDSETF(n, x) __CONDSETF(n, tc, x, TTY)
00391 
00392 #ifndef MIN_CTRL_C_SLOP
00393 #define MIN_CTRL_C_SLOP 50
00394 #endif
00395 
00396 class tty_min
00397 {
00398   pid_t sid;    /* Session ID of tty */
00399 public:
00400   DWORD status;
00401   pid_t pgid;
00402   int OutputStopped;
00403   int ntty;
00404   DWORD last_ctrl_c;    // tick count of last ctrl-c
00405 
00406   tty_min (int t = -1, pid_t s = -1) : sid (s), ntty (t) {}
00407   void setntty (int n) {ntty = n;}
00408   pid_t getpgid () {return pgid;}
00409   void setpgid (int pid) {pgid = pid;}
00410   int getsid () {return sid;}
00411   void setsid (pid_t tsid) {sid = tsid;}
00412   struct termios ti;
00413   struct winsize winsize;
00414 
00415   /* ioctl requests buffer */
00416   int cmd;
00417   union
00418   {
00419     struct termios termios;
00420     struct winsize winsize;
00421     int value;
00422     pid_t pid;
00423   } arg;
00424   /* XXX_retval variables holds master's completion codes. Error are stored as
00425    * -ERRNO
00426    */
00427   int ioctl_retval;
00428 
00429   int write_retval;
00430 };
00431 
00432 class fhandler_pty_master;
00433 
00434 class tty: public tty_min
00435 {
00436   HANDLE get_event (const char *fmt, BOOL inherit);
00437 public:
00438   HWND  hwnd;   /* Console window handle tty belongs to */
00439 
00440   DWORD master_pid;     /* Win32 PID of tty master process */
00441 
00442   HANDLE from_master, to_slave;
00443   HANDLE from_slave, to_master;
00444 
00445   int read_retval;
00446   BOOL was_opened;      /* True if opened at least once. */
00447 
00448   void init ();
00449   HANDLE create_inuse (const char *);
00450   BOOL common_init (fhandler_pty_master *);
00451   BOOL alive (const char *fmt);
00452   BOOL slave_alive ();
00453   BOOL master_alive ();
00454   HWND gethwnd () {return hwnd;}
00455   void sethwnd (HWND wnd) {hwnd = wnd;}
00456   int make_pipes (fhandler_pty_master *ptym);
00457   HANDLE open_output_mutex (BOOL inherit = FALSE)
00458   {
00459     char buf[80];
00460     __small_sprintf (buf, OUTPUT_MUTEX, ntty);
00461     return OpenMutex (MUTEX_ALL_ACCESS, inherit, buf);
00462   }
00463   BOOL exists ()
00464   {
00465     HANDLE h = open_output_mutex ();
00466     if (h)
00467       {
00468         CloseHandle (h);
00469         return 1;
00470       }
00471     return slave_alive ();
00472   }
00473 };
00474 
00475 class tty_list
00476 {
00477   tty ttys[NTTYS];
00478 
00479 public:
00480   tty * operator [](int n) {return ttys + n;}
00481   int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */
00482   int connect_tty (int);
00483   void terminate ();
00484   void init ();
00485   tty_min *get_tty (int n);
00486 };
00487 
00488 void __stdcall tty_init ();
00489 void __stdcall tty_terminate ();
00490 int __stdcall attach_tty (int);
00491 void __stdcall create_tty_master (int);
00492 extern "C" int ttyslot (void);
00493 
00494 /******** Shared Info ********/
00495 /* Data accessible to all tasks */
00496 
00497 class shared_info
00498 {
00499   DWORD inited;
00500 
00501 public:
00502   pinfo_list p;
00503 
00504   /* FIXME: Doesn't work if more than one user on system. */
00505   mount_info mount;
00506 
00507   int heap_chunk_in_mb;
00508   unsigned heap_chunk_size (void);
00509 
00510   tty_list tty;
00511   delqueue_list delqueue;
00512   void initialize (void);
00513 };
00514 
00515 /* Various types of security attributes for use in Create* functions. */
00516 extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih;
00517 extern SECURITY_ATTRIBUTES *__stdcall sec_user (PVOID sa_buf, PSID sid2 = NULL, BOOL inherit = TRUE);
00518 extern SECURITY_ATTRIBUTES *__stdcall sec_user_nih (PVOID sa_buf, PSID sid2 = NULL);
00519 
00520 extern shared_info *cygwin_shared;
00521 extern HANDLE cygwin_shared_h;
00522 extern HANDLE console_shared_h;
00523 extern int __stdcall set_console_state_for_spawn ();
00524 
00525 void __stdcall shared_init (void);
00526 void __stdcall shared_terminate (void);
00527 
00528 char *__stdcall shared_name (const char *, int);
00529 void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);
00530 
00531 extern "C" {
00532 /* This is for programs that want to access the shared data. */
00533 class shared_info *cygwin_getshared (void);
00534 
00535 struct cygwin_version_info
00536 {
00537   unsigned short api_major;
00538   unsigned short api_minor;
00539   unsigned short dll_major;
00540   unsigned short dll_minor;
00541   unsigned short shared_data;
00542   unsigned short mount_registry;
00543   const char *dll_build_date;
00544   char shared_id[sizeof (CYGWIN_VERSION_DLL_IDENTIFIER) + 64];
00545 };
00546 }
00547 
00548 extern cygwin_version_info cygwin_version;
00549 extern const char *cygwin_version_strings;

Generated on Sun Mar 12 23:56:32 2006 for ScriptBasic by  doxygen 1.4.6-NO