/* are there any running or stopped jobs ? */ int j_stopped_running(void) { Job *j; int which = 0; for (j = job_list; j != (Job *) 0; j = j->next) { #ifdef JOBS if (j->ppid == procpid && j->state == PSTOPPED) which |= 1; #endif /* JOBS */ if (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid && j->ppid == procpid && j->state == PRUNNING) which |= 2; } if (which) { shellf("You have %s%s%s jobs\n", which & 1 ? "stopped" : "", which == 3 ? " and " : "", which & 2 ? "running" : ""); return 1; } return 0; }
/* note: i MUST NOT be 0 */ void unwind(int i) { /* * This is a kludge. We need to restore everything that was * changed in the new environment, see cid 1005090337C7A669439 * and 10050903386452ACBF1, but fail to even save things most of * the time. funcs.c:c_eval() changes FERREXIT temporarily to 0, * which needs to be restored thus (related to Debian #696823). * We did not save the shell flags, so we use a special or'd * value here... this is mostly to clean up behind *other* * callers of unwind(LERROR) here; exec.c has the regular case. */ if (Flag(FERREXIT) & 0x80) { /* GNU bash does not run this trapsig */ trapsig(ksh_SIGERR); Flag(FERREXIT) &= ~0x80; } /* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */ if (i == LEXIT || ((i == LERROR || i == LINTR) && sigtraps[ksh_SIGEXIT].trap && (!Flag(FTALKING) || Flag(FERREXIT)))) { ++trap_nested; runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1); --trap_nested; i = LLEAVE; } else if (Flag(FERREXIT) == 1 && (i == LERROR || i == LINTR)) { ++trap_nested; runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1); --trap_nested; i = LLEAVE; } while (/* CONSTCOND */ 1) { switch (e->type) { case E_PARSE: case E_FUNC: case E_INCL: case E_LOOP: case E_ERRH: kshlongjmp(e->jbuf, i); /* NOTREACHED */ case E_NONE: if (i == LINTR) e->flags |= EF_FAKE_SIGDIE; /* FALLTHROUGH */ default: quitenv(NULL); /* * quitenv() may have reclaimed the memory * used by source which will end badly when * we jump to a function that expects it to * be valid */ source = NULL; } } }
void setTrasformationFlags(){ addFlag(Flag("r", "min-alph", "Minimal Alphabet Size", INT, &settings::MIN_ALHPABET_SIZE)); addFlag(Flag("R", "max-alph", "Maximum Alphabet Size", INT, &settings::MAX_ALHPABET_SIZE)); }
/*! This method checks if the date mask is complete in the sense that it doesn't need to have a prefilled "struct tm" when its time value is computed. */ bool DateMask::IsComplete() { // mask must be absolute, at last if ((fMask & Flag(TYPE_UNIT)) != 0) return false; // minimal set of flags to have a complete set return !(~fMask & (Flag(TYPE_DAY) | Flag(TYPE_MONTH))); }
void setLogFlags(){ /* ------ LOGGER ----- */ addFlag(Flag("D", "log-main-dir", "Main directory to store all logs", STRING, &settings::LOG_MAIN_DIR)); addFlag(Flag("d", "log-dir", "directory to store logs of current computations", STRING, &settings::LOG_CURR_DIR)); }
/* job cleanup before shell exit */ void j_exit(void) { /* kill stopped, and possibly running, jobs */ Job *j; int killed = 0; for (j = job_list; j != (Job *) 0; j = j->next) { if (j->ppid == procpid && (j->state == PSTOPPED || (j->state == PRUNNING && ((j->flags & JF_FG) || (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid))))) { killed = 1; if (j->pgrp == 0) kill_job(j, SIGHUP); else killpg(j->pgrp, SIGHUP); #ifdef JOBS if (j->state == PSTOPPED) { if (j->pgrp == 0) kill_job(j, SIGCONT); else killpg(j->pgrp, SIGCONT); } #endif /* JOBS */ } } if (killed) sleep(1); j_notify(); #ifdef JOBS if (kshpid == procpid && restore_ttypgrp >= 0) { /* Need to restore the tty pgrp to what it was when the * shell started up, so that the process that started us * will be able to access the tty when we are done. * Also need to restore our process group in case we are * about to do an exec so that both our parent and the * process we are to become will be able to access the tty. */ tcsetpgrp(tty_fd, restore_ttypgrp); setpgid(0, restore_ttypgrp); } if (Flag(FMONITOR)) { Flag(FMONITOR) = 0; j_change(); } #endif /* JOBS */ }
/* exec with no args - args case is taken care of in comexec() */ int c_exec(char **wp) { int i; /* make sure redirects stay in place */ if (e->savefd != NULL) { for (i = 0; i < NUFILE; i++) { if (e->savefd[i] > 0) close(e->savefd[i]); /* * For ksh keep anything > 2 private, * for sh, let them be (POSIX says what * happens is unspecified and the bourne shell * keeps them open). */ #ifdef KSH if (!Flag(FSH) &&i > 2 && e->savefd[i]) fd_clexec(i); #endif /* KSH */ } e->savefd = NULL; } return 0; }
/* Used by built-in utilities to prefix shell and utility name to message * (also unwinds environments for special builtins). */ void bi_errorf(const char *fmt, ...) { va_list va; shl_stdout_ok = 0; /* debugging: note that stdout not valid */ exstat = 1; if (fmt != NULL && *fmt != '\0') { error_prefix(true); /* not set when main() calls parse_args() */ if (builtin_argv0) shf_fprintf(shl_out, "%s: ", builtin_argv0); va_start(va, fmt); shf_vfprintf(shl_out, fmt, va); va_end(va); shf_putchar('\n', shl_out); } shf_flush(shl_out); /* POSIX special builtins and ksh special builtins cause * non-interactive shells to exit. * XXX odd use of KEEPASN; also may not want LERROR here */ if ((builtin_flag & SPEC_BI) || (Flag(FPOSIX) && (builtin_flag & KEEPASN))) { builtin_argv0 = NULL; unwind(LERROR); } }
int c_set(char **wp) { int argi, setargs; struct block *l = e->loc; char **owp = wp; if (wp[1] == NULL) { static const char *const args [] = { "set", "-", NULL }; return c_typeset((char **) args); } argi = parse_args(wp, OF_SET, &setargs); if (argi < 0) return 1; /* set $# and $* */ if (setargs) { owp = wp += argi - 1; wp[0] = l->argv[0]; /* save $0 */ while (*++wp != NULL) *wp = str_save(*wp, &l->area); l->argc = wp - owp - 1; l->argv = acalloc(l->argc+2, sizeof(char *), &l->area); for (wp = l->argv; (*wp++ = *owp++) != NULL; ) ; } /* POSIX says set exit status is 0, but old scripts that use * getopt(1), use the construct: set -- `getopt ab:c "$@"` * which assumes the exit value set will be that of the `` * (subst_exstat is cleared in execute() so that it will be 0 * if there are no command substitutions). */ return Flag(FPOSIX) ? 0 : subst_exstat; }
static void printoptions(int verbose) { int i; if (verbose) { struct options_info oi; int n, len; /* verbose version */ shprintf("Current option settings\n"); for (i = n = oi.opt_width = 0; i < NELEM(options); i++) if (options[i].name) { len = strlen(options[i].name); oi.opts[n].name = options[i].name; oi.opts[n++].flag = i; if (len > oi.opt_width) oi.opt_width = len; } print_columns(shl_stdout, n, options_fmt_entry, &oi, oi.opt_width + 5, 1); } else { /* short version ala ksh93 */ shprintf("set"); for (i = 0; i < NELEM(options); i++) if (Flag(i) && options[i].name) shprintf(" -o %s", options[i].name); shprintf(newline); } }
// int main(int argc,char * const argv[]) // normally this int main(int argc,char * argv[]) // const argv[] not compatible with TRint { const char* cflags="hpRvV"; RunFlags Flag(argc,argv,cflags); if(Flag.verbose>1 ) cout << __FILE__<< " " << __FUNCTION__ << " after RunFlags line " << setw(4) << __LINE__ << '\n'; const char* Fname_b1_o="~/mad/LEP/lep_twiss.tfs"; const char* Fname_b1_s="~/mad/LEP/lep_survey.tfs"; Ntuple nt_b1(ReadAndMerge(Fname_b1_o,Fname_b1_s,Flag.verbose)); TRint* theApp; if(Flag.R) theApp = new TRint("", &argc, argv, NULL, 0); // root in line mode, defined theApp Beam b1(Fname_b1_o,Flag.verbose); // get Energy and synchr integrals from optics twiss header b1.RFHV_from_twiss(nt_b1 ); b1.Print(); double nsig=1; // quad radiation from sawtooth + beam size. 0 is sawtooth only double EmitRatio=0.002; b1.EmitFromSynrad(EmitRatio); CalcBeamSizeDivergence(nt_b1,b1.ex,b1.ey,b1.sige,Flag.verbose); // calculate beam sizes and divergences and add to ntupl CalcSynrad(nt_b1,b1,Flag.verbose,nsig); nt_b1.PrintSummary(); if(Flag.p) Plot_optics(&nt_b1,Flag.verbose); //nt_b1.WriteAsciiNtFile(NULL,"/tmp/hbu/tlep_175_o_s.tfs"); // write combined optics and survey // double xmin=-0.3,xmax=0.15,zmin=0,zmax=250.; //Plot_survey(&nt_b1,Flag.verbose,xmin,xmax,zmin,zmax); if(Flag.R) { cout << " running in line mode. When done quit root from the menu bar / File " << '\n'; theApp->Run(); } };
void settrap(Trap *p, char *s) { sig_t f; if (p->trap) afree(p->trap, APERM); p->trap = str_save(s, APERM); /* handles s == 0 */ p->flags |= TF_CHANGED; f = !s ? SIG_DFL : s[0] ? trapsig : SIG_IGN; p->flags |= TF_USER_SET; if ((p->flags & (TF_DFL_INTR|TF_FATAL)) && f == SIG_DFL) f = trapsig; else if (p->flags & TF_SHELL_USES) { if (!(p->flags & TF_ORIG_IGN) || Flag(FTALKING)) { /* do what user wants at exec time */ p->flags &= ~(TF_EXEC_IGN|TF_EXEC_DFL); if (f == SIG_IGN) p->flags |= TF_EXEC_IGN; else p->flags |= TF_EXEC_DFL; } /* assumes handler already set to what shell wants it * (normally trapsig, but could be j_sigchld() or SIG_IGN) */ return; } /* todo: should we let user know signal is ignored? how? */ setsig(p, f, SS_RESTORE_CURR|SS_USER); }
/* list jobs for top-level notification */ void j_notify(void) { Job *j, *tmp; sigset_t omask; sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); for (j = job_list; j; j = j->next) { #ifdef JOBS if (Flag(FMONITOR) && (j->flags & JF_CHANGED)) j_print(j, JP_MEDIUM, shl_out); #endif /* JOBS */ /* Remove job after doing reports so there aren't * multiple +/- jobs. */ if (j->state == PEXITED || j->state == PSIGNALLED) j->flags |= JF_REMOVE; } for (j = job_list; j; j = tmp) { tmp = j->next; if (j->flags & JF_REMOVE) remove_job(j, "notify"); } shf_flush(shl_out); sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); }
void CEventQueue::CancelEventRequest() { if (Flag(EValidEventMsg)) { iEventMsg.Complete(KErrCancel); ClearFlag(EValidEventMsg); } }
/* change a Flag(*) value; takes care of special actions */ void change_flag(enum sh_flag f, int what, /* flag to change */ int newval) /* what is changing the flag (command line vs set) */ { int oldval; oldval = Flag(f); Flag(f) = newval; #ifdef JOBS if (f == FMONITOR) { if (what != OF_CMDLINE && newval != oldval) j_change(); } else #endif /* JOBS */ #ifdef EDIT if (0 # ifdef VI || f == FVI # endif /* VI */ # ifdef EMACS || f == FEMACS || f == FGMACS # endif /* EMACS */ ) { if (newval) { # ifdef VI Flag(FVI) = 0; # endif /* VI */ # ifdef EMACS Flag(FEMACS) = Flag(FGMACS) = 0; # endif /* EMACS */ Flag(f) = newval; } } else #endif /* EDIT */ /* Turning off -p? */ if (f == FPRIVILEGED && oldval && !newval) { gid_t gid = getgid(); setresgid(gid, gid, gid); setgroups(1, &gid); setresuid(ksheuid, ksheuid, ksheuid); } else if (f == FPOSIX && newval) { #ifdef BRACE_EXPAND Flag(FBRACEEXPAND) = 0 #endif /* BRACE_EXPAND */ ; } /* Changing interactive flag? */ if (f == FTALKING) { if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) Flag(FTALKING_I) = newval; } }
void CEventQueue::RequestEvent(const RMessage2& aMessage) { __ASSERT_DEBUG(!Flag(EValidEventMsg),User::Leave(KErrCompletion)); if (!Flag(EValidEventMsg)) { iEventMsg=aMessage; SetFlag(EValidEventMsg); if (Flag(EQueueError)) { TContactDbObserverEventV2 errorEvent; //EContactDbObserverEventUnknownChanges is indicating that the event queue is full errorEvent.iType = EContactDbObserverEventUnknownChanges; errorEvent.iContactId = KNullContactId; errorEvent.iConnectionId = KCntNullConnectionId; errorEvent.iTypeV2 = EContactDbObserverEventV2Null; errorEvent.iAdditionalContactIds = NULL; ClearFlag(EQueueError); SendEvent(errorEvent, NULL); } else if (iEvents.Count()>0) { SendEvent(iEvents[0], iIds[0]); iEvents.Remove(0); delete iIds[0]; iIds.Remove(0); } else { //No events has happened, so there is nothing to tell the client, //But to be able to test the API policing we will complete the message //if it contains the ApiPolicingTest flag and that the message is sent by the //API policing test process sid(0x101F7784) TInt isApiPolicingTest = aMessage.Int1(); if (isApiPolicingTest == 666 && aMessage.SecureId() == 0x101F7784) { TContactDbObserverEventV2 nullEvent; nullEvent.iType = EContactDbObserverEventNull; nullEvent.iConnectionId = 0; nullEvent.iTypeV2 = EContactDbObserverEventV2Null; nullEvent.iAdditionalContactIds = NULL; SendEvent(nullEvent, NULL); } } } }
/* format a single select menu item */ static void options_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) { const struct options_info *oi = (const struct options_info *)arg; shf_snprintf(buf, buflen, "%-*s %s", oi->opt_width, OFN(oi->opts[i]), Flag(oi->opts[i]) ? "on" : "off"); }
int c_eval(char **wp) { struct source *s,*olds=source; int retval, errexitflagtmp; if (ksh_getopt(wp, &builtin_opt, null) == '?') return 1; s = pushs(SWORDS, ATEMP); s->u.strv = wp + builtin_opt.optind; if (!Flag(FPOSIX)) { /* * Handle case where the command is empty due to failed * command substitution, eg, eval "$(false)". * In this case, shell() will not set/change exstat (because * compiled tree is empty), so will use this value. * subst_exstat is cleared in execute(), so should be 0 if * there were no substitutions. * * A strict reading of POSIX says we don't do this (though * it is traditionally done). [from 1003.2-1992] * 3.9.1: Simple Commands * ... If there is a command name, execution shall * continue as described in 3.9.1.1. If there * is no command name, but the command contained a command * substitution, the command shall complete with the exit * status of the last command substitution * 3.9.1.1: Command Search and Execution * ...(1)...(a) If the command name matches the name of * a special built-in utility, that special built-in * utility shall be invoked. * 3.14.5: Eval * ... If there are no arguments, or only null arguments, * eval shall return an exit status of zero. */ exstat = subst_exstat; } errexitflagtmp = Flag(FERREXIT); Flag(FERREXIT) = 0; retval=shell(s, false); Flag(FERREXIT) = errexitflagtmp; source=olds; return retval; }
void Quiddiards::initObjects(){ ground = new Ground({ 0, 0, 0 }, MAXRANGE, WAVEHGT); //float desktop = table.getRugHgt(); float desktop = WAVEHGT / 2; table.setCenter({ 0, 0, 0 }); // init balls and stick cueball.setCenter({ 0, 0, desktop + cueball.getR() }); balls.clear(); balls.push_back(&cueball); float l = cuebroom.getStickLen(); cuebroom.setAim(cueball.getCenter()); cuebroom.setCenter(cueball.getCenter() + QVector3D({ l, l / 3, l / 3 })); float boundX = COURTRANGE - 1, boundY = COURTRANGE - 1; for (unsigned i = 0; i < QUAFNUM; i++){ do{ quaffles[i].setCenter({ randf(-boundX, boundX), randf(-boundY, boundY), desktop + quaffles[i].getR() }); } while (conflict(quaffles[i])); balls.push_back(&quaffles[i]); } float sB = bludgers[0].getSpeed(), sS = snitch.getSpeed(); for (unsigned i = 0; i < BLUGNUM; i++){ do{ bludgers[i].setCenter({ randf(-boundX, boundX), randf(-boundY, boundY), desktop + bludgers[i].getR() }); } while (conflict(bludgers[i])); bludgers[i].setVelocity({ randf(-sB, sB), randf(-sB, sB), 0.0f }); balls.push_back(&bludgers[i]); } do{ snitch.setCenter({ randf(-boundX, boundX), randf(-boundY, boundY), desktop + snitch.getR() + 5.0f }); } while (conflict(snitch)); snitch.setVelocity({ randf(-sS, sS), randf(-sS, sS), 0 }); balls.push_back(&snitch); // init flag wind = { 1.0f, 1.0f }; flags[0] = Flag({ COURTRANGE, COURTRANGE, FLAGHGT }, Flag::GRYFFINDOR); flags[1] = Flag({ -COURTRANGE, COURTRANGE, FLAGHGT }, Flag::SLYTHERIN); flags[2] = Flag({ -COURTRANGE, -COURTRANGE, FLAGHGT }, Flag::RAVENCLAW); flags[3] = Flag({ COURTRANGE, -COURTRANGE, FLAGHGT }, Flag::HUFFLEPUFF); }
/* format a single select menu item */ static char * options_fmt_entry(char *buf, int buflen, int i, const void *arg) { const struct options_info *oi = (const struct options_info *)arg; shf_snprintf(buf, buflen, "%-*s %s", oi->opt_width, options[oi->opts[i]].name, Flag(oi->opts[i]) ? "on" : "off"); return (buf); }
/* format a single select menu item */ static char * options_fmt_entry(void *arg, int i, char *buf, int buflen) { struct options_info *oi = (struct options_info *) arg; shf_snprintf(buf, buflen, "%-*s %s", oi->opt_width, oi->opts[i].name, Flag(oi->opts[i].flag) ? "on" : "off"); return buf; }
void CEventQueue::QueueEvent(const TContactDbObserverEventV2 &aEvent) { // Flush the queue - there's no point in sending out all the preceeding // events when the an Unknown Changes event is being sent. // Unknown changes means that there are too many events to propagate and // the client should resync all its cached data. if (aEvent.iType == EContactDbObserverEventUnknownChanges) { Flush(); } // Is the queue in order, if not then return (no event will be sent) if (Flag(EQueueError)) { return; } // Can we send the event right away, i.e. do we have an outstanding request if (Flag(EValidEventMsg)) { SendEvent(aEvent, aEvent.iAdditionalContactIds); }// Is the queue full? If so set flag EQueueError and return else if (iEvents.Count() > KMaxNumberOfEventsInEventQueue) { DEBUG_PRINTDN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] ->X"), aEvent); Flush(); SetFlag(EQueueError); }// Otherwise can we add the request to the queue else if (Append(aEvent)!=KErrNone) { SetFlag(EQueueError); } #if defined(__VERBOSE_DEBUG__) else { // If added then add it to log DebugLogNotification(_L("[CNTMODEL] ->Q"), aEvent); } #endif }
/// ParseDesignator - Parse a designator. Return null if current token is not a /// designator. /// /// [R601]: /// designator := /// object-name /// or array-element /// or array-section /// or coindexed-named-object /// or complex-part-designator /// or structure-component /// or substring /// /// FIXME: substring for a character array ExprResult Parser::ParseDesignator(bool IsLvalue) { auto E = ParseNameOrCall(); struct ScopedFlag { bool value; bool &dest; ScopedFlag(bool &flag) : dest(flag) { value = flag; } ~ScopedFlag() { dest = value; } }; ScopedFlag Flag(DontResolveIdentifiers); if(DontResolveIdentifiersInSubExpressions) DontResolveIdentifiers = true; while(true) { if(!E.isUsable()) break; if(IsPresent(tok::l_paren)) { auto EType = E.get()->getType(); if(EType->isArrayType()) E = ParseArraySubscript(E); else if(EType->isCharacterType()) E = ParseSubstring(E); else { Diag.Report(Tok.getLocation(), diag::err_unexpected_lparen); return ExprError(); } } else if(IsPresent(tok::percent)) { auto EType = E.get()->getType(); if(EType->isRecordType()) E = ParseStructureComponent(E); else { Diag.Report(Tok.getLocation(), diag::err_unexpected_percent); return ExprError(); } } else if(IsPresent(tok::period)) { auto EType = E.get()->getType(); if(EType->isRecordType()) E = ParseStructureComponent(E); else { Diag.Report(Tok.getLocation(), diag::err_unexpected_period); return ExprError(); } } else break; } return E; }
Flag ConfigFlagsTable::GetFlag(__in LPCWSTR str) { for(int i=0; i < FlagCount; i++) { if(0 == _wcsicmp(str, FlagNames[i])) { return Flag(i); } } return InvalidFlag; }
/* * read an edited command line */ int x_read(char *buf, size_t len) { int i; x_mode(true); #ifdef EMACS if (Flag(FEMACS) || Flag(FGMACS)) i = x_emacs(buf, len); else #endif #ifdef VI if (Flag(FVI)) i = x_vi(buf, len); else #endif i = -1; /* internal error */ x_mode(false); check_sigwinch(); return i; }
void ConfigFlagsTable::PrintUsageString() { Output::Print(_u("List of Phases:\n")); for(int i = 0; i < PhaseCount; i++) { if (i % 4 == 0) { Output::Print(_u("\n ")); } Output::Print(_u("%-40ls "), PhaseNames[i]); } Output::Print(_u("\n\nList of flags:\n\n")); for(int i = 0; i < FlagCount; i++) { Output::Print(_u("%60ls "), FlagNames[i]); switch(GetFlagType(Flag(i))) { case InvalidFlagType: break; case FlagString: Output::Print(_u("[:String] ")); break; case FlagPhases: Output::Print(_u("[:Phase] ")); break; case FlagNumber: Output::Print(_u("[:Number] ")); break; case FlagBoolean: Output::Print(_u(" ")); break; case FlagNumberSet: Output::Print(_u("[:NumberSet] ")); break; case FlagNumberPairSet: Output::Print(_u("[:NumberPairSet] ")); break; case FlagNumberTrioSet: Output::Print(_u("[:NumberTrioSet] ")); break; case FlagNumberRange: Output::Print(_u("[:NumberRange] ")); break; default: Assert(false); __assume(false); } Output::Print(_u("%ls\n"), FlagDescriptions[i]); } }
/* change a Flag(*) value; takes care of special actions */ void change_flag(enum sh_flag f, int what, /* flag to change */ int newval) /* what is changing the flag (command line vs set) */ { int oldval; oldval = Flag(f); Flag(f) = newval; /* Turning off -p? */ if (f == FPOSIX && newval) { Flag(FBRACEEXPAND) = 0 ; } /* Changing interactive flag? */ if (f == FTALKING) { if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) Flag(FTALKING_I) = newval; } }
char * getoptions(void) { int i; char m[(int) FNFLAGS + 1]; char *cp = m; for (i = 0; i < NELEM(options); i++) if (options[i].c && Flag(i)) *cp++ = options[i].c; *cp = 0; return str_save(m, ATEMP); }
char * getoptions(void) { unsigned int i; char m[(int) FNFLAGS + 1]; char *cp = m; for (i = 0; i < NELEM(options); i++) if (options[i].c && Flag(i)) *cp++ = options[i].c; strndupx(cp, m, cp - m, ATEMP); return (cp); }
char * getoptions(void) { unsigned int ele; char m[(int) FNFLAGS + 1]; char *cp = m; for (ele = 0; ele < NELEM(sh_options); ele++) if (sh_options[ele].c && Flag(ele)) *cp++ = sh_options[ele].c; *cp = 0; return str_save(m, ATEMP); }