/* kill the wine server holding the lock */ int kill_lock_owner( int sig ) { const char *server_dir = wine_get_server_dir(); int fd, i, ret = 0; pid_t pid = 0; struct flock fl; if (!server_dir) return 0; /* no server dir, nothing to do */ create_server_dir( server_dir ); fd = create_server_lock(); for (i = 1; i <= 20; i++) { fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 1; if (fcntl( fd, F_GETLK, &fl ) == -1) goto done; if (fl.l_type != F_WRLCK) goto done; /* the file is not locked */ if (!pid) /* first time around */ { if (!(pid = fl.l_pid)) goto done; /* shouldn't happen */ if (sig == -1) { if (kill( pid, SIGINT ) == -1) goto done; kill( pid, SIGCONT ); ret = 1; } else /* just send the specified signal and return */ { ret = (kill( pid, sig ) != -1); goto done; } } else if (fl.l_pid != pid) goto done; /* no longer the same process */ usleep( 50000 * i ); } /* waited long enough, now kill it */ kill( pid, SIGKILL ); done: close( fd ); return ret; }
/* wait for the server lock */ int wait_for_lock(void) { const char *server_dir = wine_get_server_dir(); int fd, r; struct flock fl; if (!server_dir) return 0; /* no server dir, so no lock to wait on */ create_server_dir( server_dir ); fd = create_server_lock(); fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 1; r = fcntl( fd, F_SETLKW, &fl ); close(fd); return r; }
/* open the master server socket and start waiting for new clients */ void open_master_socket(void) { const char *server_dir = wine_get_server_dir(); const char *config_dir = wine_get_config_dir(); int fd, pid, status, sync_pipe[2]; char dummy; /* make sure no request is larger than the maximum size */ assert( sizeof(union generic_request) == sizeof(struct request_max_size) ); assert( sizeof(union generic_reply) == sizeof(struct request_max_size) ); /* make sure the stdio fds are open */ fd = open( "/dev/null", O_RDWR ); while (fd >= 0 && fd <= 2) fd = dup( fd ); if (!server_dir) fatal_error( "directory %s cannot be accessed\n", config_dir ); if (chdir( config_dir ) == -1) fatal_perror( "chdir to %s", config_dir ); if ((config_dir_fd = open( ".", O_RDONLY )) == -1) fatal_perror( "open %s", config_dir ); create_server_dir( server_dir ); if (!foreground) { if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" ); pid = fork(); switch( pid ) { case 0: /* child */ setsid(); close( sync_pipe[0] ); acquire_lock(); /* close stdin and stdout */ dup2( fd, 0 ); dup2( fd, 1 ); /* signal parent */ dummy = 0; write( sync_pipe[1], &dummy, 1 ); close( sync_pipe[1] ); break; case -1: fatal_perror( "fork" ); break; default: /* parent */ close( sync_pipe[1] ); /* wait for child to signal us and then exit */ if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0); /* child terminated, propagate exit status */ waitpid( pid, &status, 0 ); if (WIFEXITED(status)) _exit( WEXITSTATUS(status) ); _exit(1); } } else /* remain in the foreground */ { acquire_lock(); } /* init the process tracing mechanism */ init_tracing_mechanism(); close( fd ); }
/* open the master server socket and start waiting for new clients */ void open_master_socket(void) { const char *server_dir = wine_get_server_dir(); int fd, pid, status, sync_pipe[2]; char dummy; /* make sure no request is larger than the maximum size */ assert( sizeof(union generic_request) == sizeof(struct request_max_size) ); assert( sizeof(union generic_reply) == sizeof(struct request_max_size) ); if (!server_dir) fatal_error( "directory %s cannot be accessed\n", wine_get_config_dir() ); create_server_dir( server_dir ); if (!foreground) { if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" ); pid = fork(); switch( pid ) { case 0: /* child */ setsid(); close( sync_pipe[0] ); acquire_lock(); /* close stdin and stdout */ if ((fd = open( "/dev/null", O_RDWR )) != -1) { dup2( fd, 0 ); dup2( fd, 1 ); close( fd ); } /* signal parent */ dummy = 0; write( sync_pipe[1], &dummy, 1 ); close( sync_pipe[1] ); break; case -1: fatal_perror( "fork" ); break; default: /* parent */ close( sync_pipe[1] ); /* wait for child to signal us and then exit */ if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0); /* child terminated, propagate exit status */ wait4( pid, &status, 0, NULL ); if (WIFEXITED(status)) _exit( WEXITSTATUS(status) ); _exit(1); } } else /* remain in the foreground */ { acquire_lock(); } /* setup msghdr structure constant fields */ msghdr.msg_name = NULL; msghdr.msg_namelen = 0; msghdr.msg_iov = &myiovec; msghdr.msg_iovlen = 1; /* init startup time */ gettimeofday( &server_start_time, NULL ); }