blob: 5adffd7714a9569e1cf1c5aaca14cb187651b439 [file] [log] [blame]
/*
*
* Copyright (c) International Business Machines Corp., 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* NAME
* getcwd02
*
* DESCRIPTION
* Testcase to check the basic functionality of the getcwd(2) system call.
*
* ALGORITHM
* Get the path name of the current working directory from the current
* shell through a pipe, and compare it with what is returned by
* getcwd(2) system call.
*
* Blocks 1-4 are with char[], #4 is special case where address is -1
*
* Block 1: Call getcwd(2) with valid cwd[]:
* Should work fine
* Block 2: Call getcwd(2) with valid cwd[], size = 0:
* Should return NULL, errno = EINVAL
* Block 3: Call getcwd(2) with valid cwd[], size <= strlen(path):
* i.e. size = 1, Should return NULL, errno = ERANGE
* Block 4: Call getcwd(2) with cwd address = -1, size > strlen(path):
* Should return NULL, errno = EFAULT
*
* Blocks 5-7 are with char*
*
* Block 5: Call getcwd(2) with *buffer = NULL, size = 0:
* Should allocate buffer, and work fine
* Block 6: Call getcwd(2) with *buffer = NULL, size <= strlen(path):
* i.e. size = 1, Should return NULL, errno = ERANGE
* Block 7: Call getcwd(2) with *buffer = NULL, size > strlen(path):
* Should work fine and allocate buffer
*
* HISTORY
* 07/2001 Ported by Wayne Boyer
* 02/2002 Added more testcases, cleaned up by wjh
*
* RESTRICTIONS
* NONE
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <test.h>
#include <usctest.h>
#define FAILED 1
char *pwd = "/bin/pwd";
int flag;
char *TCID = "getcwd02";
int TST_TOTAL = 7;
extern int Tst_count;
void cleanup(void);
void setup(void);
void do_block1();
void do_block2();
void do_block3();
void do_block4();
void do_block5();
void do_block6();
void do_block7();
char pwd_buf[BUFSIZ]; //holds results of pwd pipe
char cwd[BUFSIZ]; //used as our valid buffer
char *buffer = NULL; //catches the return value from getcwd when passing NULL
char *cwd_ptr = NULL; //catches the return value from getcwd() when passing cwd[]
int main(int ac, char **av)
{
FILE *fin;
char *cp, *cp_cur;
int lc; /* loop counter */
char *msg; /* parse_opts() return message */
if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
}
setup();
/*
* The following loop checks looping state if -i option given
*/
for (lc = 0; TEST_LOOPING(lc); lc++) {
Tst_count = 0;
if ((fin = popen(pwd, "r")) == NULL) {
tst_resm(TINFO, "%s: can't run %s", TCID, pwd);
tst_brkm(TBROK, cleanup, "%s FAILED", TCID);
/*NOTREACHED*/}
while (fgets(pwd_buf, sizeof(pwd_buf), fin) != NULL) {
if ((cp = strchr(pwd_buf, '\n')) == NULL) {
tst_brkm(TBROK, cleanup, "pwd output too long");
/*NOTREACHED*/}
*cp = 0;
cp_cur = pwd_buf;
}
pclose(fin);
do_block1();
do_block2();
do_block3();
do_block4();
do_block5();
do_block6();
do_block7();
}
cleanup();
/*NOTREACHED*/ return 0;
}
void do_block1() //valid cwd[]: -> Should work fine
{
int flag = 0;
tst_resm(TINFO, "Enter Block 1");
if ((cwd_ptr = getcwd(cwd, sizeof(cwd))) == NULL) {
tst_resm(TFAIL, "getcwd() failed unexpectedly: "
"errno = %d\n", errno);
flag = FAILED;
}
if ((flag != FAILED) && (strcmp(pwd_buf, cwd) != 0)) {
tst_resm(TFAIL, "getcwd() returned unexpected working "
"directory: expected: %s, got: %s\n", pwd_buf, cwd);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 1");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 1 FAILED");
} else {
tst_resm(TPASS, "Block 1 PASSED");
}
}
void do_block2() //valid cwd[], size = 0: -> Should return NULL, errno = EINVAL
{
int flag = 0;
tst_resm(TINFO, "Enter Block 2");
if (((cwd_ptr = getcwd(cwd, 0)) == NULL)
&& (errno != EINVAL)) {
tst_resm(TFAIL, "getcwd() failed unexpectedly: "
"errno = %d expected EINVAL(%d)\n", errno, EINVAL);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 2");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 2 FAILED");
} else {
tst_resm(TPASS, "Block 2 PASSED");
}
}
void do_block3() //valid cwd[], size = 1 -> Should return NULL, errno = ERANGE
{
int flag = 0;
tst_resm(TINFO, "Enter Block 3");
if (((cwd_ptr = getcwd(cwd, 1)) != NULL)
|| (errno != ERANGE)) {
tst_resm(TFAIL, "getcwd() failed unexpectedly: "
"errno = %d, expected ERANGE(%d)\n", errno, ERANGE);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 3");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 3 FAILED");
} else {
tst_resm(TPASS, "Block 3 PASSED");
}
}
void do_block4() //invalid cwd[] = -1, size = BUFSIZ: -> return NULL, errno = FAULT
{
/* Skip since uClinux does not implement memory protection */
#ifndef UCLINUX
int flag = 0;
tst_resm(TINFO, "Enter Block 4");
if (((cwd_ptr = getcwd((char *)-1, sizeof(cwd))) != NULL)
|| (errno != EFAULT)) {
tst_resm(TFAIL, "getcwd() failed unexpectedly: "
"errno = %d, expected EFAULT(%d)\n", errno, EFAULT);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 4");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 4 FAILED");
} else {
tst_resm(TPASS, "Block 4 PASSED");
}
#else
tst_resm(TINFO, "Skipping Block 4 on uClinux");
#endif
}
void do_block5() //buffer = NULL, and size = 0, should succeed
{
int flag = 0;
tst_resm(TINFO, "Enter Block 5");
if ((buffer = getcwd(NULL, 0)) == NULL) {
tst_resm(TFAIL, "getcwd() failed unexpectedly: "
"errno = %d\n", errno);
flag = FAILED;
}
if ((flag != FAILED) && (strcmp(pwd_buf, buffer) != 0)) {
tst_resm(TFAIL, "getcwd() returned unexpected working "
"directory: expected: %s, got: %s\n", pwd_buf, buffer);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 5");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 5 FAILED");
} else {
tst_resm(TPASS, "Block 5 PASSED");
}
free(buffer);
buffer = NULL;
}
void do_block6() //buffer = NULL, size = 1: -> return NULL, errno = ERANGE
{
int flag = 0;
tst_resm(TINFO, "Enter Block 6");
if (((buffer = getcwd(NULL, 1)) != NULL)
|| (errno != ERANGE)) {
tst_resm(TFAIL, "getcwd() failed unexpectedly: "
"errno = %d, expected ERANGE(%d)\n", errno, ERANGE);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 6");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 6 FAILED");
} else {
tst_resm(TPASS, "Block 6 PASSED");
}
}
void do_block7() //buffer = NULL, size = BUFSIZ: -> work fine, allocate buffer
{
int flag = 0;
tst_resm(TINFO, "Enter Block 7");
if ((buffer = getcwd(NULL, sizeof(cwd))) == NULL) {
tst_resm(TFAIL, "getcwd() failed unexpectedly: "
"errno = %d\n", errno);
flag = FAILED;
}
if ((flag != FAILED) && (strcmp(pwd_buf, buffer) != 0)) {
tst_resm(TFAIL, "getcwd() returned unexpected working "
"directory: expected: %s, got: %s\n", pwd_buf, buffer);
flag = FAILED;
}
tst_resm(TINFO, "Exit Block 7");
if (flag == FAILED) {
tst_resm(TFAIL, "Block 7 FAILED");
} else {
tst_resm(TPASS, "Block 7 PASSED");
}
free(buffer);
buffer = NULL;
}
void setup()
{
/* capture signals */
/* FORK is set here because of the popen() call above */
tst_sig(FORK, DEF_HANDLER, cleanup);
/* Pause if that option was specified */
TEST_PAUSE;
/* create a test directory and cd into it */
tst_tmpdir();
}
void cleanup()
{
/* remove the test directory */
tst_rmdir();
/* exit with return code appropriate for results */
tst_exit();
}