Re: sh and process management
On Sun, 16 Jul 2006, Gustavo Rios wrote: > Ok, here you have it: I'm sorry, but I'm not gonna go though this bit flag mess. Until you come up with a simple (let's say less than 10 lines) piece of code to demonstrate the porblem you're seeing, my conclusion is the bug is hiding in your code. -Otto > > Code for apx_setuid : > #include > > long > apx_setsid(void) > { >return setsid(); > } > > Code for apx_setpgid : > > #include > > int > apx_setpgid(const long p, const long g) > { >return setpgid((pid_t)p, (pid_t)g); > } > > > Code for sux (main.c) : (the relevant part is option -s and function do_sid) > > #include > #include > #include > > #include "abf.h" > #include "amp.h" > #include "apx.h" > #include "msc.h" > #include "rsc.h" > #include "sdb.h" > > extern int r2e __P((int)); > extern void wrn __P((int)), >die __P((int)); > > static int > do_env(const xlong f, const char *e) > { >struct amp a; >xlong n, x; >int r = 0; > >if (f) *apx_environ = NULL; >if (e) { >amp_opn(&a); >r = env_h2b(&a, e, apx_strlen(e)); >if (!r) for (e = a.b, n = a.s.x; n; e += x, n -= x) { >if (!(x = chr(e, n, '+'))) break; >if (r = apx_putenv(e + x)) break; >} >amp_cls(&a); >} >return r; > } > > static int > do_dir(const char * const d) > { >return d ? apx_chdir(d) : 0; > } > > static long > do_fork(const xlong f) > { >return f ? apx_fork() : 0l; > } > > static int > do_sid(const xlong f) > { >int r; > >if (r = 0, f & 1) >if (f & 2) { if (apx_setsid() == -1) r = -1; } >else r = apx_setpgid(0l, apx_getpid()); > >return r; > } > > static int > do_prio(const char * const s) > { >xlong x; >int r; > >if (r = 0, s) { >if (!scn_u(&x, s)) r = 5; >if (!r) r = apx_setprio(prio_process, 0l, (int)x); >} >return r; > } > > static int > do_ioe(const char * const s) > { >xlong x; >int r; > >if (r = 0, s) { >if (!scn_x(&x, s)) r = 5; >if (!r) r = apx_setioe((int)x, NULL, NULL); >} >return r; > } > > static int > do_rsc(const char * const s) > { >struct sdb sd; >struct rsc rs; >xlong i; >int r; > >rsc_opn(&rs); >sdb_opn(&sd); >r = s ? getrsc(&rs, &sd, s) : 0; >if (!r) for (i = 0; i < rs.sze.x; i++) >(void)apx_setrlmt(rs.rds[i].idx, &rs.rds[i].val); >sdb_cls(&sd); >rsc_cls(&rs); >return r; > } > > static int > do_crd(const char * const u, const char * const g, const char * const G) > { >struct passwd *pwd = NULL; >struct group*grp = NULL; >struct amp a; >xlong v; >xadk32_ts[ngroups_max]; >int r = 0; >char*p; > >if (u) if (!(pwd = getpwnam(u))) r = 4; >if (!r) if (g) if (!(grp = getgrnam(g))) r = 4; >if (!r) { >v = grp ? grp->gr_gid : pwd ? pwd->pw_gid : -1ul; >if (v + 1) r = apx_setgid(v); >} > >if (!r) if (G) { >amp_opn(&a); >r = amp_mem(&a, G, apx_strlen(G)); >if (!r) r = amp_chr(&a, '\0'); >if (!r) { >for (p = a.b; *p; p++) if (*p == ',') *p = '\0'; >for (v = 0, p = a.b; p - a.b < a.s.x; v++, p++) { >if (v == ngroups_max) break; >if (!(grp = getgrnam(p))) break; >s[v] = grp->gr_gid; >while (*p) p++; >} >if (p - a.b < a.s.x) if (v < ngroups_max) r = 4; >} >amp_cls(&a); >if (!r) if (!v) r = 5; >if (!r) r = apx_setgrp(s, v); >} > >if (!r) if (pwd) r = apx_setuid(0ul+pwd->pw_uid); > >return r; > } > > static int > do_exec(char **a) > { >(void)apx_execve(*a, a + 1, apx_environ); >return 2; > } > > static long > __chk(char *s[8]) > { >xlong n; > >for (n = 8; n; n--) if (s[n - 1]) break; >return n; > } > > int > main(int argc, char **argv) > { >xlong i, f; >int r; >char*s[8], >o[] = "fspeu:g:G:d:n:E:x:r:"; > >apx_memset(s, 0, sizeof s); >apx_opterr = 0; >i = f = 0; > >while ((r = apx_getopt(argc, argv, o)) + 1) >switch (r) { >case 'f' : f |= 1; break; >
Re: sh and process management
On 7/16/06, Gustavo Rios <[EMAIL PROTECTED]> wrote: ... static int do_sid(const xlong f) { int r; if (r = 0, f & 1) if (f & 2) { if (apx_setsid() == -1) r = -1; } else r = apx_setpgid(0l, apx_getpid()); return r; } Wow, what an annoying set of coding conventions you use. The best part is, the bug is in your use of one of them: use of unnamed bit flags with particular flags being stored in _different_bits_ in different parts of the code. (i.e., the "do setsid()" flag is 4 in main but 2 in the above. Using the same values and defining symbolic names would have kept this problem from occuring. Not trying to be too clever would have helped too. So, please consider the above code and then think _really_ hard about the code that determines the value of 'f' in that call: ... case 's' : f |= 2, f |= 4; break; case 'p' : f |= 2, f &= ~4; break; ... if (!r) r = do_sid(f & 6 >> 1); That last line contains the bug, but the _source_ of the bug is either the lack of symbolic constants or your decision to use bitflags at all instead of just putting the flags in separate variables. Philip Guenther
Re: sh and process management
Ok, here you have it: Code for apx_setuid : #include long apx_setsid(void) { return setsid(); } Code for apx_setpgid : #include int apx_setpgid(const long p, const long g) { return setpgid((pid_t)p, (pid_t)g); } Code for sux (main.c) : (the relevant part is option -s and function do_sid) #include #include #include #include "abf.h" #include "amp.h" #include "apx.h" #include "msc.h" #include "rsc.h" #include "sdb.h" extern int r2e __P((int)); extern void wrn __P((int)), die __P((int)); static int do_env(const xlong f, const char *e) { struct amp a; xlong n, x; int r = 0; if (f) *apx_environ = NULL; if (e) { amp_opn(&a); r = env_h2b(&a, e, apx_strlen(e)); if (!r) for (e = a.b, n = a.s.x; n; e += x, n -= x) { if (!(x = chr(e, n, '+'))) break; if (r = apx_putenv(e + x)) break; } amp_cls(&a); } return r; } static int do_dir(const char * const d) { return d ? apx_chdir(d) : 0; } static long do_fork(const xlong f) { return f ? apx_fork() : 0l; } static int do_sid(const xlong f) { int r; if (r = 0, f & 1) if (f & 2) { if (apx_setsid() == -1) r = -1; } else r = apx_setpgid(0l, apx_getpid()); return r; } static int do_prio(const char * const s) { xlong x; int r; if (r = 0, s) { if (!scn_u(&x, s)) r = 5; if (!r) r = apx_setprio(prio_process, 0l, (int)x); } return r; } static int do_ioe(const char * const s) { xlong x; int r; if (r = 0, s) { if (!scn_x(&x, s)) r = 5; if (!r) r = apx_setioe((int)x, NULL, NULL); } return r; } static int do_rsc(const char * const s) { struct sdb sd; struct rsc rs; xlong i; int r; rsc_opn(&rs); sdb_opn(&sd); r = s ? getrsc(&rs, &sd, s) : 0; if (!r) for (i = 0; i < rs.sze.x; i++) (void)apx_setrlmt(rs.rds[i].idx, &rs.rds[i].val); sdb_cls(&sd); rsc_cls(&rs); return r; } static int do_crd(const char * const u, const char * const g, const char * const G) { struct passwd *pwd = NULL; struct group*grp = NULL; struct amp a; xlong v; xadk32_ts[ngroups_max]; int r = 0; char*p; if (u) if (!(pwd = getpwnam(u))) r = 4; if (!r) if (g) if (!(grp = getgrnam(g))) r = 4; if (!r) { v = grp ? grp->gr_gid : pwd ? pwd->pw_gid : -1ul; if (v + 1) r = apx_setgid(v); } if (!r) if (G) { amp_opn(&a); r = amp_mem(&a, G, apx_strlen(G)); if (!r) r = amp_chr(&a, '\0'); if (!r) { for (p = a.b; *p; p++) if (*p == ',') *p = '\0'; for (v = 0, p = a.b; p - a.b < a.s.x; v++, p++) { if (v == ngroups_max) break; if (!(grp = getgrnam(p))) break; s[v] = grp->gr_gid; while (*p) p++; } if (p - a.b < a.s.x) if (v < ngroups_max) r = 4; } amp_cls(&a); if (!r) if (!v) r = 5; if (!r) r = apx_setgrp(s, v); } if (!r) if (pwd) r = apx_setuid(0ul+pwd->pw_uid); return r; } static int do_exec(char **a) { (void)apx_execve(*a, a + 1, apx_environ); return 2; } static long __chk(char *s[8]) { xlong n; for (n = 8; n; n--) if (s[n - 1]) break; return n; } int main(int argc, char **argv) { xlong i, f; int r; char*s[8], o[] = "fspeu:g:G:d:n:E:x:r:"; apx_memset(s, 0, sizeof s); apx_opterr = 0; i = f = 0; while ((r = apx_getopt(argc, argv, o)) + 1) switch (r) { case 'f' : f |= 1; break; case 's' : f |= 2, f |= 4; break; case 'p' : f |= 2, f &= ~4; break; case 'e' : f |= 8; break; case 'u' : s[0] = apx_optarg; break; case 'g' : s[1] = apx_optarg; break; case 'G' : s[2] = apx_optarg; break; case 'd' : s[3] = apx_optarg; break; case 'n' : s[4] = apx_optarg; break; case 'E' : s[5] = apx_optarg; break; case 'x' : s[6] = apx_optarg; break; case 'r' : s[7] = apx_optarg; break; } argc -= apx_optind, argv += apx_optind; r = f || __chk(s) ? 0 : argc < 3 ? 1 : (s[0] = *argv++, argc--, 0)
Re: sh and process management
On 7/15/06, Gustavo Rios <[EMAIL PROTECTED]> wrote: i am trying to set a process as the session leader of its own. I wrote a simple program that handles that. It is working when i call it from my shell command line: ... But when i write a simple shell script like in : The process is not put on its own session as a leader the (setsid) returns no errors. /bin/sh doesn't change the process-group of the processes that it invokes, while interactive shells with job-control support do change it, so that's the difference between invocation from a script versus an interactive shell. Unfortunately, it would suggest the _opposite_ behavior: setsid() from a process run by an interactive shell should fail. Too bad you didn't provide a complete description of the system calls made by your program, or direct evidence (say, the output of ps -j) of the results of running it in the two cases. As is, my current guess is that you're misreading the 'ps' output and confusing the concepts of process-group leader and session leader. Philip Guenther
Re: sh and process management
On Sun, 16 Jul 2006, Gustavo Rios wrote: > Hey folks, > > i am trying to set a process as the session leader of its own. I wrote > a simple program that handles that. It is working when i call it from > my shell command line: > > $ sux -s -e -E \ > PATH==/home/grios/.bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games:/asd/bin:/asd/sbin:/asd/thr=,ASDROOT==/asd= > /asd/sbin/algr algr argm > > But when i write a simple shell script like in : > > #!/bin/sh > sux -s -e -E \ > PATH==/home/grios/.bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games:/asd/bin:/asd/sbin:/asd/thr=,ASDROOT==/asd= > /asd/sbin/algr algr argm > > The process is not put on its own session as a leader the (setsid) > returns no errors. > > Does anybody have any ideia what the behavior problem i am not seeing ? Please show the code. How do you check if the program has become session leader? Any other process group/session stuff being done in your program? -Otto
sh and process management
Hey folks, i am trying to set a process as the session leader of its own. I wrote a simple program that handles that. It is working when i call it from my shell command line: $ sux -s -e -E \ PATH==/home/grios/.bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games:/asd/bin:/asd/sbin:/asd/thr=,ASDROOT==/asd= /asd/sbin/algr algr argm But when i write a simple shell script like in : #!/bin/sh sux -s -e -E \ PATH==/home/grios/.bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games:/asd/bin:/asd/sbin:/asd/thr=,ASDROOT==/asd= /asd/sbin/algr algr argm The process is not put on its own session as a leader the (setsid) returns no errors. Does anybody have any ideia what the behavior problem i am not seeing ? Thanks in advance.