context-sync.hc (2445B)
1 // $Id$ --*- c -*-- 2 3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; version 2 of the License. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 19 /// \args p[0] used for parent -> child sync (child waits till parent is in deathrow) 20 /// \args p[1] used for child -> parent sync (recognize execv() errors) 21 static inline ALWAYSINLINE int 22 initSync(int p[2][2], bool do_disconnect) 23 { 24 if (!do_disconnect) return 0; 25 26 Epipe(p[0]); 27 Epipe(p[1]); 28 fcntl(p[1][1], F_SETFD, FD_CLOEXEC); 29 return Efork(); 30 } 31 32 static inline ALWAYSINLINE void 33 doSyncStage0(int p[2][2], bool do_disconnect) 34 { 35 char c; 36 if (!do_disconnect) return; 37 38 Eclose(p[0][1]); 39 Eread (p[0][0], &c, 1); 40 Eclose(p[0][0]); 41 } 42 43 static inline ALWAYSINLINE void 44 doSyncStage1(int p[2][2], bool do_disconnect) 45 { 46 int fd; 47 48 if (!do_disconnect) return; 49 50 fd = EopenD("/dev/null", O_RDONLY|O_NONBLOCK, 0); 51 (void)setsid(); // ignore error when we are already a session-leader 52 Edup2(fd, 0); 53 Eclose(p[1][0]); 54 if (fd!=0) Eclose(fd); 55 Ewrite(p[1][1], ".", 1); 56 } 57 58 static inline ALWAYSINLINE void 59 doSyncStage2(int p[2][2], bool do_disconnect) 60 { 61 if (!do_disconnect) return; 62 63 Ewrite(p[1][1], "X", 1); 64 } 65 66 /// \args p[0] used for parent -> child sync (child waits till parent is in deathrow) 67 /// \args p[1] used for child -> parent sync (recognize execv() errors) 68 static void 69 waitOnSync(pid_t pid, int p[2][2], bool is_prevent_race) 70 { 71 char c; 72 size_t l; 73 74 if (is_prevent_race && 75 !jailIntoTempDir(0)) { 76 perror(ENSC_WRAPPERS_PREFIX "jailIntoTempDir()"); 77 exit(255); 78 } 79 80 Eclose(p[0][0]); 81 Ewrite(p[0][1], "X", 1); 82 Eclose(p[0][1]); 83 84 Eclose(p[1][1]); 85 l = Eread(p[1][0], &c, 1); 86 if (l!=1) vc_exitLikeProcess(pid, wrapper_exit_code); 87 l = Eread(p[1][0], &c, 1); 88 if (l!=0) vc_exitLikeProcess(pid, wrapper_exit_code); 89 }