This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fetch magic on the first stacked filetest, not the last
[perl5.git] / pp_sys.c
index b078586..5c9f768 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -213,8 +213,8 @@ void endservent(void);
 #endif
 
 #if !defined(PERL_EFF_ACCESS) && defined(HAS_ACCESSX) && defined(ACC_SELF)
-    /* AIX */
-#   define PERL_EFF_ACCESS(p,f) (accessx((p), (f), ACC_SELF))
+    /* AIX's accessx() doesn't declare its argument const, unlike every other platform */
+#   define PERL_EFF_ACCESS(p,f) (accessx((char*)(p), (f), ACC_SELF))
 #endif
 
 
@@ -417,7 +417,7 @@ PP(pp_warn)
     }
     else if (SP == MARK) {
        exsv = &PL_sv_no;
-       EXTEND(SP, 1);
+       MEXTEND(SP, 1);
        SP = MARK + 1;
     }
     else {
@@ -498,7 +498,7 @@ PP(pp_die)
                }
            }
        }
-       else if (SvPOK(errsv) && SvCUR(errsv)) {
+       else if (SvOK(errsv) && (SvPV_nomg(errsv,len), len)) {
            exsv = sv_mortalcopy(errsv);
            sv_catpvs(exsv, "\t...propagated");
        }
@@ -690,7 +690,7 @@ PP(pp_pipe_op)
     if (IoIFP(wstio))
        do_close(wgv, FALSE);
 
-    if (PerlProc_pipe(fd) < 0)
+    if (PerlProc_pipe_cloexec(fd) < 0)
        goto badexit;
 
     IoIFP(rstio) = PerlIO_fdopen(fd[0], "r" PIPE_OPEN_MODE);
@@ -711,12 +711,6 @@ PP(pp_pipe_op)
            PerlLIO_close(fd[1]);
        goto badexit;
     }
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
-    /* ensure close-on-exec */
-    if ((fd[0] > PL_maxsysfd && fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) ||
-        (fd[1] > PL_maxsysfd && fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0))
-        goto badexit;
-#endif
     RETPUSHYES;
 
   badexit:
@@ -1299,7 +1293,7 @@ PP(pp_sselect)
 
 /*
 
-=head1 GV Functions
+=for apidoc_section $GV
 
 =for apidoc setdefout
 
@@ -1731,10 +1725,9 @@ PP(pp_sysread)
 
     if ((fp_utf8 = PerlIO_isutf8(IoIFP(io))) && !IN_BYTES) {
         if (PL_op->op_type == OP_SYSREAD || PL_op->op_type == OP_RECV) {
-            Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
-                             "%s() is deprecated on :utf8 handles. "
-                             "This will be a fatal error in Perl 5.30",
-                             OP_DESC(PL_op));
+            Perl_croak(aTHX_
+                       "%s() isn't allowed on :utf8 handles",
+                       OP_DESC(PL_op));
         }
        buffer = SvPVutf8_force(bufsv, blen);
        /* UTF-8 may not have been set if they are all low bytes */
@@ -1743,7 +1736,7 @@ PP(pp_sysread)
     }
     else {
        buffer = SvPV_force(bufsv, blen);
-       buffer_utf8 = !IN_BYTES && SvUTF8(bufsv);
+       buffer_utf8 = DO_UTF8(bufsv);
     }
     if (DO_UTF8(bufsv)) {
        blen = sv_len_utf8_nomg(bufsv);
@@ -1945,7 +1938,6 @@ PP(pp_syswrite)
     const char *buffer;
     SSize_t retval;
     STRLEN blen;
-    STRLEN orig_blen_bytes;
     const int op_type = PL_op->op_type;
     bool doing_utf8;
     U8 *tmpbuf = NULL;
@@ -1991,20 +1983,12 @@ PP(pp_syswrite)
 
     /* Do this first to trigger any overloading.  */
     buffer = SvPV_const(bufsv, blen);
-    orig_blen_bytes = blen;
     doing_utf8 = DO_UTF8(bufsv);
 
     if (PerlIO_isutf8(IoIFP(io))) {
-        Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
-                         "%s() is deprecated on :utf8 handles. "
-                         "This will be a fatal error in Perl 5.30",
-                         OP_DESC(PL_op));
-       if (!SvUTF8(bufsv)) {
-           /* We don't modify the original scalar.  */
-           tmpbuf = bytes_to_utf8((const U8*) buffer, &blen);
-           buffer = (char *) tmpbuf;
-           doing_utf8 = TRUE;
-       }
+        Perl_croak(aTHX_
+                   "%s() isn't allowed on :utf8 handles",
+                   OP_DESC(PL_op));
     }
     else if (doing_utf8) {
        STRLEN tmplen = blen;
@@ -2037,25 +2021,10 @@ PP(pp_syswrite)
 #endif
     {
        Size_t length = 0; /* This length is in characters.  */
-       STRLEN blen_chars;
        IV offset;
 
-       if (doing_utf8) {
-           if (tmpbuf) {
-               /* The SV is bytes, and we've had to upgrade it.  */
-               blen_chars = orig_blen_bytes;
-           } else {
-               /* The SV really is UTF-8.  */
-               /* Don't call sv_len_utf8 on a magical or overloaded
-                  scalar, as we might get back a different result.  */
-               blen_chars = sv_or_pv_len_utf8(bufsv, buffer, blen);
-           }
-       } else {
-           blen_chars = blen;
-       }
-
        if (MARK >= SP) {
-           length = blen_chars;
+           length = blen;
        } else {
 #if Size_t_size > IVSIZE
            length = (Size_t)SvNVx(*++MARK);
@@ -2071,46 +2040,21 @@ PP(pp_syswrite)
        if (MARK < SP) {
            offset = SvIVx(*++MARK);
            if (offset < 0) {
-               if (-offset > (IV)blen_chars) {
+               if (-offset > (IV)blen) {
                    Safefree(tmpbuf);
                    DIE(aTHX_ "Offset outside string");
                }
-               offset += blen_chars;
-           } else if (offset > (IV)blen_chars) {
+               offset += blen;
+           } else if (offset > (IV)blen) {
                Safefree(tmpbuf);
                DIE(aTHX_ "Offset outside string");
            }
        } else
            offset = 0;
-       if (length > blen_chars - offset)
-           length = blen_chars - offset;
-       if (doing_utf8) {
-           /* Here we convert length from characters to bytes.  */
-           if (tmpbuf || SvGMAGICAL(bufsv) || SvAMAGIC(bufsv)) {
-               /* Either we had to convert the SV, or the SV is magical, or
-                  the SV has overloading, in which case we can't or mustn't
-                  or mustn't call it again.  */
-
-               buffer = (const char*)utf8_hop((const U8 *)buffer, offset);
-               length = utf8_hop((U8 *)buffer, length) - (U8 *)buffer;
-           } else {
-               /* It's a real UTF-8 SV, and it's not going to change under
-                  us.  Take advantage of any cache.  */
-               I32 start = offset;
-               I32 len_I32 = length;
-
-               /* Convert the start and end character positions to bytes.
-                  Remember that the second argument to sv_pos_u2b is relative
-                  to the first.  */
-               sv_pos_u2b(bufsv, &start, &len_I32);
-
-               buffer += start;
-               length = len_I32;
-           }
-       }
-       else {
-           buffer = buffer+offset;
-       }
+       if (length > blen - offset)
+           length = blen - offset;
+        buffer = buffer+offset;
+
 #ifdef PERL_SOCK_SYSWRITE_IS_SEND
        if (IoTYPE(io) == IoTYPE_SOCKET) {
            retval = PerlSock_send(fd, buffer, length, 0);
@@ -2126,8 +2070,6 @@ PP(pp_syswrite)
     if (retval < 0)
        goto say_undef;
     SP = ORIGMARK;
-    if (doing_utf8)
-        retval = utf8_length((U8*)buffer, (U8*)buffer + retval);
 
     Safefree(tmpbuf);
 #if Size_t_size > IVSIZE
@@ -2179,7 +2121,7 @@ PP(pp_eof)
     }
 
     if (!gv)
-       RETPUSHNO;
+       RETPUSHYES;
 
     if ((io = GvIO(gv)) && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar))) {
        return tied_method1(SV_CONST(EOF), SP, MUTABLE_SV(io), mg, newSVuv(which));
@@ -2187,7 +2129,7 @@ PP(pp_eof)
 
     if (!MAXARG && (PL_op->op_flags & OPf_SPECIAL)) {  /* eof() */
        if (io && !IoIFP(io)) {
-           if ((IoFLAGS(io) & IOf_START) && av_tindex(GvAVn(gv)) < 0) {
+           if ((IoFLAGS(io) & IOf_START) && av_count(GvAVn(gv)) == 0) {
                SV ** svp;
                IoLINES(io) = 0;
                IoFLAGS(io) &= ~IOf_START;
@@ -2237,9 +2179,9 @@ PP(pp_tell)
     }
 
 #if LSEEKSIZE > IVSIZE
-    PUSHn( do_tell(gv) );
+    PUSHn( (NV)do_tell(gv) );
 #else
-    PUSHi( do_tell(gv) );
+    PUSHi( (IV)do_tell(gv) );
 #endif
     RETURN;
 }
@@ -2379,7 +2321,7 @@ PP(pp_truncate)
                  */
                 mode |= O_BINARY;
 #endif
-                tmpfd = PerlLIO_open(name, mode);
+                tmpfd = PerlLIO_open_cloexec(name, mode);
 
                if (tmpfd < 0) {
                    result = 0;
@@ -2521,7 +2463,7 @@ PP(pp_socket)
        do_close(gv, FALSE);
 
     TAINT_PROPER("socket");
-    fd = PerlSock_socket(domain, type, protocol);
+    fd = PerlSock_socket_cloexec(domain, type, protocol);
     if (fd < 0) {
        RETPUSHUNDEF;
     }
@@ -2534,11 +2476,6 @@ PP(pp_socket)
        if (!IoIFP(io) && !IoOFP(io)) PerlLIO_close(fd);
        RETPUSHUNDEF;
     }
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
-    /* ensure close-on-exec */
-    if (fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
-       RETPUSHUNDEF;
-#endif
 
     RETPUSHYES;
 }
@@ -2564,7 +2501,7 @@ PP(pp_sockpair)
        do_close(gv2, FALSE);
 
     TAINT_PROPER("socketpair");
-    if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
+    if (PerlSock_socketpair_cloexec(domain, type, protocol, fd) < 0)
        RETPUSHUNDEF;
     IoIFP(io1) = PerlIO_fdopen(fd[0], "r" SOCKET_OPEN_MODE);
     IoOFP(io1) = PerlIO_fdopen(fd[0], "w" SOCKET_OPEN_MODE);
@@ -2581,12 +2518,6 @@ PP(pp_sockpair)
        if (!IoIFP(io2) && !IoOFP(io2)) PerlLIO_close(fd[1]);
        RETPUSHUNDEF;
     }
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
-    /* ensure close-on-exec */
-    if ((fd[0] > PL_maxsysfd && fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) ||
-        (fd[1] > PL_maxsysfd && fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0))
-       RETPUSHUNDEF;
-#endif
 
     RETPUSHYES;
 #else
@@ -2673,7 +2604,7 @@ PP(pp_accept)
        goto nuts;
 
     nstio = GvIOn(ngv);
-    fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *) namebuf, &len);
+    fd = PerlSock_accept_cloexec(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *) namebuf, &len);
 #if defined(OEMVS)
     if (len == 0) {
        /* Some platforms indicate zero length when an AF_UNIX client is
@@ -2698,11 +2629,6 @@ PP(pp_accept)
        if (!IoIFP(nstio) && !IoOFP(nstio)) PerlLIO_close(fd);
        goto badexit;
     }
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
-    /* ensure close-on-exec */
-    if (fd > PL_maxsysfd && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
-        goto badexit;
-#endif
 
 #ifdef __SCO_VERSION__
     len = sizeof (struct sockaddr_in); /* OpenUNIX 8 somehow truncates info */
@@ -2779,30 +2705,16 @@ PP(pp_ssockopt)
        PUSHs(sv);
        break;
     case OP_SSOCKOPT: {
-#if defined(__SYMBIAN32__)
-# define SETSOCKOPT_OPTION_VALUE_T void *
-#else
-# define SETSOCKOPT_OPTION_VALUE_T const char *
-#endif
-       /* XXX TODO: We need to have a proper type (a Configure probe,
-        * etc.) for what the C headers think of the third argument of
-        * setsockopt(), the option_value read-only buffer: is it
-        * a "char *", or a "void *", const or not.  Some compilers
-        * don't take kindly to e.g. assuming that "char *" implicitly
-        * promotes to a "void *", or to explicitly promoting/demoting
-        * consts to non/vice versa.  The "const void *" is the SUS
-        * definition, but that does not fly everywhere for the above
-        * reasons. */
-           SETSOCKOPT_OPTION_VALUE_T buf;
+           const char *buf;
            int aint;
            if (SvPOKp(sv)) {
                STRLEN l;
-               buf = (SETSOCKOPT_OPTION_VALUE_T) SvPV_const(sv, l);
+               buf = SvPV_const(sv, l);
                len = l;
            }
            else {
                aint = (int)SvIV(sv);
-               buf = (SETSOCKOPT_OPTION_VALUE_T) &aint;
+               buf = (const char *) &aint;
                len = sizeof(int);
            }
            if (PerlSock_setsockopt(fd, lvl, optname, buf, len) < 0)
@@ -2837,9 +2749,13 @@ PP(pp_getpeername)
     if (!IoIFP(io))
        goto nuts;
 
-    sv = sv_2mortal(newSV(257));
-    (void)SvPOK_only(sv);
+#ifdef HAS_SOCKADDR_STORAGE
+    len = sizeof(struct sockaddr_storage);
+#else
     len = 256;
+#endif
+    sv = sv_2mortal(newSV(len+1));
+    (void)SvPOK_only(sv);
     SvCUR_set(sv, len);
     *SvEND(sv) ='\0';
     fd = PerlIO_fileno(IoIFP(io));
@@ -2981,9 +2897,9 @@ PP(pp_stat)
        if (PL_laststatval < 0) {
            if (ckWARN(WARN_NEWLINE) && should_warn_nl(file)) {
                 /* PL_warn_nl is constant */
-                GCC_DIAG_IGNORE(-Wformat-nonliteral);
+                GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral);
                Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
-                GCC_DIAG_RESTORE;
+                GCC_DIAG_RESTORE_STMT;
             }
            max = 0;
        }
@@ -3014,11 +2930,11 @@ PP(pp_stat)
             */
            bool neg;
            Stat_t s;
-           CLANG_DIAG_IGNORE(-Wtautological-compare);
-           GCC_DIAG_IGNORE(-Wtype-limits);
+           CLANG_DIAG_IGNORE_STMT(-Wtautological-compare);
+           GCC_DIAG_IGNORE_STMT(-Wtype-limits);
            neg = PL_statcache.st_ino < 0;
-           GCC_DIAG_RESTORE;
-           CLANG_DIAG_RESTORE;
+           GCC_DIAG_RESTORE_STMT;
+           CLANG_DIAG_RESTORE_STMT;
            if (neg) {
                s.st_ino = (IV)PL_statcache.st_ino;
                if (LIKELY(s.st_ino == PL_statcache.st_ino)) {
@@ -3151,7 +3067,7 @@ S_try_amagic_ftest(pTHX_ char chr) {
     SV *const arg = *PL_stack_sp;
 
     assert(chr != '?');
-    if (!(PL_op->op_private & OPpFT_STACKING)) SvGETMAGIC(arg);
+    if (!(PL_op->op_private & OPpFT_STACKED)) SvGETMAGIC(arg);
 
     if (SvAMAGIC(arg))
     {
@@ -3593,9 +3509,9 @@ PP(pp_fttext)
            }
            if (ckWARN(WARN_NEWLINE) && should_warn_nl(file)) {
                 /* PL_warn_nl is constant */
-                GCC_DIAG_IGNORE(-Wformat-nonliteral);
+                GCC_DIAG_IGNORE_STMT(-Wformat-nonliteral);
                Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
-                GCC_DIAG_RESTORE;
+                GCC_DIAG_RESTORE_STMT;
             }
            FT_RETURNUNDEF;
        }
@@ -3898,8 +3814,7 @@ PP(pp_readlink)
     len = readlink(tmps, buf, sizeof(buf) - 1);
     if (len < 0)
        RETPUSHUNDEF;
-    if (len != -1)
-        buf[len] = '\0';
+    buf[len] = '\0';
     PUSHp(buf, len);
     RETURN;
 #else
@@ -4392,14 +4307,45 @@ PP(pp_system)
     int result;
 # endif
 
+    while (++MARK <= SP) {
+       SV *origsv = *MARK, *copysv;
+       STRLEN len;
+       char *pv;
+       SvGETMAGIC(origsv);
+#if defined(WIN32) || defined(__VMS)
+       /*
+        * Because of a nasty platform-specific variation on the meaning
+        * of arguments to this op, we must preserve numeric arguments
+        * as numeric, not just retain the string value.
+        */
+       if (SvNIOK(origsv) || SvNIOKp(origsv)) {
+           copysv = newSV_type(SVt_PVNV);
+           sv_2mortal(copysv);
+           if (SvPOK(origsv) || SvPOKp(origsv)) {
+               pv = SvPV_nomg(origsv, len);
+               sv_setpvn(copysv, pv, len);
+               SvPOK_off(copysv);
+           }
+           if (SvIOK(origsv) || SvIOKp(origsv))
+               SvIV_set(copysv, SvIVX(origsv));
+           if (SvNOK(origsv) || SvNOKp(origsv))
+               SvNV_set(copysv, SvNVX(origsv));
+           SvFLAGS(copysv) |= SvFLAGS(origsv) &
+               (SVf_IOK|SVf_NOK|SVf_POK|SVp_IOK|SVp_NOK|SVp_POK|
+                   SVf_UTF8|SVf_IVisUV);
+       } else
+#endif
+       {
+           pv = SvPV_nomg(origsv, len);
+           copysv = newSVpvn_flags(pv, len,
+                       (SvFLAGS(origsv) & SVf_UTF8) | SVs_TEMP);
+       }
+       *MARK = copysv;
+    }
+    MARK = ORIGMARK;
+
     if (TAINTING_get) {
        TAINT_ENV();
-       while (++MARK <= SP) {
-           (void)SvPV_nolen_const(*MARK);      /* stringify for taint check */
-           if (TAINT_get)
-               break;
-       }
-       MARK = ORIGMARK;
        TAINT_PROPER("system");
     }
     PERL_FLUSHALL_FOR_CHILD;
@@ -4418,7 +4364,7 @@ PP(pp_system)
        sigset_t newset, oldset;
 #endif
 
-       if (PerlProc_pipe(pp) >= 0)
+       if (PerlProc_pipe_cloexec(pp) >= 0)
            did_pipes = 1;
 #ifdef __amigaos4__
         amigaos_fork_set_userdata(aTHX_
@@ -4480,7 +4426,6 @@ PP(pp_system)
            (void)rsignal_restore(SIGQUIT, &qhand);
 #endif
            STATUS_NATIVE_CHILD_SET(result == -1 ? -1 : status);
-           do_execfree();      /* free any memory child malloced on fork */
            SP = ORIGMARK;
            if (did_pipes) {
                int errkid;
@@ -4516,13 +4461,8 @@ PP(pp_system)
 #ifdef HAS_SIGPROCMASK
        sigprocmask(SIG_SETMASK, &oldset, NULL);
 #endif
-       if (did_pipes) {
+       if (did_pipes)
            PerlLIO_close(pp[0]);
-#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
-           if (fcntl(pp[1], F_SETFD, FD_CLOEXEC) < 0)
-                RETPUSHUNDEF;
-#endif
-       }
        if (PL_op->op_flags & OPf_STACKED) {
            SV * const really = *++MARK;
            value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);
@@ -4540,14 +4480,14 @@ PP(pp_system)
     result = 0;
     if (PL_op->op_flags & OPf_STACKED) {
        SV * const really = *++MARK;
-#  if defined(WIN32) || defined(OS2) || defined(__SYMBIAN32__) || defined(__VMS)
+#  if defined(WIN32) || defined(OS2) || defined(__VMS)
        value = (I32)do_aspawn(really, MARK, SP);
 #  else
        value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
 #  endif
     }
     else if (SP - MARK != 1) {
-#  if defined(WIN32) || defined(OS2) || defined(__SYMBIAN32__) || defined(__VMS)
+#  if defined(WIN32) || defined(OS2) || defined(__VMS)
        value = (I32)do_aspawn(NULL, MARK, SP);
 #  else
        value = (I32)do_aspawn(NULL, (void **)MARK, (void **)SP);
@@ -4559,7 +4499,6 @@ PP(pp_system)
     if (PL_statusvalue == -1)  /* hint that value must be returned as is */
        result = 1;
     STATUS_NATIVE_CHILD_SET(value);
-    do_execfree();
     SP = ORIGMARK;
     XPUSHi(result ? value : STATUS_CURRENT);
 #endif /* !FORK or VMS or OS/2 */
@@ -4670,6 +4609,11 @@ PP(pp_setpgrp)
 #endif
 }
 
+/*
+ * The glibc headers typedef __priority_which_t to an enum under C, but
+ * under C++, it keeps it as int. -Wc++-compat doesn't know this, so we
+ * need to explicitly cast it to shut up the warning.
+ */
 #if defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || (__GLIBC__ > 2))
 #  define PRIORITY_WHICH_T(which) (__priority_which_t)which
 #else
@@ -4712,9 +4656,9 @@ PP(pp_time)
 {
     dSP; dTARGET;
 #ifdef BIG_TIME
-    XPUSHn( time(NULL) );
+    XPUSHn( (NV)time(NULL) );
 #else
-    XPUSHi( time(NULL) );
+    XPUSHu( (UV)time(NULL) );
 #endif
     RETURN;
 }
@@ -4914,7 +4858,7 @@ PP(pp_sleep)
         }
     }
     (void)time(&when);
-    XPUSHi(when - lasttime);
+    XPUSHu((UV)(when - lasttime));
     RETURN;
 }
 
@@ -5330,8 +5274,8 @@ PP(pp_shostent)
        DIE(aTHX_ PL_no_sock_func, PL_op_desc[PL_op->op_type]);
 #endif
        break;
-#ifdef HAS_SETNETENT
     case OP_SNETENT:
+#ifdef HAS_SETNETENT
        PerlSock_setnetent(stayopen);
 #else
        DIE(aTHX_ PL_no_sock_func, PL_op_desc[PL_op->op_type]);
@@ -5483,7 +5427,7 @@ PP(pp_gpwent)
      * it is only included in special cases.
      *
      * In Digital UNIX/Tru64 if using the getespw*() (which seems to be
-     * be preferred interface, even though also the getprpw*() interface
+     * the preferred interface, even though also the getprpw*() interface
      * is available) one needs to link with -lsecurity -ldb -laud -lm.
      * One also needs to call set_auth_parameters() in main() before
      * doing anything else, whether one is using getespw*() or getprpw*().