Welcome to mirror list, hosted at ThFree Co, Russian Federation.

shared.h « cygwin « winsup - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: fa14492cb679901db60847836b9ae6eeb0b4cc48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
/* 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);

/******** 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[MAX_SID_LEN];  /* buffer for user's SID */
  char logsrv[MAX_HOST_NAME]; /* Logon server, may be FQDN */
  char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */

  /* token is needed if sexec should be called. It can be set by a call
     to `set_impersonation_token()'. */
  HANDLE token;
  BOOL impersonated;
  uid_t orig_uid;        /* Remains intact also after impersonation */
  uid_t orig_gid;        /* Ditto */
  uid_t real_uid;        /* Remains intact on seteuid, replaced by setuid */
  gid_t real_gid;	 /* Ditto */

  /* Filled when chroot() is called by the process or one of it's parents.
     Saved without trailing backslash. */
  char root[MAX_PATH+1];
  size_t rootlen;

  /* 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))

#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 = 0xaf08f000,
  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;
  LONG key_is_invalid;

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);
  int killvalue (const char *name);

  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);

  ~reg_key ();
};

/* Evaluates path to the directory of the local user registry hive */
char *__stdcall get_registry_hive_path (const PSID psid, char *path);
void __stdcall load_registry_hive (PSID psid);

/******** 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 reg_p);
  int del_item (const char *path, unsigned flags, int reg_p);

  void from_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);
  int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags);
  int get_cygdrive_prefixes (char *user, char *system);

  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);

char *__stdcall shared_name (const char *, int);
void *__stdcall open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr);

extern "C" {
/* This is for programs that want to access the shared data. */
class shared_info *cygwin_getshared (void);

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;
  char shared_id[sizeof (CYGWIN_VERSION_DLL_IDENTIFIER) + 64];
};
}

extern cygwin_version_info cygwin_version;
extern const char *cygwin_version_strings;