|
37 | 37 | * |
38 | 38 | * |
39 | 39 | * IDENTIFICATION |
40 | | - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.357 2004/01/09 23:27:20 momjian Exp $ |
| 40 | + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.358 2004/01/11 03:49:31 momjian Exp $ |
41 | 41 | * |
42 | 42 | * NOTES |
43 | 43 | * |
@@ -297,6 +297,10 @@ postmaster_error(const char *fmt,...) |
297 | 297 | __attribute__((format(printf,1,2))); |
298 | 298 |
|
299 | 299 | #ifdefEXEC_BACKEND |
| 300 | +#ifdefWIN32 |
| 301 | +pid_twin32_forkexec(constchar*path,char*argv[]); |
| 302 | +#endif |
| 303 | + |
300 | 304 | staticpid_tBackend_forkexec(Port*port); |
301 | 305 |
|
302 | 306 | staticunsigned longtmpBackendFileNum=0; |
@@ -923,7 +927,12 @@ pmdaemonize(int argc, char *argv[]) |
923 | 927 | getitimer(ITIMER_PROF,&prof_itimer); |
924 | 928 | #endif |
925 | 929 |
|
| 930 | +#ifdefWIN32 |
| 931 | +/* FIXME: [fork/exec] to be implemented? */ |
| 932 | +abort(); |
| 933 | +#else |
926 | 934 | pid=fork(); |
| 935 | +#endif |
927 | 936 | if (pid== (pid_t)-1) |
928 | 937 | { |
929 | 938 | postmaster_error("could not fork background process: %s", |
@@ -2692,14 +2701,17 @@ Backend_forkexec(Port *port) |
2692 | 2701 | av[ac++]=NULL; |
2693 | 2702 | Assert(ac <=lengthof(av)); |
2694 | 2703 |
|
| 2704 | +#ifdefWIN32 |
| 2705 | +pid=win32_forkexec(pg_pathname,av);/* logs on error */ |
| 2706 | +#else |
2695 | 2707 | /* Fire off execv in child */ |
2696 | 2708 | if ((pid=fork())==0&& (execv(pg_pathname,av)==-1)) |
2697 | 2709 | /* |
2698 | 2710 | * FIXME: [fork/exec] suggestions for what to do here? |
2699 | 2711 | * Probably OK to issue error (unlike pgstat case) |
2700 | 2712 | */ |
2701 | 2713 | abort(); |
2702 | | - |
| 2714 | +#endif |
2703 | 2715 | returnpid;/* Parent returns pid */ |
2704 | 2716 | } |
2705 | 2717 |
|
@@ -3039,12 +3051,16 @@ SSDataBase(int xlop) |
3039 | 3051 |
|
3040 | 3052 | #ifdefEXEC_BACKEND |
3041 | 3053 | /* EXEC_BACKEND case; fork/exec here */ |
| 3054 | +#ifdefWIN32 |
| 3055 | +pid=win32_forkexec(pg_pathname,av);/* logs on error */ |
| 3056 | +#else |
3042 | 3057 | if ((pid=fork())==0&& (execv(pg_pathname,av)==-1)) |
3043 | 3058 | { |
3044 | 3059 | /* in child */ |
3045 | 3060 | elog(ERROR,"unable to execv in SSDataBase: %m"); |
3046 | 3061 | exit(0); |
3047 | 3062 | } |
| 3063 | +#endif |
3048 | 3064 | #else |
3049 | 3065 | BootstrapMain(ac,av); |
3050 | 3066 | ExitPostmaster(0); |
@@ -3335,3 +3351,52 @@ read_backend_variables(unsigned long id, Port *port) |
3335 | 3351 | } |
3336 | 3352 |
|
3337 | 3353 | #endif |
| 3354 | + |
| 3355 | +#ifdefWIN32 |
| 3356 | + |
| 3357 | +pid_twin32_forkexec(constchar*path,char*argv[]) |
| 3358 | +{ |
| 3359 | +STARTUPINFOsi; |
| 3360 | +PROCESS_INFORMATIONpi; |
| 3361 | +char*p; |
| 3362 | +inti; |
| 3363 | +charcmdLine[MAXPGPATH]; |
| 3364 | + |
| 3365 | +/* Format the cmd line */ |
| 3366 | +snprintf(cmdLine,sizeof(cmdLine),"%s",path); |
| 3367 | +i=0; |
| 3368 | +while (argv[++i]!=NULL) |
| 3369 | +{ |
| 3370 | +/* FIXME: [fork/exec] some strlen checks might be prudent here */ |
| 3371 | +strcat(cmdLine," "); |
| 3372 | +strcat(cmdLine,argv[i]); |
| 3373 | +} |
| 3374 | + |
| 3375 | +/* |
| 3376 | + * The following snippet can disappear when we consistently |
| 3377 | + * use forward slashes. |
| 3378 | + */ |
| 3379 | +p=cmdLine; |
| 3380 | +while (*(p++)!='\0') |
| 3381 | +if (*p=='/')*p='\\'; |
| 3382 | + |
| 3383 | +memset(&pi,0,sizeof(pi)); |
| 3384 | +memset(&si,0,sizeof(si)); |
| 3385 | +si.cb=sizeof(si); |
| 3386 | +if (!CreateProcess(NULL,cmdLine,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)) |
| 3387 | +{ |
| 3388 | +elog(ERROR,"CreateProcess call failed (%d): %m",GetLastError()); |
| 3389 | +return-1; |
| 3390 | +} |
| 3391 | + |
| 3392 | +/* |
| 3393 | + FIXME: [fork/exec] we might need to keep the following handle/s, |
| 3394 | + depending on how we implement signalling. |
| 3395 | +*/ |
| 3396 | +CloseHandle(pi.hProcess); |
| 3397 | +CloseHandle(pi.hThread); |
| 3398 | + |
| 3399 | +returnpi.dwProcessId; |
| 3400 | +} |
| 3401 | + |
| 3402 | +#endif |