summaryrefslogtreecommitdiff
path: root/winsup/cygwin/shared.h
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/shared.h')
-rw-r--r--winsup/cygwin/shared.h552
1 files changed, 552 insertions, 0 deletions
diff --git a/winsup/cygwin/shared.h b/winsup/cygwin/shared.h
new file mode 100644
index 00000000000..036ca8815af
--- /dev/null
+++ b/winsup/cygwin/shared.h
@@ -0,0 +1,552 @@
+/* shared.h: shared info for cygwin
+
+ Copyright 1998, 1999, 2000 Cygnus Solutions.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+/******** Functions declarations for use in methods below ********/
+
+/* Printf type functions */
+extern "C" void __api_fatal (const char *, ...) __attribute__ ((noreturn));
+extern "C" int __small_sprintf (char *dst, const char *fmt, ...);
+extern "C" int __small_vsprintf (char *dst, const char *fmt, va_list ap);
+extern "C" int __small_sprintf (char *dst, const char *fmt, ...);
+
+/******** Deletion Queue Class ********/
+
+/* First pass at a file deletion queue structure.
+
+ We can't keep this list in the per-process info, since
+ one process may open a file, and outlive a process which
+ wanted to unlink the file - and the data would go away.
+
+ Perhaps the FILE_FLAG_DELETE_ON_CLOSE would be ok,
+ but brief experimentation didn't get too far.
+*/
+
+#define MAX_DELQUEUES_PENDING 100
+
+class delqueue_list
+{
+ char name[MAX_DELQUEUES_PENDING][MAX_PATH];
+ char inuse[MAX_DELQUEUES_PENDING];
+ int empty;
+
+public:
+ void init ();
+ void queue_file (const char *dosname);
+ void process_queue ();
+};
+
+/******** Process Table ********/
+
+/* Signal constants (have to define them here, unfortunately) */
+
+enum
+{
+ __SIGFLUSH = -2,
+ __SIGSTRACE = -1,
+ __SIGCHILDSTOPPED = 0,
+ __SIGOFFSET = 3
+};
+
+class pinfo
+{
+ public:
+
+ /* If hProcess is set, it's because it came from a
+ CreateProcess call. This means it's process relative
+ to the thing which created the process. That's ok because
+ we only use this handle from the parent. */
+ HANDLE hProcess;
+
+ HANDLE parent_alive;
+
+ /* dwProcessId contains the processid used for sending signals. It
+ * will be reset in a child process when it is capable of receiving
+ * signals.
+ */
+ DWORD dwProcessId;
+
+ /* User information.
+ The information is derived from the GetUserName system call,
+ with the name looked up in /etc/passwd and assigned a default value
+ if not found. This data resides in the shared data area (allowing
+ tasks to store whatever they want here) so it's for informational
+ purposes only. */
+ uid_t uid; /* User ID */
+ gid_t gid; /* Group ID */
+ pid_t pgid; /* Process group ID */
+ pid_t sid; /* Session ID */
+ int ctty; /* Control tty */
+ mode_t umask;
+ char username[MAX_USER_NAME]; /* user's name */
+
+ /* Extendend user information.
+ The information is derived from the internal_getlogin call
+ when on a NT system. */
+ PSID psid; /* user's SID */
+ char sidbuf[40]; /* buffer for user's SID */
+ char logsrv[256]; /* Logon server, may be fully qualified DNS name */
+ char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */
+
+ /* Non-zero if process was stopped by a signal. */
+ char stopsig;
+
+ struct sigaction& getsig (int);
+ void copysigs (pinfo *);
+ sigset_t& getsigmask ();
+ void setsigmask (sigset_t);
+ LONG* getsigtodo (int);
+ HANDLE getthread2signal ();
+ void setthread2signal (void *);
+
+ /* Resources used by process. */
+ long start_time;
+ struct rusage rusage_self;
+ struct rusage rusage_children;
+
+private:
+ struct sigaction sigs[NSIG];
+ sigset_t sig_mask; /* one set for everything to ignore. */
+ LONG _sigtodo[NSIG + __SIGOFFSET];
+#ifdef _MT_SAFE
+ ThreadItem* thread2signal; // NULL means means thread any other means a pthread
+#endif
+
+public:
+
+ /* Pointer to mmap'ed areas for this process. Set up by fork. */
+ void *mmap_ptr;
+
+ /* Used to spawn a child for fork(), among other things. */
+ char progname[MAX_PATH];
+
+ #define PINFO_ZERO ((((pinfo *) NULL)->progname + 1) - ((char *) NULL))
+
+ /* Anything below this point is not zeroed automatically by allocate_pid */
+
+ /* The pid stays the same, while the hProcess moves due to execs. */
+ pid_t pid;
+ /* Parent process id. */
+ pid_t ppid;
+
+ /* Various flags indicating the state of the process. See PID_
+ constants below. */
+ DWORD process_state;
+
+ void record_death (int lock = 1);
+};
+
+#define ISSTATE(p, f) (!!((p)->process_state & f))
+#define NOTSTATE(p, f) (!((p)->process_state & f))
+
+/* Flags associated with process_state */
+enum
+{
+ PID_NOT_IN_USE = 0x0000, // Free entry.
+ PID_IN_USE = 0x0001, // Entry in use.
+ PID_ZOMBIE = 0x0002, // Child exited: no parent wait.
+ PID_STOPPED = 0x0004, // Waiting for SIGCONT.
+ PID_TTYIN = 0x0008, // Waiting for terminal input.
+ PID_TTYOU = 0x0010, // Waiting for terminal output.
+ PID_ORPHANED = 0x0020, // Member of an orphaned process group.
+ PID_ACTIVE = 0x0040, // Pid accepts signals.
+ PID_CYGPARENT = 0x0080, // Set if parent was a cygwin app.
+ PID_SPLIT_HEAP = 0x0100, // Set if the heap has been split,
+ // which means we can't fork again.
+ PID_CLEAR = 0x0200, // Flag that pid should be cleared from parent's
+ // wait list
+ PID_SOCKETS_USED = 0x0400, // Set if process uses Winsock.
+ PID_INITIALIZING = 0x0800, // Set until ready to receive signals.
+ PID_USETTY = 0x1000, // Setting this enables or disables cygwin's
+ // tty support. This is inherited by
+ // all execed or forked processes.
+ PID_REPARENT = 0x2000 // child has execed
+};
+
+#define PSIZE 128
+
+class pinfo_list
+{
+ public:
+ int next_pid;
+ pinfo vec[PSIZE];
+ char lock_info[MAX_PATH + 1];
+ pinfo * operator[] (pid_t x);
+ int size (void) { return PSIZE; }
+ pinfo *allocate_pid (void);
+ void init (void);
+};
+
+void __stdcall pinfo_init (PBYTE);
+pinfo *__stdcall procinfo (int n);
+
+enum
+{
+ PROC_MAGIC = 0xaf04f000,
+ PROC_FORK = PROC_MAGIC + 1,
+ PROC_EXEC = PROC_MAGIC + 2,
+ PROC_SPAWN = PROC_MAGIC + 3,
+ PROC_FORK1 = PROC_MAGIC + 4 // Newer versions provide stack
+ // location information
+};
+
+#define PROC_MAGIC_MASK 0xff00f000
+#define PROC_MAGIC_GENERIC 0xaf00f000
+#define PROC_MAGIC_VER_MASK 0x0ff0000
+
+#define EXEC_MAGIC_SIZE sizeof(child_info)
+class child_info
+{
+public:
+ DWORD zero[1]; // must be zeroed
+ DWORD cb; // size of this record
+ DWORD type; // type of record
+ int cygpid; // cygwin pid of child process
+ HANDLE subproc_ready; // used for synchronization with parent
+ HANDLE shared_h;
+ HANDLE console_h;
+ HANDLE parent_alive; // handle of thread used to track children
+};
+
+class child_info_fork: public child_info
+{
+public:
+ HANDLE forker_finished;// for synchronization with child
+ DWORD stacksize; // size of parent stack
+ void *heaptop;
+ void *heapbase;
+ void *heapptr;
+ jmp_buf jmp; // where child will jump to
+ void *stacktop; // location of top of parent stack
+ void *stackbottom; // location of bottom of parent stack
+};
+
+void __stdcall init_child_info (DWORD, child_info *, int, HANDLE);
+
+extern child_info_fork *child_proc_info;
+
+/* Process info for this process */
+extern pinfo *myself;
+
+/* non-NULL if this process is a child of a cygwin process */
+extern HANDLE parent_alive;
+
+/******** Registry Access ********/
+
+class reg_key
+{
+private:
+
+ HKEY key;
+
+public:
+
+ reg_key (HKEY toplev, REGSAM access, ...);
+ reg_key (REGSAM access, ...);
+ reg_key (REGSAM access = KEY_ALL_ACCESS);
+
+ void *operator new (size_t, void *p) {return p;}
+ void build_reg (HKEY key, REGSAM access, va_list av);
+
+ int error () {return key == (HKEY) INVALID_HANDLE_VALUE;}
+
+ int kill (const char *child);
+
+ HKEY get_key ();
+ int get_int (const char *,int def);
+ int get_string (const char *, char *buf, size_t len, const char *def);
+ int set_string (const char *,const char *);
+ int set_int (const char *, int val);
+ int setone_string (const char *src, const char *name);
+
+ ~reg_key ();
+};
+
+/******** Mount Table ********/
+
+/* Mount table entry */
+
+class mount_item
+{
+public:
+ /* FIXME: Nasty static allocation. Need to have a heap in the shared
+ area [with the user being able to configure at runtime the max size]. */
+
+ /* Win32-style mounted partition source ("C:\foo\bar").
+ native_path[0] == 0 for unused entries. */
+ char native_path[MAX_PATH];
+ int native_pathlen;
+
+ /* POSIX-style mount point ("/foo/bar") */
+ char posix_path[MAX_PATH];
+ int posix_pathlen;
+
+ unsigned flags;
+
+ void init (const char *dev, const char *path, unsigned flags);
+
+ struct mntent *getmntent ();
+};
+
+/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
+ higher numbered registry entries. Don't change this number willy-nilly.
+ What we need is to have a more dynamic allocation scheme, but the current
+ scheme should be satisfactory for a long while yet. */
+#define MAX_MOUNTS 30
+
+class mount_info
+{
+ int posix_sorted[MAX_MOUNTS];
+ int native_sorted[MAX_MOUNTS];
+public:
+ int nmounts;
+ mount_item mount[MAX_MOUNTS];
+
+ /* Strings used by getmntent(). */
+ char mnt_type[20];
+ char mnt_opts[20];
+ char mnt_fsname[MAX_PATH];
+ char mnt_dir[MAX_PATH];
+
+ /* cygdrive_prefix is used as the root of the path automatically
+ prepended to a path when the path has no associated mount.
+ cygdrive_flags are the default flags for the cygdrives. */
+ char cygdrive[MAX_PATH];
+ size_t cygdrive_len;
+ unsigned cygdrive_flags;
+
+ /* Increment when setting up a reg_key if mounts area had to be
+ created so we know when we need to import old mount tables. */
+ int had_to_create_mount_areas;
+
+ void init ();
+ int add_item (const char *dev, const char *path, unsigned flags);
+ int del_item (const char *path, unsigned flags);
+
+ void from_registry ();
+ void from_v1_registry ();
+ int add_reg_mount (const char * native_path, const char * posix_path,
+ unsigned mountflags);
+ int del_reg_mount (const char * posix_path, unsigned mountflags);
+
+ unsigned set_flags_from_win32_path (const char *path);
+ int conv_to_win32_path (const char *src_path, char *win32_path,
+ char *full_win32_path, DWORD &devn, int &unit,
+ unsigned *flags = NULL);
+ int conv_to_posix_path (const char *src_path, char *posix_path,
+ int keep_rel_p);
+ struct mntent *getmntent (int x);
+
+ int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
+
+ void import_v1_mounts ();
+
+private:
+
+ void sort ();
+ void read_mounts (reg_key& r);
+ void read_v1_mounts (reg_key r, unsigned which);
+ void mount_slash ();
+ void to_registry ();
+
+ int cygdrive_win32_path (const char *src, char *dst, int trailing_slash_p);
+ void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
+ void slash_drive_to_win32_path (const char *path, char *buf, int trailing_slash_p);
+ void read_cygdrive_info_from_registry ();
+};
+
+/******** TTY Support ********/
+
+/* tty tables */
+
+#define INP_BUFFER_SIZE 256
+#define OUT_BUFFER_SIZE 256
+#define NTTYS 128
+#define TTY_CONSOLE 0x40000000
+#define tty_attached(p) ((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
+
+/* Input/Output/ioctl events */
+
+#define OUTPUT_DONE_EVENT "cygtty%d.output.done"
+#define IOCTL_REQUEST_EVENT "cygtty%d.ioctl.request"
+#define IOCTL_DONE_EVENT "cygtty%d.ioctl.done"
+#define RESTART_OUTPUT_EVENT "cygtty%d.output.restart"
+#define OUTPUT_MUTEX "cygtty%d.output.mutex"
+#define TTY_SLAVE_ALIVE "cygtty%x.slave_alive"
+#define TTY_MASTER_ALIVE "cygtty%x.master_alive"
+
+#include <sys/termios.h>
+
+enum
+{
+ TTY_INITIALIZED = 1, /* Set if tty is initialized */
+ TTY_RSTCONS = 2 /* Set if console needs to be set to "non-cooked" */
+};
+
+#define TTYISSETF(x) __ISSETF (tc, x, TTY)
+#define TTYSETF(x) __SETF (tc, x, TTY)
+#define TTYCLEARF(x) __CLEARF (tc, x, TTY)
+#define TTYCONDSETF(n, x) __CONDSETF(n, tc, x, TTY)
+
+#ifndef MIN_CTRL_C_SLOP
+#define MIN_CTRL_C_SLOP 50
+#endif
+
+class tty_min
+{
+ pid_t sid; /* Session ID of tty */
+public:
+ DWORD status;
+ pid_t pgid;
+ int OutputStopped;
+ int ntty;
+ DWORD last_ctrl_c; // tick count of last ctrl-c
+
+ tty_min (int t = -1, pid_t s = -1) : sid (s), ntty (t) {}
+ void setntty (int n) {ntty = n;}
+ pid_t getpgid () {return pgid;}
+ void setpgid (int pid) {pgid = pid;}
+ int getsid () {return sid;}
+ void setsid (pid_t tsid) {sid = tsid;}
+ struct termios ti;
+ struct winsize winsize;
+
+ /* ioctl requests buffer */
+ int cmd;
+ union
+ {
+ struct termios termios;
+ struct winsize winsize;
+ int value;
+ pid_t pid;
+ } arg;
+ /* XXX_retval variables holds master's completion codes. Error are stored as
+ * -ERRNO
+ */
+ int ioctl_retval;
+
+ int write_retval;
+};
+
+class fhandler_pty_master;
+
+class tty: public tty_min
+{
+ HANDLE get_event (const char *fmt, BOOL inherit);
+public:
+ HWND hwnd; /* Console window handle tty belongs to */
+
+ DWORD master_pid; /* Win32 PID of tty master process */
+
+ HANDLE from_master, to_slave;
+ HANDLE from_slave, to_master;
+
+ int read_retval;
+ BOOL was_opened; /* True if opened at least once. */
+
+ void init ();
+ HANDLE create_inuse (const char *);
+ BOOL common_init (fhandler_pty_master *);
+ BOOL alive (const char *fmt);
+ BOOL slave_alive ();
+ BOOL master_alive ();
+ HWND gethwnd () {return hwnd;}
+ void sethwnd (HWND wnd) {hwnd = wnd;}
+ int make_pipes (fhandler_pty_master *ptym);
+ HANDLE open_output_mutex (BOOL inherit = FALSE)
+ {
+ char buf[80];
+ __small_sprintf (buf, OUTPUT_MUTEX, ntty);
+ return OpenMutex (MUTEX_ALL_ACCESS, inherit, buf);
+ }
+ BOOL exists ()
+ {
+ HANDLE h = open_output_mutex ();
+ if (h)
+ {
+ CloseHandle (h);
+ return 1;
+ }
+ return slave_alive ();
+ }
+};
+
+class tty_list
+{
+ tty ttys[NTTYS];
+
+public:
+ tty * operator [](int n) {return ttys + n;}
+ int allocate_tty (int n); /* n non zero if allocate a tty, pty otherwise */
+ int connect_tty (int);
+ void terminate ();
+ void init ();
+ tty_min *get_tty (int n);
+};
+
+void __stdcall tty_init ();
+void __stdcall tty_terminate ();
+int __stdcall attach_tty (int);
+void __stdcall create_tty_master (int);
+extern "C" int ttyslot (void);
+
+/******** Shared Info ********/
+/* Data accessible to all tasks */
+
+class shared_info
+{
+ DWORD inited;
+
+public:
+ pinfo_list p;
+
+ /* FIXME: Doesn't work if more than one user on system. */
+ mount_info mount;
+
+ int heap_chunk_in_mb;
+ unsigned heap_chunk_size (void);
+
+ tty_list tty;
+ delqueue_list delqueue;
+ void initialize (void);
+};
+
+/* Various types of security attributes for use in Create* functions. */
+extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih;
+extern SECURITY_ATTRIBUTES *__stdcall sec_user (PVOID sa_buf, PSID sid2 = NULL, BOOL inherit = TRUE);
+extern SECURITY_ATTRIBUTES *__stdcall sec_user_nih (PVOID sa_buf, PSID sid2 = NULL);
+
+extern shared_info *cygwin_shared;
+extern HANDLE cygwin_shared_h;
+extern HANDLE console_shared_h;
+extern int __stdcall set_console_state_for_spawn ();
+
+void __stdcall shared_init (void);
+void __stdcall shared_terminate (void);
+
+/* This is for programs that want to access the shared data. */
+extern "C" class shared_info *cygwin_getshared (void);
+
+char *__stdcall shared_name (const char *, int);
+void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);
+
+struct cygwin_version_info
+{
+ unsigned short api_major;
+ unsigned short api_minor;
+ unsigned short dll_major;
+ unsigned short dll_minor;
+ unsigned short shared_data;
+ unsigned short mount_registry;
+ const char *dll_build_date;
+ const char shared_id[sizeof (CYGWIN_VERSION_DLL_IDENTIFIER) + 64];
+};
+
+extern cygwin_version_info cygwin_version;
+extern const char *cygwin_version_strings;